mirror of https://github.com/fantasticit/think.git
improve table cell
parent
922ecdf98f
commit
c6abfab7c8
|
@ -1,13 +1,18 @@
|
|||
import { IconPlus } from '@douyinfe/semi-icons';
|
||||
import { mergeAttributes, Node } from '@tiptap/core';
|
||||
import { Plugin } from 'prosemirror-state';
|
||||
import { Tooltip } from 'components/tooltip';
|
||||
import { Plugin, PluginKey } from 'prosemirror-state';
|
||||
import { addRowAfter } from 'prosemirror-tables';
|
||||
import { Decoration, DecorationSet } from 'prosemirror-view';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { getCellsInColumn, isRowSelected, isTableSelected, selectRow, selectTable } from 'tiptap/prose-utils';
|
||||
|
||||
export interface TableCellOptions {
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
|
||||
export const TableCell = Node.create<TableCellOptions>({
|
||||
export const TableCell = Node.create<TableCellOptions, { clearCallbacks: Array<() => void> }>({
|
||||
name: 'tableCell',
|
||||
content: 'block+',
|
||||
tableRole: 'cell',
|
||||
|
@ -19,14 +24,6 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
};
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: 'td' }];
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['td', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
colspan: {
|
||||
|
@ -46,7 +43,7 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
},
|
||||
},
|
||||
colwidth: {
|
||||
default: [150],
|
||||
default: [100],
|
||||
parseHTML: (element) => {
|
||||
const colwidth = element.getAttribute('colwidth');
|
||||
const value = colwidth ? [parseInt(colwidth, 10)] : null;
|
||||
|
@ -59,22 +56,44 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
};
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: 'td' }];
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['td', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
|
||||
addStorage() {
|
||||
return {
|
||||
clearCallbacks: [],
|
||||
};
|
||||
},
|
||||
|
||||
onDestroy() {
|
||||
this.storage.clearCallbacks.forEach((cb) => cb());
|
||||
this.storage.clearCallbacks.length = 0;
|
||||
},
|
||||
|
||||
// @ts-ignore
|
||||
addProseMirrorPlugins() {
|
||||
const { isEditable } = this.editor;
|
||||
|
||||
return [
|
||||
new Plugin({
|
||||
key: new PluginKey('table-cell-control'),
|
||||
props: {
|
||||
decorations: (state) => {
|
||||
if (!isEditable) {
|
||||
return DecorationSet.empty;
|
||||
}
|
||||
|
||||
const { doc, selection } = state;
|
||||
const decorations: Decoration[] = [];
|
||||
const cells = getCellsInColumn(0)(selection);
|
||||
|
||||
if (cells) {
|
||||
this.storage.clearCallbacks.forEach((cb) => cb());
|
||||
this.storage.clearCallbacks.length = 0;
|
||||
|
||||
cells.forEach(({ pos }, index) => {
|
||||
if (index === 0) {
|
||||
decorations.push(
|
||||
|
@ -89,8 +108,10 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
grip.addEventListener('mousedown', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.editor.view.dispatch(selectTable(this.editor.state.tr));
|
||||
// this.options.onSelectTable(state);
|
||||
this.editor.view.dispatch(
|
||||
// @ts-ignore
|
||||
selectTable(this.editor.state.tr)
|
||||
);
|
||||
});
|
||||
return grip;
|
||||
})
|
||||
|
@ -99,7 +120,6 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
decorations.push(
|
||||
Decoration.widget(pos + 1, () => {
|
||||
const rowSelected = isRowSelected(index)(selection);
|
||||
|
||||
let className = 'grip-row';
|
||||
if (rowSelected) {
|
||||
className += ' selected';
|
||||
|
@ -111,18 +131,41 @@ export const TableCell = Node.create<TableCellOptions>({
|
|||
className += ' last';
|
||||
}
|
||||
const grip = document.createElement('a');
|
||||
grip.className = className;
|
||||
grip.addEventListener('mousedown', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.editor.view.dispatch(selectRow(index)(this.editor.state.tr));
|
||||
|
||||
ReactDOM.render(
|
||||
<Tooltip content="向后增加一行">
|
||||
<IconPlus />
|
||||
</Tooltip>,
|
||||
grip
|
||||
);
|
||||
|
||||
this.storage.clearCallbacks.push(() => {
|
||||
ReactDOM.unmountComponentAtNode(grip);
|
||||
});
|
||||
|
||||
grip.className = className;
|
||||
grip.addEventListener(
|
||||
'mousedown',
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
this.editor.view.dispatch(
|
||||
// @ts-ignore
|
||||
selectRow(index)(this.editor.state.tr)
|
||||
);
|
||||
|
||||
if (event.target !== grip) {
|
||||
addRowAfter(this.editor.state, this.editor.view.dispatch);
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
return grip;
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return DecorationSet.create(doc, decorations);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,9 +1,29 @@
|
|||
import { TableHeader as BuiltInTableHeader } from '@tiptap/extension-table-header';
|
||||
import { Plugin } from 'prosemirror-state';
|
||||
import { IconPlus } from '@douyinfe/semi-icons';
|
||||
import { mergeAttributes, Node } from '@tiptap/core';
|
||||
import { Tooltip } from 'components/tooltip';
|
||||
import { Plugin, PluginKey } from 'prosemirror-state';
|
||||
import { addColumnAfter } from 'prosemirror-tables';
|
||||
import { Decoration, DecorationSet } from 'prosemirror-view';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { getCellsInRow, isColumnSelected, selectColumn } from 'tiptap/prose-utils';
|
||||
|
||||
export const TableHeader = BuiltInTableHeader.extend({
|
||||
export interface TableHeaderOptions {
|
||||
HTMLAttributes: Record<string, any>;
|
||||
}
|
||||
|
||||
export const TableHeader = Node.create<TableHeaderOptions, { clearCallbacks: Array<() => void> }>({
|
||||
name: 'tableHeader',
|
||||
content: 'block+',
|
||||
tableRole: 'header_cell',
|
||||
isolating: true,
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
};
|
||||
},
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
colspan: {
|
||||
|
@ -13,10 +33,10 @@ export const TableHeader = BuiltInTableHeader.extend({
|
|||
default: 1,
|
||||
},
|
||||
colwidth: {
|
||||
default: [150],
|
||||
default: [100],
|
||||
parseHTML: (element) => {
|
||||
const colwidth = element.getAttribute('colwidth');
|
||||
const value = colwidth ? colwidth.split(',').map((item) => parseInt(item, 10)) : null;
|
||||
const value = colwidth ? [parseInt(colwidth, 10)] : null;
|
||||
|
||||
return value;
|
||||
},
|
||||
|
@ -27,22 +47,44 @@ export const TableHeader = BuiltInTableHeader.extend({
|
|||
};
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: 'th' }];
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ['th', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||
},
|
||||
|
||||
addStorage() {
|
||||
return {
|
||||
clearCallbacks: [],
|
||||
};
|
||||
},
|
||||
|
||||
onDestroy() {
|
||||
this.storage.clearCallbacks.forEach((cb) => cb());
|
||||
this.storage.clearCallbacks.length = 0;
|
||||
},
|
||||
|
||||
// @ts-ignore
|
||||
addProseMirrorPlugins() {
|
||||
const { isEditable } = this.editor;
|
||||
|
||||
return [
|
||||
new Plugin({
|
||||
key: new PluginKey('table-header-control'),
|
||||
props: {
|
||||
decorations: (state) => {
|
||||
if (!isEditable) {
|
||||
return DecorationSet.empty;
|
||||
}
|
||||
|
||||
const { doc, selection } = state;
|
||||
const decorations: Decoration[] = [];
|
||||
const cells = getCellsInRow(0)(selection);
|
||||
|
||||
if (cells) {
|
||||
this.storage.clearCallbacks.forEach((cb) => cb());
|
||||
this.storage.clearCallbacks.length = 0;
|
||||
|
||||
cells.forEach(({ pos }, index) => {
|
||||
decorations.push(
|
||||
Decoration.widget(pos + 1, () => {
|
||||
|
@ -58,17 +100,33 @@ export const TableHeader = BuiltInTableHeader.extend({
|
|||
}
|
||||
const grip = document.createElement('a');
|
||||
grip.className = className;
|
||||
|
||||
ReactDOM.render(
|
||||
<Tooltip content="向后增加一列">
|
||||
<IconPlus />
|
||||
</Tooltip>,
|
||||
grip
|
||||
);
|
||||
|
||||
this.storage.clearCallbacks.push(() => {
|
||||
ReactDOM.unmountComponentAtNode(grip);
|
||||
});
|
||||
|
||||
grip.addEventListener('mousedown', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
this.editor.view.dispatch(selectColumn(index)(this.editor.state.tr));
|
||||
|
||||
if (event.target !== grip) {
|
||||
addColumnAfter(this.editor.state, this.editor.view.dispatch);
|
||||
}
|
||||
});
|
||||
return grip;
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return DecorationSet.create(doc, decorations);
|
||||
},
|
||||
},
|
|
@ -1,5 +1,7 @@
|
|||
import BuiltInTable from '@tiptap/extension-table';
|
||||
import { Node as ProseMirrorNode } from 'prosemirror-model';
|
||||
import { Plugin, PluginKey } from 'prosemirror-state';
|
||||
import { tableNodeTypes } from 'prosemirror-tables';
|
||||
import { NodeView } from 'prosemirror-view';
|
||||
|
||||
function updateColumns(
|
||||
|
@ -105,6 +107,26 @@ class TableView implements NodeView {
|
|||
}
|
||||
}
|
||||
|
||||
export function readonlyTableView({ cellMinWidth = 25, View = TableView } = {}) {
|
||||
const plugin = new Plugin({
|
||||
key: new PluginKey('readonlyTableView'),
|
||||
state: {
|
||||
init(_, state) {
|
||||
this.spec.props.nodeViews[tableNodeTypes(state.schema).table.name] = (node, view) =>
|
||||
new View(node, cellMinWidth);
|
||||
return {};
|
||||
},
|
||||
apply(tr, prev) {
|
||||
return prev;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
nodeViews: {},
|
||||
},
|
||||
});
|
||||
return plugin;
|
||||
}
|
||||
|
||||
export const Table = BuiltInTable.extend({
|
||||
// @ts-ignore
|
||||
addOptions() {
|
||||
|
@ -118,4 +140,8 @@ export const Table = BuiltInTable.extend({
|
|||
allowTableNodeSelection: false,
|
||||
};
|
||||
},
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [...this.parent(), !this.editor.isEditable && readonlyTableView()].filter(Boolean);
|
||||
},
|
||||
}).configure({ resizable: true });
|
||||
|
|
|
@ -25,13 +25,14 @@ export const TableBubbleMenu = ({ editor }) => {
|
|||
const shouldShow = useCallback(() => {
|
||||
return editor.isActive(Table.name);
|
||||
}, [editor]);
|
||||
|
||||
const getRenderContainer = useCallback((node) => {
|
||||
let container = node;
|
||||
// 文本节点
|
||||
if (container && !container.tag) {
|
||||
container = node.parentElement;
|
||||
}
|
||||
while (container && container.tagName !== 'TABLE') {
|
||||
while (container && !container.classList.contains('tableWrapper')) {
|
||||
container = container.parentElement;
|
||||
}
|
||||
return container;
|
||||
|
@ -40,6 +41,7 @@ export const TableBubbleMenu = ({ editor }) => {
|
|||
const deleteMe = useCallback(() => {
|
||||
deleteNode(Table.name, editor);
|
||||
}, [editor]);
|
||||
|
||||
const addColumnBefore = useCallback(() => editor.chain().focus().addColumnBefore().run(), [editor]);
|
||||
const addColumnAfter = useCallback(() => editor.chain().focus().addColumnAfter().run(), [editor]);
|
||||
const deleteColumn = useCallback(() => editor.chain().focus().deleteColumn().run(), [editor]);
|
||||
|
@ -59,7 +61,6 @@ export const TableBubbleMenu = ({ editor }) => {
|
|||
pluginKey="table-bubble-menu"
|
||||
tippyOptions={{
|
||||
maxWidth: 'calc(100vw - 100px)',
|
||||
placement: 'bottom',
|
||||
}}
|
||||
shouldShow={shouldShow}
|
||||
getRenderContainer={getRenderContainer}
|
||||
|
|
|
@ -9,8 +9,8 @@ export const Table: React.FC<{ editor: Editor }> = ({ editor }) => {
|
|||
return (
|
||||
<>
|
||||
<TableBubbleMenu editor={editor} />
|
||||
<TableRowBubbleMenu editor={editor} />
|
||||
<TableColBubbleMenu editor={editor} />
|
||||
{/* <TableRowBubbleMenu editor={editor} /> */}
|
||||
{/* <TableColBubbleMenu editor={editor} /> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,160 +1,282 @@
|
|||
.ProseMirror {
|
||||
.node-table {
|
||||
position: relative;
|
||||
margin-top: 0.75em;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: transparent transparent;
|
||||
}
|
||||
/* stylelint-disable */
|
||||
$tableBorderColor: var(--semi-color-border);
|
||||
$tableHeaderBgColor: var(--semi-color-fill-0);
|
||||
$tableSelectedBorderColor: rgb(0 101 255);
|
||||
$tableSelectedCellBgColor: transparent;
|
||||
$tableSelectedControlBgColor: #2584ff;
|
||||
$tableResizeHandleBgColor: #adf;
|
||||
|
||||
.scrollable {
|
||||
padding-left: 1em;
|
||||
margin-left: -1em;
|
||||
overflow: auto hidden;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
transition: border 250ms ease-in-out 0s;
|
||||
}
|
||||
.tableWrapper {
|
||||
position: relative;
|
||||
margin: 0.5em 0px;
|
||||
|
||||
.scrollable-shadow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -1em;
|
||||
width: 16px;
|
||||
transition: box-shadow 250ms ease-in-out 0s;
|
||||
border-width: 0 0 0 1em;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-image: initial;
|
||||
pointer-events: none;
|
||||
|
||||
&.left {
|
||||
box-shadow: 16px 0 16px -16px inset rgb(0 0 0 / 25%);
|
||||
}
|
||||
|
||||
&.right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
box-shadow: rgb(0 0 0 / 25%) -16px 0 16px -16px inset;
|
||||
|
||||
&.is-editable {
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
background-color: var(--semi-color-nav-bg);
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
&.has-focus {
|
||||
.scrollWrapper {
|
||||
margin-top: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin-top: 1em;
|
||||
border-radius: 4px;
|
||||
border-collapse: collapse;
|
||||
.scrollWrapper {
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
padding-left: 28px;
|
||||
padding-top: 28px;
|
||||
padding-bottom: 8px;
|
||||
margin-left: -28px;
|
||||
margin-top: -20px;
|
||||
margin-bottom: -8px;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
-webkit-transition: border 250ms ease-in-out 0s;
|
||||
transition: border 250ms ease-in-out 0s;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 4px;
|
||||
overflow: auto;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
border-color: var(--semi-color-fill-2);
|
||||
}
|
||||
|
||||
&.is-readonly {
|
||||
margin-top: 0;
|
||||
}
|
||||
tr {
|
||||
position: relative;
|
||||
border-bottom: 1px solid $tableBorderColor;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
position: relative;
|
||||
min-width: 100px;
|
||||
padding: 4px 8px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
border: 1px solid rgb(232 235 237);
|
||||
border-color: var(--semi-color-fill-2);
|
||||
th {
|
||||
background: $tableHeaderBgColor;
|
||||
}
|
||||
|
||||
:not(a) {
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
td,
|
||||
th {
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
border: 1px solid $tableBorderColor;
|
||||
position: relative;
|
||||
padding: 4px 8px;
|
||||
text-align: left;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: bold;
|
||||
background-color: var(--semi-color-fill-0);
|
||||
}
|
||||
.selectedCell {
|
||||
position: relative;
|
||||
border: 1px solid $tableSelectedBorderColor;
|
||||
background-color: $tableSelectedCellBgColor;
|
||||
|
||||
.selectedCell {
|
||||
border-style: double;
|
||||
border-color: rgb(0 101 255);
|
||||
background: var(--semi-color-info-light-hover);
|
||||
}
|
||||
|
||||
.grip-column {
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 0.7em;
|
||||
margin-bottom: 3px;
|
||||
cursor: pointer;
|
||||
background: #ced4da;
|
||||
|
||||
&:hover,
|
||||
&.selected {
|
||||
background: var(--semi-color-info);
|
||||
}
|
||||
}
|
||||
|
||||
.grip-row {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1em;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
width: 0.7em;
|
||||
&::after {
|
||||
box-sizing: content-box;
|
||||
height: 100%;
|
||||
margin-right: 3px;
|
||||
cursor: pointer;
|
||||
background: #ced4da;
|
||||
|
||||
&:hover,
|
||||
&.selected {
|
||||
background: var(--semi-color-info);
|
||||
}
|
||||
}
|
||||
|
||||
.grip-table {
|
||||
width: 100%;
|
||||
border: 1px solid $tableSelectedBorderColor;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: -1em;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
cursor: pointer;
|
||||
background: #ced4da;
|
||||
border-radius: 50%;
|
||||
left: -1px;
|
||||
top: -1px;
|
||||
bottom: 0px;
|
||||
z-index: 12;
|
||||
display: inline-block;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.selected {
|
||||
background: var(--semi-color-info);
|
||||
.grip-column {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -1px;
|
||||
width: 100%;
|
||||
|
||||
> span {
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
left: 100%;
|
||||
transform: translateX(-8px);
|
||||
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
font-size: 0;
|
||||
cursor: pointer;
|
||||
|
||||
.semi-icon-default {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
bottom: 4px;
|
||||
transform: translateX(-1px);
|
||||
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background-color: $tableBorderColor;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&::after {
|
||||
box-sizing: content-box;
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
background: $tableHeaderBgColor;
|
||||
border: 1px solid $tableBorderColor;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $tableSelectedBorderColor;
|
||||
|
||||
> span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedControlBgColor;
|
||||
}
|
||||
}
|
||||
|
||||
&.last::after {
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedControlBgColor;
|
||||
}
|
||||
}
|
||||
|
||||
.grip-row {
|
||||
position: absolute;
|
||||
left: -12px;
|
||||
top: -1px;
|
||||
height: 100%;
|
||||
|
||||
> span {
|
||||
transform: translateY(8px);
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
bottom: 4px;
|
||||
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
font-size: 0;
|
||||
cursor: pointer;
|
||||
|
||||
.semi-icon-default {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
bottom: -2px;
|
||||
width: 4px;
|
||||
pointer-events: none;
|
||||
background-color: #adf;
|
||||
height: 4px;
|
||||
background-color: $tableBorderColor;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&::after {
|
||||
box-sizing: content-box;
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 10px;
|
||||
background: $tableHeaderBgColor;
|
||||
border: 1px solid $tableBorderColor;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $tableSelectedBorderColor;
|
||||
|
||||
> span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
&.last::after {
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
.grip-table {
|
||||
&::after {
|
||||
box-sizing: content-box;
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -12px;
|
||||
display: block;
|
||||
background: $tableHeaderBgColor;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 1px solid $tableBorderColor;
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedBorderColor;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
background: $tableSelectedControlBgColor;
|
||||
border-color: $tableSelectedBorderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column-resize-handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
width: 4px;
|
||||
pointer-events: none;
|
||||
background-color: $tableResizeHandleBgColor;
|
||||
}
|
||||
|
||||
.resize-cursor {
|
||||
|
|
Loading…
Reference in New Issue