Skip to content

Commit 46f5168

Browse files
authored
feat(YfmTable): change border color for selected cells (#850)
1 parent b1ca9c6 commit 46f5168

File tree

6 files changed

+189
-59
lines changed

6 files changed

+189
-59
lines changed

src/extensions/yfm/YfmTable/plugins/YfmTableControls/const.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ export enum YfmTableDecorationType {
1010
OpenRowMenu = 'cell--open-row-menu', // sign of opening the row menu in the cell
1111
OpenColumnMenu = 'cell--open-column-menu', // sign of opening the column menu in the cell
1212

13-
ActivateRow = 'row--active',
13+
ActivateRowCells = 'cell--active-row',
1414
ActivateColumnCells = 'cell--active-column',
1515

16-
ActivateDangerRow = 'row--danger',
16+
ActivateDangerRowCells = 'cell--danger-row',
1717
ActivateDangerColumnCells = 'cell--danger-column',
1818
}

src/extensions/yfm/YfmTable/plugins/YfmTableControls/dnd/dnd.scss

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,75 @@
4141
z-index: 2;
4242
}
4343

44-
.yfm.ProseMirror {
45-
.g-md-yfm-table-dnd-dragged-row,
46-
.g-md-yfm-table-dnd-dragged-column-cell {
47-
opacity: 0.3;
48-
background-color: var(--g-color-base-selection);
49-
// --yfm-color-border: var(--g-color-line-brand);
50-
}
51-
}
44+
.yfm.ProseMirror table {
45+
td {
46+
$selectedCell: 'g-md-yfm-table-selected-cell';
47+
48+
position: relative;
49+
50+
&.#{$selectedCell} {
51+
overflow: unset;
52+
53+
border-color: var(--g-color-line-brand);
54+
background-color: var(--g-color-base-selection);
55+
56+
&::after {
57+
position: absolute;
58+
z-index: 2;
59+
inset: -1px;
60+
61+
display: inline-block;
62+
63+
content: '';
64+
pointer-events: none;
65+
66+
border: 1px solid var(--g-color-line-brand);
67+
}
68+
69+
&_first-row::after {
70+
top: 0;
71+
}
5272

53-
.yfm.ProseMirror {
54-
.g-md-yfm-table-active-row,
55-
.g-md-yfm-table-active-column-cell {
56-
background-color: var(--g-color-base-selection);
57-
// --yfm-color-border: var(--g-color-line-brand);
73+
&_last-row::after {
74+
bottom: 0;
75+
}
76+
77+
&_first-column::after {
78+
left: 0;
79+
}
80+
81+
&_last-column::after {
82+
right: 0;
83+
}
84+
85+
&_first-row.#{$selectedCell}_first-column::after {
86+
border-top-left-radius: 8px;
87+
}
88+
89+
&_first-row.#{$selectedCell}_last-column::after {
90+
border-top-right-radius: 8px;
91+
}
92+
93+
&_last-row.#{$selectedCell}_first-column::after {
94+
border-bottom-left-radius: 8px;
95+
}
96+
97+
&_last-row.#{$selectedCell}_last-column::after {
98+
border-bottom-right-radius: 8px;
99+
}
100+
101+
&.dragged-cell::before {
102+
position: absolute;
103+
inset: 0;
104+
105+
display: inline-block;
106+
107+
content: '';
108+
pointer-events: none;
109+
110+
opacity: 0.7;
111+
background-color: var(--g-color-base-background);
112+
}
113+
}
58114
}
59115
}

src/extensions/yfm/YfmTable/plugins/YfmTableControls/dnd/dnd.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {type Node, Slice} from '#pm/model';
22
import {TextSelection} from '#pm/state';
33
import {findParentNodeClosestToPos} from '#pm/utils';
44
import type {EditorView} from '#pm/view';
5-
import {debounce, range as iterate} from 'src/lodash';
5+
import {debounce} from 'src/lodash';
66
import type {Logger2} from 'src/logger';
77
import {isTableNode} from 'src/table-utils';
88
import {
@@ -17,6 +17,7 @@ import {
1717
import {YfmTableNode} from '../../../YfmTableSpecs';
1818
import {clearAllSelections, selectDraggedColumn, selectDraggedRow} from '../plugins/dnd-plugin';
1919
import {hideHoverDecos} from '../plugins/focus-plugin';
20+
import {getSelectedCellsForColumns, getSelectedCellsForRows} from '../utils';
2021

2122
import {
2223
type DropCursorParams,
@@ -212,12 +213,7 @@ class YfmTableRowDnDHandler extends YfmTableDnDAbstractHandler {
212213
{
213214
const {tr} = this._editorView.state;
214215
hideHoverDecos(tr);
215-
selectDraggedRow(
216-
tr,
217-
iterate(currRowRange.startIdx, currRowRange.endIdx + 1).map((rowIdx) =>
218-
tableDesc.getPosForRow(rowIdx),
219-
),
220-
);
216+
selectDraggedRow(tr, getSelectedCellsForRows(info.tableDesc, currRowRange));
221217
this._editorView.dispatch(tr);
222218
}
223219

@@ -415,15 +411,9 @@ class YfmTableColumnDnDHandler extends YfmTableDnDAbstractHandler {
415411
this._logger.event({event: 'column-drag-start'});
416412

417413
{
418-
const columnCellsPos: CellPos[] = [];
419-
for (const i of iterate(currColumnRange.startIdx, currColumnRange.endIdx + 1)) {
420-
columnCellsPos.push(...tableDesc.getPosForColumn(i));
421-
}
422-
const realPos = columnCellsPos.filter((cell) => cell.type === 'real');
423-
424414
const {tr} = this._editorView.state;
425415
hideHoverDecos(tr);
426-
selectDraggedColumn(tr, realPos);
416+
selectDraggedColumn(tr, getSelectedCellsForColumns(tableDesc, currColumnRange));
427417
this._editorView.dispatch(tr);
428418
}
429419
{

src/extensions/yfm/YfmTable/plugins/YfmTableControls/nodeviews/yfm-table-cell-view.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import type {Logger2} from 'src/logger';
88
import {ErrorLoggerBoundary} from 'src/react-utils/ErrorBoundary';
99
import {isTableNode} from 'src/table-utils';
1010
import {
11-
type CellPos,
1211
type TableColumnRange,
1312
TableDesc,
1413
type TableDescBinded,
@@ -35,6 +34,7 @@ import {
3534
deactivateColumn,
3635
deactivateRow,
3736
} from '../plugins/dnd-plugin';
37+
import {getSelectedCellsForColumns, getSelectedCellsForRows} from '../utils';
3838

3939
const dropCursorParams: DropCursorParams = {
4040
color: 'var(--g-color-line-brand)',
@@ -241,9 +241,7 @@ class YfmTableCellView implements NodeView {
241241
const rowRange = info.tableDesc.base.getRowRangeByRowIdx(info.cell.row);
242242
const tr = activateRows(this._view.state.tr, {
243243
controlCell: {from: info.pos, to: info.pos + this._node.nodeSize},
244-
rows: iterate(rowRange.startIdx, rowRange.endIdx + 1).map((rowIdx) =>
245-
info.tableDesc.getPosForRow(rowIdx),
246-
),
244+
cells: getSelectedCellsForRows(info.tableDesc, rowRange),
247245
uniqKey: this._decoRowUniqKey,
248246
});
249247
this._view.dispatch(tr);
@@ -264,14 +262,10 @@ class YfmTableCellView implements NodeView {
264262
if (!info) return;
265263

266264
this._decoColumnUniqKey = Date.now();
267-
const currColumnRange = info.tableDesc.base.getColumnRangeByColumnIdx(info.cell.column);
268-
const cells: CellPos[] = [];
269-
for (const i of iterate(currColumnRange.startIdx, currColumnRange.endIdx + 1)) {
270-
cells.push(...info.tableDesc.getPosForColumn(i));
271-
}
265+
const columnRange = info.tableDesc.base.getColumnRangeByColumnIdx(info.cell.column);
272266
const tr = activateColumns(this._view.state.tr, {
273267
controlCell: {from: info.pos, to: info.pos + this._node.nodeSize},
274-
cells: cells.filter((pos) => pos.type === 'real'),
268+
cells: getSelectedCellsForColumns(info.tableDesc, columnRange),
275269
uniqKey: this._decoColumnUniqKey,
276270
});
277271
this._view.dispatch(tr);

src/extensions/yfm/YfmTable/plugins/YfmTableControls/plugins/dnd-plugin.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,50 @@
11
import {Plugin, PluginKey, type Transaction} from '#pm/state';
22
import {Decoration, DecorationSet} from '#pm/view';
3+
import {cn} from 'src/classname';
34

45
import {
56
YfmTableDecorationType,
67
YfmTableDecorationTypeKey,
78
YfmTableDecorationUniqKey,
89
} from '../const';
910

11+
const b = cn('yfm-table-selected-cell');
12+
1013
type FromTo = {
1114
from: number;
1215
to: number;
1316
};
1417

18+
type CellMods = {
19+
'first-row'?: boolean;
20+
'last-row'?: boolean;
21+
'first-column'?: boolean;
22+
'last-column'?: boolean;
23+
};
24+
25+
export type SelectedCellPos = FromTo & {
26+
mods: CellMods;
27+
};
28+
1529
type DndMeta =
16-
| {action: 'row-control-active'; controlCell: FromTo; rows: FromTo[]; uniqKey: number}
17-
| {action: 'column-control-active'; controlCell: FromTo; cells: FromTo[]; uniqKey: number}
30+
| {action: 'row-control-active'; controlCell: FromTo; cells: SelectedCellPos[]; uniqKey: number}
31+
| {
32+
action: 'column-control-active';
33+
controlCell: FromTo;
34+
cells: SelectedCellPos[];
35+
uniqKey: number;
36+
}
1837
| {action: 'row-control-non-active'; uniqKey: number}
1938
| {action: 'column-control-non-active'; uniqKey: number}
20-
| {action: 'drag-rows'; rows: FromTo[]}
21-
| {action: 'drag-columns'; cells: FromTo[]}
39+
| {action: 'drag-rows'; cells: SelectedCellPos[]}
40+
| {action: 'drag-columns'; cells: SelectedCellPos[]}
2241
| {action: 'hide'};
2342

2443
const key = new PluginKey<DecorationSet>('yfm-table-dnd-decos');
2544

2645
export function activateRows(
2746
tr: Transaction,
28-
params: {controlCell: FromTo; rows: FromTo[]; uniqKey: number},
47+
params: {controlCell: FromTo; cells: SelectedCellPos[]; uniqKey: number},
2948
): Transaction {
3049
const meta: DndMeta = {action: 'row-control-active', ...params};
3150
tr.setMeta(key, meta);
@@ -40,7 +59,7 @@ export function deactivateRow(tr: Transaction, uniqKey: number): Transaction {
4059

4160
export function activateColumns(
4261
tr: Transaction,
43-
params: {controlCell: FromTo; cells: FromTo[]; uniqKey: number},
62+
params: {controlCell: FromTo; cells: SelectedCellPos[]; uniqKey: number},
4463
): Transaction {
4564
const meta: DndMeta = {action: 'column-control-active', ...params};
4665
tr.setMeta(key, meta);
@@ -53,13 +72,13 @@ export function deactivateColumn(tr: Transaction, uniqKey: number): Transaction
5372
return tr;
5473
}
5574

56-
export function selectDraggedRow(tr: Transaction, rows: FromTo[]): Transaction {
57-
const meta: DndMeta = {action: 'drag-rows', rows};
75+
export function selectDraggedRow(tr: Transaction, cells: SelectedCellPos[]): Transaction {
76+
const meta: DndMeta = {action: 'drag-rows', cells};
5877
tr.setMeta(key, meta);
5978
return tr;
6079
}
6180

62-
export function selectDraggedColumn(tr: Transaction, cells: FromTo[]): Transaction {
81+
export function selectDraggedColumn(tr: Transaction, cells: SelectedCellPos[]): Transaction {
6382
const meta: DndMeta = {action: 'drag-columns', cells};
6483
tr.setMeta(key, meta);
6584
return tr;
@@ -86,7 +105,7 @@ export const yfmTableDndPlugin = () => {
86105
}
87106

88107
if (meta?.action === 'row-control-active') {
89-
const {controlCell, rows, uniqKey} = meta;
108+
const {controlCell, cells, uniqKey} = meta;
90109
return DecorationSet.create(tr.doc, [
91110
Decoration.node(
92111
controlCell.from,
@@ -97,14 +116,15 @@ export const yfmTableDndPlugin = () => {
97116
[YfmTableDecorationTypeKey]: YfmTableDecorationType.OpenRowMenu,
98117
},
99118
),
100-
...rows.map((row) =>
119+
...cells.map((cell) =>
101120
Decoration.node(
102-
row.from,
103-
row.to,
104-
{class: 'g-md-yfm-table-active-row'},
121+
cell.from,
122+
cell.to,
123+
{class: b(cell.mods)},
105124
{
106125
[YfmTableDecorationUniqKey]: uniqKey,
107-
[YfmTableDecorationTypeKey]: YfmTableDecorationType.ActivateRow,
126+
[YfmTableDecorationTypeKey]:
127+
YfmTableDecorationType.ActivateRowCells,
108128
},
109129
),
110130
),
@@ -137,7 +157,7 @@ export const yfmTableDndPlugin = () => {
137157
Decoration.node(
138158
pos.from,
139159
pos.to,
140-
{class: 'g-md-yfm-table-active-column-cell'},
160+
{class: b(pos.mods)},
141161
{
142162
[YfmTableDecorationUniqKey]: uniqKey,
143163
[YfmTableDecorationTypeKey]:
@@ -161,9 +181,9 @@ export const yfmTableDndPlugin = () => {
161181
if (meta?.action === 'drag-rows') {
162182
return DecorationSet.create(
163183
tr.doc,
164-
meta.rows.map((row) =>
165-
Decoration.node(row.from, row.to, {
166-
class: 'g-md-yfm-table-dnd-dragged-row',
184+
meta.cells.map((cell) =>
185+
Decoration.node(cell.from, cell.to, {
186+
class: b(cell.mods, 'dragged-cell'),
167187
}),
168188
),
169189
);
@@ -174,7 +194,7 @@ export const yfmTableDndPlugin = () => {
174194
tr.doc,
175195
meta.cells.map((cell) =>
176196
Decoration.node(cell.from, cell.to, {
177-
class: 'g-md-yfm-table-dnd-dragged-column-cell',
197+
class: b(cell.mods, 'dragged-cell'),
178198
}),
179199
),
180200
);

0 commit comments

Comments
 (0)