@rowsncolumns/spreadsheet 10.6.0 → 10.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api/cf-data-bar.d.ts +73 -0
- package/dist/cjs/api/cf-data-bar.d.ts.map +1 -0
- package/dist/cjs/api/cf-data-bar.js +182 -0
- package/dist/cjs/api/cf-icons.d.ts +73 -0
- package/dist/cjs/api/cf-icons.d.ts.map +1 -0
- package/dist/cjs/api/cf-icons.js +322 -0
- package/dist/cjs/api/cf-overlays.d.ts +89 -3
- package/dist/cjs/api/cf-overlays.d.ts.map +1 -1
- package/dist/cjs/api/cf-overlays.js +256 -80
- package/dist/cjs/api/cf-priority.d.ts +34 -0
- package/dist/cjs/api/cf-priority.d.ts.map +1 -0
- package/dist/cjs/api/cf-priority.js +94 -0
- package/dist/cjs/api/heatmap.d.ts +7 -1
- package/dist/cjs/api/heatmap.d.ts.map +1 -1
- package/dist/cjs/api/heatmap.js +27 -11
- package/dist/cjs/api/selections.d.ts +2 -2
- package/dist/cjs/api/validation.d.ts +6 -0
- package/dist/cjs/api/validation.d.ts.map +1 -1
- package/dist/cjs/api/validation.js +10 -1
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +194 -51
- package/dist/cjs/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/cjs/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/overflow.js +49 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/page-breaks.js +77 -0
- package/dist/cjs/components/canvas-grid/typings.d.ts +25 -0
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.d.ts +83 -1
- package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.js +182 -1
- package/dist/cjs/components/cell/cell-background.d.ts +18 -0
- package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-background.js +145 -59
- package/dist/cjs/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-backgrounds.js +5 -1
- package/dist/cjs/components/cell/cell-text-runs.d.ts +12 -5
- package/dist/cjs/components/cell/cell-text-runs.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-text-runs.js +19 -21
- package/dist/cjs/components/cell/index.d.ts.map +1 -1
- package/dist/cjs/components/cell/index.js +392 -45
- package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
- package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/cjs/components/cell/number-format-layout.js +106 -0
- package/dist/cjs/components/cell/typings.d.ts +22 -0
- package/dist/cjs/components/cell/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +2 -2
- package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-filter/index.js +3 -3
- package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
- package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-overlay/index.js +155 -28
- package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/cjs/components/cf-icon-preview/index.js +48 -0
- package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/cjs/components/embeds/embed-component.js +3 -2
- package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/index.js +8 -7
- package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
- package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/style.js +13 -2
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
- package/dist/cjs/components/toolbar/types.d.ts +1 -1
- package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
- package/dist/cjs/config.d.ts +13 -1
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +15 -3
- package/dist/cjs/helpers.d.ts +15 -5
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +51 -35
- package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/cjs/hooks/use-border-styles.js +5 -28
- package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +85 -47
- package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/themes.d.ts +8 -0
- package/dist/cjs/themes.d.ts.map +1 -1
- package/dist/cjs/themes.js +21 -3
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +81 -4
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/api/cf-data-bar.d.ts +73 -0
- package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
- package/dist/esm/api/cf-data-bar.js +178 -0
- package/dist/esm/api/cf-icons.d.ts +73 -0
- package/dist/esm/api/cf-icons.d.ts.map +1 -0
- package/dist/esm/api/cf-icons.js +306 -0
- package/dist/esm/api/cf-overlays.d.ts +89 -3
- package/dist/esm/api/cf-overlays.d.ts.map +1 -1
- package/dist/esm/api/cf-overlays.js +223 -67
- package/dist/esm/api/cf-priority.d.ts +34 -0
- package/dist/esm/api/cf-priority.d.ts.map +1 -0
- package/dist/esm/api/cf-priority.js +61 -0
- package/dist/esm/api/heatmap.d.ts +7 -1
- package/dist/esm/api/heatmap.d.ts.map +1 -1
- package/dist/esm/api/heatmap.js +24 -9
- package/dist/esm/api/selections.d.ts +2 -2
- package/dist/esm/api/validation.d.ts +6 -0
- package/dist/esm/api/validation.d.ts.map +1 -1
- package/dist/esm/api/validation.js +6 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +163 -47
- package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/overflow.js +39 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
- package/dist/esm/components/canvas-grid/typings.d.ts +25 -0
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.d.ts +83 -1
- package/dist/esm/components/cell/alignment.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.js +143 -1
- package/dist/esm/components/cell/cell-background.d.ts +18 -0
- package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-background.js +110 -41
- package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-backgrounds.js +5 -1
- package/dist/esm/components/cell/cell-text-runs.d.ts +12 -5
- package/dist/esm/components/cell/cell-text-runs.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-text-runs.js +19 -24
- package/dist/esm/components/cell/index.d.ts.map +1 -1
- package/dist/esm/components/cell/index.js +352 -46
- package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
- package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/esm/components/cell/number-format-layout.js +99 -0
- package/dist/esm/components/cell/typings.d.ts +22 -0
- package/dist/esm/components/cell/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +2 -2
- package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
- package/dist/esm/components/cell-filter/index.js +4 -4
- package/dist/esm/components/cell-overlay/index.d.ts +20 -0
- package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/esm/components/cell-overlay/index.js +111 -25
- package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/esm/components/cf-icon-preview/index.js +41 -0
- package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/esm/components/embeds/embed-component.js +4 -3
- package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/index.js +9 -8
- package/dist/esm/components/hidden-markers/style.d.ts +7 -0
- package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/style.js +8 -1
- package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
- package/dist/esm/components/toolbar/types.d.ts +1 -1
- package/dist/esm/components/toolbar/types.d.ts.map +1 -1
- package/dist/esm/config.d.ts +13 -1
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +13 -1
- package/dist/esm/helpers.d.ts +15 -5
- package/dist/esm/helpers.d.ts.map +1 -1
- package/dist/esm/helpers.js +48 -32
- package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/esm/hooks/use-border-styles.js +5 -26
- package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +83 -42
- package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/esm/hooks/use-conditional-formatting.js +215 -120
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/themes.d.ts +8 -0
- package/dist/esm/themes.d.ts.map +1 -1
- package/dist/esm/themes.js +20 -3
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +81 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Paint-time expansion of Excel's width-aware number-format tokens: `*x`
|
|
2
|
+
// repeats `x` across the cell's free width, `_x` reserves the width of `x`
|
|
3
|
+
// and `?` reserves a digit's width ("Number format codes",
|
|
4
|
+
// support.microsoft.com). The formatter keeps those as parts
|
|
5
|
+
// (`ssfFormatLayout`); this module turns them into positioned text runs once
|
|
6
|
+
// the glyph widths are known.
|
|
7
|
+
import { numberFormatLayoutText, ssfFormatLayout, } from "@rowsncolumns/utils";
|
|
8
|
+
/**
|
|
9
|
+
* Position the parts inside `availableWidth`. Parts before the (first) fill
|
|
10
|
+
* start at the left edge and parts after it end at the right edge, with the
|
|
11
|
+
* fill character repeated in between as many whole times as it fits —
|
|
12
|
+
* Excel's accounting format (`$` left, number right). Without a fill the
|
|
13
|
+
* block is aligned by `align`. Returns `undefined` when the fixed parts
|
|
14
|
+
* alone do not fit, so the caller keeps its plain-text paint.
|
|
15
|
+
*/
|
|
16
|
+
export const layoutNumberFormatParts = ({ parts, measure, availableWidth, align, }) => {
|
|
17
|
+
const widthOf = (part) => {
|
|
18
|
+
switch (part.type) {
|
|
19
|
+
case "text":
|
|
20
|
+
return measure(part.text);
|
|
21
|
+
case "skip":
|
|
22
|
+
return measure(part.char);
|
|
23
|
+
case "digit":
|
|
24
|
+
return measure("0");
|
|
25
|
+
default:
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const fillIndex = parts.findIndex((part) => part.type === "fill");
|
|
30
|
+
// Excel honours one `*` per section; a later one paints nothing.
|
|
31
|
+
const widths = parts.map(widthOf);
|
|
32
|
+
const fixedWidth = widths.reduce((total, width) => total + width, 0);
|
|
33
|
+
if (fixedWidth > availableWidth + 0.5)
|
|
34
|
+
return undefined;
|
|
35
|
+
const runs = [];
|
|
36
|
+
const pushRuns = (from, to, startX) => {
|
|
37
|
+
let cursor = startX;
|
|
38
|
+
for (let i = from; i < to; i++) {
|
|
39
|
+
const part = parts[i];
|
|
40
|
+
if (part.type === "text" && part.text) {
|
|
41
|
+
runs.push({ text: part.text, x: cursor, width: widths[i] });
|
|
42
|
+
}
|
|
43
|
+
cursor += widths[i];
|
|
44
|
+
}
|
|
45
|
+
return cursor;
|
|
46
|
+
};
|
|
47
|
+
if (fillIndex < 0) {
|
|
48
|
+
const offset = align === "right"
|
|
49
|
+
? availableWidth - fixedWidth
|
|
50
|
+
: align === "center"
|
|
51
|
+
? (availableWidth - fixedWidth) / 2
|
|
52
|
+
: 0;
|
|
53
|
+
const end = pushRuns(0, parts.length, offset);
|
|
54
|
+
return { runs, start: offset, end };
|
|
55
|
+
}
|
|
56
|
+
const fill = parts[fillIndex];
|
|
57
|
+
const leftEnd = pushRuns(0, fillIndex, 0);
|
|
58
|
+
const rightWidth = widths
|
|
59
|
+
.slice(fillIndex + 1)
|
|
60
|
+
.reduce((total, width) => total + width, 0);
|
|
61
|
+
const rightStart = availableWidth - rightWidth;
|
|
62
|
+
const fillCharWidth = measure(fill.char);
|
|
63
|
+
const gap = rightStart - leftEnd;
|
|
64
|
+
const copies = fillCharWidth > 0 ? Math.max(0, Math.floor(gap / fillCharWidth + 1e-6)) : 0;
|
|
65
|
+
const leftRunCount = runs.length;
|
|
66
|
+
pushRuns(fillIndex + 1, parts.length, rightStart);
|
|
67
|
+
if (copies > 0 && fill.char.trim()) {
|
|
68
|
+
runs.splice(leftRunCount, 0, {
|
|
69
|
+
text: fill.char.repeat(copies),
|
|
70
|
+
x: leftEnd,
|
|
71
|
+
width: copies * fillCharWidth,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return { runs, start: 0, end: availableWidth };
|
|
75
|
+
};
|
|
76
|
+
const LAYOUT_CACHE_LIMIT = 2048;
|
|
77
|
+
const layoutCache = new Map();
|
|
78
|
+
/**
|
|
79
|
+
* The layout parts for a cell, or `undefined` when the pattern has no
|
|
80
|
+
* width-aware token or when the parts would paint a different string than
|
|
81
|
+
* the cell's formatted value (another engine, locale or conditional number
|
|
82
|
+
* format produced it) — the plain string then stays authoritative.
|
|
83
|
+
*/
|
|
84
|
+
export const getCellNumberFormatLayout = (pattern, value, formattedValue, locale) => {
|
|
85
|
+
if (!pattern || value === null || value === undefined || !formattedValue) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const key = `${locale ?? ""}\u0000${pattern}\u0000${typeof value}\u0000${value}`;
|
|
89
|
+
let parts = layoutCache.get(key);
|
|
90
|
+
if (parts === undefined) {
|
|
91
|
+
parts = ssfFormatLayout(pattern, value, locale) ?? null;
|
|
92
|
+
if (layoutCache.size >= LAYOUT_CACHE_LIMIT)
|
|
93
|
+
layoutCache.clear();
|
|
94
|
+
layoutCache.set(key, parts);
|
|
95
|
+
}
|
|
96
|
+
if (!parts)
|
|
97
|
+
return undefined;
|
|
98
|
+
return numberFormatLayoutText(parts) === formattedValue ? parts : undefined;
|
|
99
|
+
};
|
|
@@ -2,6 +2,7 @@ import type { StructuredResult } from "@rowsncolumns/common-types";
|
|
|
2
2
|
import type { SparklineAxisExtents } from "../cell-structured/sparkline-math";
|
|
3
3
|
import type { CellInterface, LineHeightMode, RendererProps } from "@rowsncolumns/grid";
|
|
4
4
|
import type { TextFormatRun } from "@rowsncolumns/ui";
|
|
5
|
+
import type { NumberFormatLayoutPart } from "@rowsncolumns/utils";
|
|
5
6
|
import type { CellFormat, Color, SortOrder, WrapStrategy } from "../../types";
|
|
6
7
|
import type { CanvasGridProps, SpreadsheetTheme } from "../canvas-grid/typings";
|
|
7
8
|
import { CellRendererProps } from "../../hooks/use-cell-renderer";
|
|
@@ -157,11 +158,32 @@ export type CellProps<S extends StructuredResult = StructuredResult> = RendererP
|
|
|
157
158
|
*/
|
|
158
159
|
expanded?: boolean;
|
|
159
160
|
overflowRight?: boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Centred overflow: pixels the text claims left of the cell (the rest of
|
|
163
|
+
* `cellWidth` lies to its right). Unset for left / right spills.
|
|
164
|
+
*/
|
|
165
|
+
overflowLeft?: number;
|
|
166
|
+
/**
|
|
167
|
+
* Center Across Selection: centre on the whole span instead of on the
|
|
168
|
+
* cell itself.
|
|
169
|
+
*/
|
|
170
|
+
centerOnSpan?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* The dropdown button paints beside the cell, past its right edge, and
|
|
173
|
+
* reserves no room inside it (a data-validation list on the active cell).
|
|
174
|
+
*/
|
|
175
|
+
arrowOutside?: boolean;
|
|
160
176
|
defaultFontSizePoint: number;
|
|
161
177
|
/**
|
|
162
178
|
* Text formatting options of a cell
|
|
163
179
|
*/
|
|
164
180
|
textFormatRuns?: TextFormatRun[] | null;
|
|
181
|
+
/**
|
|
182
|
+
* Width-aware parts of the cell's number format (`*x` fill, `_x` and
|
|
183
|
+
* `?` reserves) when its pattern has any; the painter expands them with
|
|
184
|
+
* measured glyph widths instead of painting `value` as one string.
|
|
185
|
+
*/
|
|
186
|
+
numberFormatLayout?: NumberFormatLayoutPart[];
|
|
165
187
|
/**
|
|
166
188
|
* Structured result
|
|
167
189
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typings.d.ts","sourceRoot":"","sources":["../../../../components/cell/typings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"typings.d.ts","sourceRoot":"","sources":["../../../../components/cell/typings.ts"],"names":[],"mappings":"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"}
|
|
@@ -262,10 +262,10 @@ export const CellEditor = memo(({ value = "", effectiveValue, isNewValue, onChan
|
|
|
262
262
|
minWidth,
|
|
263
263
|
minHeight,
|
|
264
264
|
paddingLeft: finalHorizontalAlignment === "left"
|
|
265
|
-
? INDENT_SPACING * indent + 1
|
|
265
|
+
? INDENT_SPACING * indent * scale + 1
|
|
266
266
|
: 0,
|
|
267
267
|
paddingRight: finalHorizontalAlignment === "right"
|
|
268
|
-
? INDENT_SPACING * indent + 1
|
|
268
|
+
? INDENT_SPACING * indent * scale + 1
|
|
269
269
|
: 0,
|
|
270
270
|
maxWidth,
|
|
271
271
|
maxHeight,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-filter/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAgC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-filter/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAgC,MAAM,OAAO,CAAC;AAerD,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,KAAK,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,EAAE,aAAa,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAkGhD,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { lightenColor } from "@rowsncolumns/utils";
|
|
2
2
|
import React, { useCallback, useState } from "react";
|
|
3
3
|
import { Group, Path, Rect } from "react-konva";
|
|
4
|
-
import { DEFAULT_CELL_SPACING, FILTER_ICON_WIDTH, FITLER_ICON_PATH, FUNNEL_ICON_PATH, SORT_ASCENDING_ICON_PATH, SORT_DESCENDING_ICON_PATH, } from "../../config";
|
|
4
|
+
import { DEFAULT_CELL_SPACING, FILTER_BUTTON_BORDER_COLOR, FILTER_BUTTON_FILL_COLOR, FILTER_BUTTON_GLYPH_COLOR, FILTER_ICON_WIDTH, FITLER_ICON_PATH, FUNNEL_ICON_PATH, SORT_ASCENDING_ICON_PATH, SORT_DESCENDING_ICON_PATH, } from "../../config";
|
|
5
5
|
import { getIconSpacing } from "../../helpers";
|
|
6
6
|
/**
|
|
7
7
|
* Filter icon
|
|
8
8
|
*/
|
|
9
|
-
export const CellFilter = ({ x = 0, y = 0, width = 0, height = 0, rowIndex, columnIndex, scale, onClick, isActive, filterIconColor =
|
|
9
|
+
export const CellFilter = ({ x = 0, y = 0, width = 0, height = 0, rowIndex, columnIndex, scale, onClick, isActive, filterIconColor = FILTER_BUTTON_GLYPH_COLOR, verticalAlignment, sortOrder, }) => {
|
|
10
10
|
const cellSpacing = DEFAULT_CELL_SPACING;
|
|
11
11
|
// Without a click handler (a readonly grid) the icon is a pure state indicator —
|
|
12
12
|
// no hover highlight, or it reads as clickable.
|
|
@@ -38,8 +38,8 @@ export const CellFilter = ({ x = 0, y = 0, width = 0, height = 0, rowIndex, colu
|
|
|
38
38
|
event.evt.stopPropagation();
|
|
39
39
|
}, perfectDrawEnabled: false, onMouseDown: (e) => e.evt.preventDefault() },
|
|
40
40
|
React.createElement(Rect, { x: posX, y: posY, width: FILTER_ICON_WIDTH * scale, height: FILTER_ICON_WIDTH * scale, fill: isHovered
|
|
41
|
-
? lightenColor(0.2, filterIconColor ??
|
|
42
|
-
:
|
|
41
|
+
? lightenColor(0.2, filterIconColor ?? FILTER_BUTTON_GLYPH_COLOR)
|
|
42
|
+
: FILTER_BUTTON_FILL_COLOR, cornerRadius: 0, perfectDrawEnabled: false, stroke: FILTER_BUTTON_BORDER_COLOR, strokeWidth: 1, hitStrokeWidth: 0 }),
|
|
43
43
|
sortIconPath ? (React.createElement(Path, { data: sortIconPath, x: posX + 0.5, y: posY + 0.5, fill: iconFill, scaleY: 0.4 * scale, scaleX: 0.4 * scale, perfectDrawEnabled: false })) : null,
|
|
44
44
|
React.createElement(Path, { data: isActive ? FUNNEL_ICON_PATH : FITLER_ICON_PATH, x: posX + 0.5 + glyphOffset, y: posY + 0.5 + glyphOffset, fill: iconFill, scaleY: glyphScale, scaleX: glyphScale, perfectDrawEnabled: false })));
|
|
45
45
|
};
|
|
@@ -17,6 +17,26 @@ export type StrokeCellProps = Omit<CellOverlayRendererProps, "key" | "rowIndex"
|
|
|
17
17
|
* @param width
|
|
18
18
|
*/
|
|
19
19
|
export declare const getOffsetFromWidth: (width: number) => number;
|
|
20
|
+
export type SlantQuad = [number, number][];
|
|
21
|
+
/**
|
|
22
|
+
* Excel paints `slantDashDot` as dash-dot runs whose ends slant: each run of
|
|
23
|
+
* `dash` (on/off lengths, already zoomed) along an edge becomes a
|
|
24
|
+
* parallelogram `width` thick, its top edge shifted forward by half the
|
|
25
|
+
* width and its bottom edge back. `at` is the edge's cross-axis position.
|
|
26
|
+
*/
|
|
27
|
+
export declare const getSlantDashQuads: (axis: "horizontal" | "vertical", length: number, at: number, width: number, dash: readonly number[]) => SlantQuad[];
|
|
28
|
+
export type DiagonalStroke = {
|
|
29
|
+
x1: number;
|
|
30
|
+
y1: number;
|
|
31
|
+
x2: number;
|
|
32
|
+
y2: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The line(s) of a diagonal border across a `width` × `height` cell. A
|
|
36
|
+
* non-zero `doubleGap` gives the two parallel lines of a double diagonal,
|
|
37
|
+
* each `doubleGap` away from the corner-to-corner line.
|
|
38
|
+
*/
|
|
39
|
+
export declare const getDiagonalStrokes: (direction: "up" | "down", width: number, height: number, doubleGap?: number) => DiagonalStroke[];
|
|
20
40
|
/**
|
|
21
41
|
* Default CellRenderer
|
|
22
42
|
* @param props
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-overlay/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,wBAAwB,GAAG,aAAa,GAAG;IACrD,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,qBAAqB,CAAC,EAAE,WAAW,CAAC;IACpC,uBAAuB,CAAC,EAAE,WAAW,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,wBAAwB,EACxB,KAAK,GAAG,UAAU,GAAG,aAAa,CACnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,WAE/C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-overlay/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,wBAAwB,GAAG,aAAa,GAAG;IACrD,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,qBAAqB,CAAC,EAAE,WAAW,CAAC;IACpC,uBAAuB,CAAC,EAAE,WAAW,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,wBAAwB,EACxB,KAAK,GAAG,UAAU,GAAG,aAAa,CACnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,WAE/C,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,GAAG,UAAU,EAC/B,QAAQ,MAAM,EACd,IAAI,MAAM,EACV,OAAO,MAAM,EACb,MAAM,SAAS,MAAM,EAAE,KACtB,SAAS,EAyBX,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,IAAI,GAAG,MAAM,EACxB,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,kBAAa,KACZ,cAAc,EAgBhB,CAAC;AAwRF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,6BAmFlE,CAAC"}
|
|
@@ -8,11 +8,64 @@ import { DEFAULT_ARRAY } from "../../config";
|
|
|
8
8
|
export const getOffsetFromWidth = (width) => {
|
|
9
9
|
return width / 2 - 0.5;
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Excel paints `slantDashDot` as dash-dot runs whose ends slant: each run of
|
|
13
|
+
* `dash` (on/off lengths, already zoomed) along an edge becomes a
|
|
14
|
+
* parallelogram `width` thick, its top edge shifted forward by half the
|
|
15
|
+
* width and its bottom edge back. `at` is the edge's cross-axis position.
|
|
16
|
+
*/
|
|
17
|
+
export const getSlantDashQuads = (axis, length, at, width, dash) => {
|
|
18
|
+
const quads = [];
|
|
19
|
+
if (!dash.length || width <= 0)
|
|
20
|
+
return quads;
|
|
21
|
+
const half = width / 2;
|
|
22
|
+
let cursor = 0;
|
|
23
|
+
for (let i = 0; cursor < length && i < 100000; i++) {
|
|
24
|
+
const run = dash[i % dash.length];
|
|
25
|
+
if (i % 2 === 0 && run > 0) {
|
|
26
|
+
const a = cursor;
|
|
27
|
+
const b = Math.min(length, cursor + run);
|
|
28
|
+
const points = [
|
|
29
|
+
[a + half, at - half],
|
|
30
|
+
[b + half, at - half],
|
|
31
|
+
[b - half, at + half],
|
|
32
|
+
[a - half, at + half],
|
|
33
|
+
];
|
|
34
|
+
quads.push(axis === "horizontal"
|
|
35
|
+
? points
|
|
36
|
+
: points.map(([along, across]) => [across, along]));
|
|
37
|
+
}
|
|
38
|
+
cursor += run;
|
|
39
|
+
}
|
|
40
|
+
return quads;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The line(s) of a diagonal border across a `width` × `height` cell. A
|
|
44
|
+
* non-zero `doubleGap` gives the two parallel lines of a double diagonal,
|
|
45
|
+
* each `doubleGap` away from the corner-to-corner line.
|
|
46
|
+
*/
|
|
47
|
+
export const getDiagonalStrokes = (direction, width, height, doubleGap = 0) => {
|
|
48
|
+
const base = direction === "down"
|
|
49
|
+
? { x1: 0, y1: 0, x2: width, y2: height }
|
|
50
|
+
: { x1: 0, y1: height, x2: width, y2: 0 };
|
|
51
|
+
if (!doubleGap)
|
|
52
|
+
return [base];
|
|
53
|
+
const length = Math.hypot(width, height) || 1;
|
|
54
|
+
// Unit normal of the line.
|
|
55
|
+
const nx = (base.y2 - base.y1) / length;
|
|
56
|
+
const ny = -(base.x2 - base.x1) / length;
|
|
57
|
+
return [-1, 1].map((side) => ({
|
|
58
|
+
x1: base.x1 + side * doubleGap * nx,
|
|
59
|
+
y1: base.y1 + side * doubleGap * ny,
|
|
60
|
+
x2: base.x2 + side * doubleGap * nx,
|
|
61
|
+
y2: base.y2 + side * doubleGap * ny,
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
11
64
|
/**
|
|
12
65
|
* Only used for strokes
|
|
13
66
|
*/
|
|
14
67
|
const CellOverlay = memo((props) => {
|
|
15
|
-
const { x, y, width, height, strokeDoubleInsetWidth, strokeTopColor, strokeRightColor, strokeBottomColor, strokeLeftColor, strokeDiagonalUpColor, strokeDiagonalDownColor, strokeTopDash = DEFAULT_ARRAY, strokeRightDash = DEFAULT_ARRAY, strokeBottomDash = DEFAULT_ARRAY, strokeLeftDash = DEFAULT_ARRAY, strokeDiagonalUpDash = DEFAULT_ARRAY, strokeDiagonalDownDash = DEFAULT_ARRAY, strokeTopWidth = 0, strokeRightWidth = 0, strokeBottomWidth = 0, strokeLeftWidth = 0, strokeDiagonalUpWidth = 0, strokeDiagonalDownWidth = 0, lineCap, strokeTopStyle, strokeBottomStyle, strokeLeftStyle, strokeRightStyle, cellBackgroundColor, } = props;
|
|
68
|
+
const { x, y, width, height, strokeDoubleInsetWidth, strokeTopColor, strokeRightColor, strokeBottomColor, strokeLeftColor, strokeDiagonalUpColor, strokeDiagonalDownColor, strokeTopDash = DEFAULT_ARRAY, strokeRightDash = DEFAULT_ARRAY, strokeBottomDash = DEFAULT_ARRAY, strokeLeftDash = DEFAULT_ARRAY, strokeDiagonalUpDash = DEFAULT_ARRAY, strokeDiagonalDownDash = DEFAULT_ARRAY, strokeTopWidth = 0, strokeRightWidth = 0, strokeBottomWidth = 0, strokeLeftWidth = 0, strokeDiagonalUpWidth = 0, strokeDiagonalDownWidth = 0, lineCap, strokeTopStyle, strokeBottomStyle, strokeLeftStyle, strokeRightStyle, strokeDiagonalUpStyle, strokeDiagonalDownStyle, cellBackgroundColor, } = props;
|
|
16
69
|
const userStroke = strokeTopColor ||
|
|
17
70
|
strokeRightColor ||
|
|
18
71
|
strokeBottomColor ||
|
|
@@ -23,8 +76,20 @@ const CellOverlay = memo((props) => {
|
|
|
23
76
|
return null;
|
|
24
77
|
}
|
|
25
78
|
return (React.createElement(Shape, { x: x, y: y, width: width, height: height, listening: false, perfectDrawEnabled: false, sceneFunc: (context, shape) => {
|
|
79
|
+
const fillSlant = (quads, color) => {
|
|
80
|
+
context.beginPath();
|
|
81
|
+
for (const quad of quads) {
|
|
82
|
+
quad.forEach(([px, py], index) => index ? context.lineTo(px, py) : context.moveTo(px, py));
|
|
83
|
+
context.closePath();
|
|
84
|
+
}
|
|
85
|
+
context.setAttr("fillStyle", color);
|
|
86
|
+
context.fill();
|
|
87
|
+
};
|
|
26
88
|
/* Top border */
|
|
27
|
-
if (strokeTopColor) {
|
|
89
|
+
if (strokeTopColor && strokeTopStyle === "slantDashDot") {
|
|
90
|
+
fillSlant(getSlantDashQuads("horizontal", shape.width() + 1, 0.5, strokeTopWidth, strokeTopDash), strokeTopColor);
|
|
91
|
+
}
|
|
92
|
+
else if (strokeTopColor) {
|
|
28
93
|
context.beginPath();
|
|
29
94
|
context.moveTo(strokeLeftColor ? -getOffsetFromWidth(strokeLeftWidth) : 0, 0.5);
|
|
30
95
|
context.lineTo(shape.width() +
|
|
@@ -36,7 +101,10 @@ const CellOverlay = memo((props) => {
|
|
|
36
101
|
context.stroke();
|
|
37
102
|
}
|
|
38
103
|
/* Bottom border */
|
|
39
|
-
if (strokeBottomColor) {
|
|
104
|
+
if (strokeBottomColor && strokeBottomStyle === "slantDashDot") {
|
|
105
|
+
fillSlant(getSlantDashQuads("horizontal", shape.width() + 1, shape.height() + 0.5, strokeBottomWidth, strokeBottomDash), strokeBottomColor);
|
|
106
|
+
}
|
|
107
|
+
else if (strokeBottomColor) {
|
|
40
108
|
context.beginPath();
|
|
41
109
|
context.moveTo(strokeLeftColor ? -getOffsetFromWidth(strokeLeftWidth) : 0, shape.height() + 0.5);
|
|
42
110
|
context.lineTo(shape.width() +
|
|
@@ -48,7 +116,10 @@ const CellOverlay = memo((props) => {
|
|
|
48
116
|
context.stroke();
|
|
49
117
|
}
|
|
50
118
|
/* Left border */
|
|
51
|
-
if (strokeLeftColor) {
|
|
119
|
+
if (strokeLeftColor && strokeLeftStyle === "slantDashDot") {
|
|
120
|
+
fillSlant(getSlantDashQuads("vertical", shape.height() + 1, 0.5, strokeLeftWidth, strokeLeftDash), strokeLeftColor);
|
|
121
|
+
}
|
|
122
|
+
else if (strokeLeftColor) {
|
|
52
123
|
context.beginPath();
|
|
53
124
|
context.moveTo(0.5, strokeTopColor ? -getOffsetFromWidth(strokeTopWidth) : 0);
|
|
54
125
|
context.lineTo(0.5, shape.height() +
|
|
@@ -62,7 +133,10 @@ const CellOverlay = memo((props) => {
|
|
|
62
133
|
context.stroke();
|
|
63
134
|
}
|
|
64
135
|
/* Right border */
|
|
65
|
-
if (strokeRightColor) {
|
|
136
|
+
if (strokeRightColor && strokeRightStyle === "slantDashDot") {
|
|
137
|
+
fillSlant(getSlantDashQuads("vertical", shape.height() + 1, shape.width() + 0.5, strokeRightWidth, strokeRightDash), strokeRightColor);
|
|
138
|
+
}
|
|
139
|
+
else if (strokeRightColor) {
|
|
66
140
|
context.beginPath();
|
|
67
141
|
context.moveTo(shape.width() + 0.5, strokeTopColor ? -getOffsetFromWidth(strokeTopWidth) : 0);
|
|
68
142
|
context.lineTo(shape.width() + 0.5, shape.height() +
|
|
@@ -112,26 +186,38 @@ const CellOverlay = memo((props) => {
|
|
|
112
186
|
}
|
|
113
187
|
context.closePath();
|
|
114
188
|
}
|
|
115
|
-
/*
|
|
116
|
-
|
|
189
|
+
/* Diagonals: top-left → bottom-right (diagonalDown), bottom-left →
|
|
190
|
+
top-right (diagonalUp). A double diagonal is two thin parallel
|
|
191
|
+
lines, as Excel draws it. */
|
|
192
|
+
const diagonals = [
|
|
193
|
+
{
|
|
194
|
+
direction: "down",
|
|
195
|
+
color: strokeDiagonalDownColor,
|
|
196
|
+
width: strokeDiagonalDownWidth,
|
|
197
|
+
dash: strokeDiagonalDownDash,
|
|
198
|
+
style: strokeDiagonalDownStyle,
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
direction: "up",
|
|
202
|
+
color: strokeDiagonalUpColor,
|
|
203
|
+
width: strokeDiagonalUpWidth,
|
|
204
|
+
dash: strokeDiagonalUpDash,
|
|
205
|
+
style: strokeDiagonalUpStyle,
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
for (const diagonal of diagonals) {
|
|
209
|
+
if (!diagonal.color)
|
|
210
|
+
continue;
|
|
211
|
+
const isDouble = diagonal.style === "double";
|
|
117
212
|
context.beginPath();
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
context.setAttr("
|
|
123
|
-
context.
|
|
124
|
-
context.stroke();
|
|
125
|
-
}
|
|
126
|
-
/* Diagonal: bottom-left to top-right (diagonalUp) */
|
|
127
|
-
if (strokeDiagonalUpColor) {
|
|
128
|
-
context.beginPath();
|
|
129
|
-
context.moveTo(0, shape.height());
|
|
130
|
-
context.lineTo(shape.width(), 0);
|
|
131
|
-
context.setAttr("strokeStyle", strokeDiagonalUpColor);
|
|
132
|
-
context.setAttr("lineWidth", strokeDiagonalUpWidth);
|
|
213
|
+
for (const line of getDiagonalStrokes(diagonal.direction, shape.width(), shape.height(), isDouble ? diagonal.width / 3 : 0)) {
|
|
214
|
+
context.moveTo(line.x1, line.y1);
|
|
215
|
+
context.lineTo(line.x2, line.y2);
|
|
216
|
+
}
|
|
217
|
+
context.setAttr("strokeStyle", diagonal.color);
|
|
218
|
+
context.setAttr("lineWidth", isDouble ? diagonal.width / 3 : diagonal.width);
|
|
133
219
|
context.setAttr("lineCap", lineCap);
|
|
134
|
-
context.setLineDash(
|
|
220
|
+
context.setLineDash(diagonal.dash);
|
|
135
221
|
context.stroke();
|
|
136
222
|
}
|
|
137
223
|
} }));
|
|
@@ -141,7 +227,7 @@ const CellOverlay = memo((props) => {
|
|
|
141
227
|
* @param props
|
|
142
228
|
*/
|
|
143
229
|
export const CellOverlayRenderer = (props) => {
|
|
144
|
-
const { x, y, width, height, stroke, strokeTopColor = stroke, strokeRightColor = stroke, strokeBottomColor = stroke, strokeLeftColor = stroke, strokeDiagonalUpColor, strokeDiagonalDownColor, strokeDash = DEFAULT_ARRAY, strokeTopDash = DEFAULT_ARRAY, strokeRightDash = DEFAULT_ARRAY, strokeBottomDash = DEFAULT_ARRAY, strokeLeftDash = DEFAULT_ARRAY, strokeDiagonalUpDash = DEFAULT_ARRAY, strokeDiagonalDownDash = DEFAULT_ARRAY, strokeWidth = 1, strokeTopWidth = strokeWidth, strokeRightWidth = strokeWidth, strokeBottomWidth = strokeWidth, strokeLeftWidth = strokeWidth, strokeDiagonalUpWidth = strokeWidth, strokeDiagonalDownWidth = strokeWidth, strokeTopStyle, strokeBottomStyle, strokeLeftStyle, strokeRightStyle, cellBackgroundColor, lineCap = "butt", key, strokeDoubleInsetWidth = 1, } = props;
|
|
230
|
+
const { x, y, width, height, stroke, strokeTopColor = stroke, strokeRightColor = stroke, strokeBottomColor = stroke, strokeLeftColor = stroke, strokeDiagonalUpColor, strokeDiagonalDownColor, strokeDash = DEFAULT_ARRAY, strokeTopDash = DEFAULT_ARRAY, strokeRightDash = DEFAULT_ARRAY, strokeBottomDash = DEFAULT_ARRAY, strokeLeftDash = DEFAULT_ARRAY, strokeDiagonalUpDash = DEFAULT_ARRAY, strokeDiagonalDownDash = DEFAULT_ARRAY, strokeWidth = 1, strokeTopWidth = strokeWidth, strokeRightWidth = strokeWidth, strokeBottomWidth = strokeWidth, strokeLeftWidth = strokeWidth, strokeDiagonalUpWidth = strokeWidth, strokeDiagonalDownWidth = strokeWidth, strokeTopStyle, strokeBottomStyle, strokeLeftStyle, strokeRightStyle, strokeDiagonalUpStyle, strokeDiagonalDownStyle, cellBackgroundColor, lineCap = "butt", key, strokeDoubleInsetWidth = 1, } = props;
|
|
145
231
|
const userStroke = strokeTopColor ||
|
|
146
232
|
strokeRightColor ||
|
|
147
233
|
strokeBottomColor ||
|
|
@@ -150,6 +236,6 @@ export const CellOverlayRenderer = (props) => {
|
|
|
150
236
|
strokeDiagonalDownColor;
|
|
151
237
|
if (!userStroke)
|
|
152
238
|
return null;
|
|
153
|
-
return (React.createElement(CellOverlay, { key: key, x: x, y: y, strokeDoubleInsetWidth: strokeDoubleInsetWidth, width: width, height: height, strokeTopColor: strokeTopColor, strokeRightColor: strokeRightColor, strokeBottomColor: strokeBottomColor, strokeLeftColor: strokeLeftColor, strokeDiagonalUpColor: strokeDiagonalUpColor, strokeDiagonalDownColor: strokeDiagonalDownColor, strokeDash: strokeDash, strokeTopDash: strokeTopDash, strokeRightDash: strokeRightDash, strokeBottomDash: strokeBottomDash, strokeLeftDash: strokeLeftDash, strokeDiagonalUpDash: strokeDiagonalUpDash, strokeDiagonalDownDash: strokeDiagonalDownDash, strokeTopWidth: strokeTopWidth, strokeRightWidth: strokeRightWidth, strokeBottomWidth: strokeBottomWidth, strokeLeftWidth: strokeLeftWidth, strokeDiagonalUpWidth: strokeDiagonalUpWidth, strokeDiagonalDownWidth: strokeDiagonalDownWidth, lineCap: lineCap, strokeTopStyle: strokeTopStyle, strokeBottomStyle: strokeBottomStyle, strokeLeftStyle: strokeLeftStyle, strokeRightStyle: strokeRightStyle, cellBackgroundColor: cellBackgroundColor }));
|
|
239
|
+
return (React.createElement(CellOverlay, { key: key, x: x, y: y, strokeDoubleInsetWidth: strokeDoubleInsetWidth, width: width, height: height, strokeTopColor: strokeTopColor, strokeRightColor: strokeRightColor, strokeBottomColor: strokeBottomColor, strokeLeftColor: strokeLeftColor, strokeDiagonalUpColor: strokeDiagonalUpColor, strokeDiagonalDownColor: strokeDiagonalDownColor, strokeDash: strokeDash, strokeTopDash: strokeTopDash, strokeRightDash: strokeRightDash, strokeBottomDash: strokeBottomDash, strokeLeftDash: strokeLeftDash, strokeDiagonalUpDash: strokeDiagonalUpDash, strokeDiagonalDownDash: strokeDiagonalDownDash, strokeTopWidth: strokeTopWidth, strokeRightWidth: strokeRightWidth, strokeBottomWidth: strokeBottomWidth, strokeLeftWidth: strokeLeftWidth, strokeDiagonalUpWidth: strokeDiagonalUpWidth, strokeDiagonalDownWidth: strokeDiagonalDownWidth, lineCap: lineCap, strokeTopStyle: strokeTopStyle, strokeBottomStyle: strokeBottomStyle, strokeLeftStyle: strokeLeftStyle, strokeRightStyle: strokeRightStyle, strokeDiagonalUpStyle: strokeDiagonalUpStyle, strokeDiagonalDownStyle: strokeDiagonalDownStyle, cellBackgroundColor: cellBackgroundColor }));
|
|
154
240
|
};
|
|
155
241
|
CellOverlay.displayName = "CellOverlay";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type CfIconPaintContext } from "../../api/cf-icons";
|
|
3
|
+
/** A DOM 2D context exposed through the painter's `setAttr` contract. */
|
|
4
|
+
export declare const toCfIconPaintContext: (ctx: CanvasRenderingContext2D) => CfIconPaintContext;
|
|
5
|
+
export type CfIconPreviewProps = {
|
|
6
|
+
iconSet: string;
|
|
7
|
+
iconId: number;
|
|
8
|
+
/** CSS pixel size of the square icon. */
|
|
9
|
+
size?: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* One conditional-format icon, drawn by the same painter the grid uses — for
|
|
13
|
+
* the rule editor's icon-style and per-icon pickers.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CfIconPreview: ({ iconSet, iconId, size, }: CfIconPreviewProps) => React.JSX.Element | null;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cf-icon-preview/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,OAAO,EACL,KAAK,kBAAkB,EAGxB,MAAM,oBAAoB,CAAC;AAE5B,yEAAyE;AACzE,eAAO,MAAM,oBAAoB,GAC/B,KAAK,wBAAwB,KAC5B,kBAsBD,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,4BAI3B,kBAAkB,6BAuBpB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
import { getCfIcon, paintCfIcon, } from "../../api/cf-icons";
|
|
3
|
+
/** A DOM 2D context exposed through the painter's `setAttr` contract. */
|
|
4
|
+
export const toCfIconPaintContext = (ctx) => ({
|
|
5
|
+
save: () => ctx.save(),
|
|
6
|
+
restore: () => ctx.restore(),
|
|
7
|
+
beginPath: () => ctx.beginPath(),
|
|
8
|
+
closePath: () => ctx.closePath(),
|
|
9
|
+
moveTo: (x, y) => ctx.moveTo(x, y),
|
|
10
|
+
lineTo: (x, y) => ctx.lineTo(x, y),
|
|
11
|
+
arc: (x, y, r, start, end, ccw) => ctx.arc(x, y, r, start, end, ccw),
|
|
12
|
+
rect: (x, y, w, h) => ctx.rect(x, y, w, h),
|
|
13
|
+
fill: () => ctx.fill(),
|
|
14
|
+
stroke: () => ctx.stroke(),
|
|
15
|
+
clip: () => ctx.clip(),
|
|
16
|
+
setAttr: (attr, value) => {
|
|
17
|
+
ctx[attr] = value;
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* One conditional-format icon, drawn by the same painter the grid uses — for
|
|
22
|
+
* the rule editor's icon-style and per-icon pickers.
|
|
23
|
+
*/
|
|
24
|
+
export const CfIconPreview = ({ iconSet, iconId, size = 16, }) => {
|
|
25
|
+
const ref = useRef(null);
|
|
26
|
+
const icon = getCfIcon(iconSet, iconId);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const canvas = ref.current;
|
|
29
|
+
const ctx = canvas?.getContext("2d");
|
|
30
|
+
if (!canvas || !ctx || !icon)
|
|
31
|
+
return;
|
|
32
|
+
const ratio = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
33
|
+
canvas.width = size * ratio;
|
|
34
|
+
canvas.height = size * ratio;
|
|
35
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
36
|
+
paintCfIcon(toCfIconPaintContext(ctx), icon, 0, 0, size * ratio);
|
|
37
|
+
}, [icon, size]);
|
|
38
|
+
if (!icon)
|
|
39
|
+
return null;
|
|
40
|
+
return (React.createElement("canvas", { ref: ref, "data-cf-icon": `${iconSet}:${iconId}`, style: { width: size, height: size, display: "inline-block" }, "aria-hidden": true }));
|
|
41
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-component.d.ts","sourceRoot":"","sources":["../../../../components/embeds/embed-component.tsx"],"names":[],"mappings":"AASA,OAAO,KAAe,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAKhF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,kBAAkB,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC;CAC3D,CAAC;AAEF,eAAO,MAAM,cAAc,wHAUtB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"embed-component.d.ts","sourceRoot":"","sources":["../../../../components/embeds/embed-component.tsx"],"names":[],"mappings":"AASA,OAAO,KAAe,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAKhF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,kBAAkB,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC;CAC3D,CAAC;AAEF,eAAO,MAAM,cAAc,wHAUtB,mBAAmB,uBA+NvB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DotsVerticalIcon } from "@rowsncolumns/icons";
|
|
2
2
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuTrigger, IconButton, } from "@rowsncolumns/ui";
|
|
3
3
|
import React, { memo } from "react";
|
|
4
|
-
import { getStringifiedColor } from "../../themes";
|
|
4
|
+
import { getStringifiedColor, resolveThemeFontFamily } from "../../themes";
|
|
5
5
|
import { resolveCanvasTextAlign } from "../cell/alignment";
|
|
6
6
|
import { ShapeSvg } from "./shape-svg";
|
|
7
7
|
export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected, onDeleteEmbed, onRequestEditEmbed, theme, }) => {
|
|
@@ -13,7 +13,7 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
|
|
|
13
13
|
? getStringifiedColor(spec.textFormat.color, theme)
|
|
14
14
|
: undefined;
|
|
15
15
|
const textStyle = {
|
|
16
|
-
fontFamily: spec.textFormat?.fontFamily || undefined,
|
|
16
|
+
fontFamily: resolveThemeFontFamily(spec.textFormat?.fontFamily, theme) || undefined,
|
|
17
17
|
fontSize: spec.textFormat?.fontSize
|
|
18
18
|
? `${spec.textFormat.fontSize * (spec.textFormat?.baselineOffset ? 0.58 : 1)}px`
|
|
19
19
|
: spec.textFormat?.baselineOffset
|
|
@@ -72,7 +72,8 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
|
|
|
72
72
|
return (React.createElement("div", { style: containerStyle },
|
|
73
73
|
React.createElement("div", { style: textStyle }, spec.richText.map((run, index) => {
|
|
74
74
|
const runStyle = {
|
|
75
|
-
fontFamily: run.format?.fontFamily ||
|
|
75
|
+
fontFamily: resolveThemeFontFamily(run.format?.fontFamily, theme) ||
|
|
76
|
+
undefined,
|
|
76
77
|
fontSize: run.format?.fontSize
|
|
77
78
|
? `${run.format.fontSize * (run.format?.baselineOffset ? 0.58 : 1)}px`
|
|
78
79
|
: run.format?.baselineOffset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/hidden-markers/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/hidden-markers/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,UAAU,GAAG;IAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,EAAE,MAAM,EAAE,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG;IAClD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,yDAIjC,wBAAwB,sBA0B1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,sDAI9B,qBAAqB,sBA8BvB,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useGridContext } from "@rowsncolumns/grid";
|
|
2
|
-
import { TriangleDownIcon, TriangleLeftIcon, TriangleRightIcon, TriangleUpIcon, } from "@rowsncolumns/icons";
|
|
3
2
|
import React from "react";
|
|
4
|
-
import { StyledHiddenMarkerButton } from "./style";
|
|
3
|
+
import { HiddenDoubleLine, StyledHiddenMarkerButton } from "./style";
|
|
5
4
|
export const HiddenColumnMarkers = ({ hiddenDimensions, expandedDimensions, onShowColumn, }) => {
|
|
6
5
|
const { getCellOffsetFromCoords } = useGridContext();
|
|
7
6
|
const markers = hiddenDimensions.map((columnIndex, index) => {
|
|
@@ -9,12 +8,13 @@ export const HiddenColumnMarkers = ({ hiddenDimensions, expandedDimensions, onSh
|
|
|
9
8
|
rowIndex: 0,
|
|
10
9
|
columnIndex,
|
|
11
10
|
});
|
|
12
|
-
const { x = 0, y = 0 } = position ?? {};
|
|
11
|
+
const { x = 0, y = 0, height = 0 } = position ?? {};
|
|
12
|
+
// Excel marks hidden columns with a double line on the header boundary.
|
|
13
13
|
return (React.createElement(StyledHiddenMarkerButton, { style: {
|
|
14
14
|
transform: `translate3d(${x}px, ${y}px, 0)`,
|
|
15
|
+
height,
|
|
15
16
|
}, key: columnIndex, onClick: () => onShowColumn?.(expandedDimensions[index]), "aria-label": "Show column", tooltip: "Show column" },
|
|
16
|
-
React.createElement(
|
|
17
|
-
React.createElement(TriangleRightIcon, null)));
|
|
17
|
+
React.createElement(HiddenDoubleLine, null)));
|
|
18
18
|
});
|
|
19
19
|
return React.createElement(React.Fragment, null, markers);
|
|
20
20
|
};
|
|
@@ -25,15 +25,16 @@ export const HiddenRowMarkers = ({ hiddenDimensions, expandedDimensions, onShowR
|
|
|
25
25
|
rowIndex,
|
|
26
26
|
columnIndex: 0,
|
|
27
27
|
});
|
|
28
|
-
const { x = 0, y = 0 } = position ?? {};
|
|
28
|
+
const { x = 0, y = 0, width = 0 } = position ?? {};
|
|
29
|
+
// Excel marks hidden rows with a double line on the header boundary.
|
|
29
30
|
return (React.createElement(StyledHiddenMarkerButton, { style: {
|
|
30
31
|
position: "absolute",
|
|
31
32
|
left: x,
|
|
32
33
|
top: y,
|
|
34
|
+
width,
|
|
33
35
|
pointerEvents: "all",
|
|
34
36
|
}, key: rowIndex, onClick: () => onShowRow?.(expandedDimensions[index]), isVertical: true, "aria-label": "Show row", tooltip: "Show row" },
|
|
35
|
-
React.createElement(
|
|
36
|
-
React.createElement(TriangleDownIcon, null)));
|
|
37
|
+
React.createElement(HiddenDoubleLine, { isVertical: true })));
|
|
37
38
|
});
|
|
38
39
|
return React.createElement(React.Fragment, null, markers);
|
|
39
40
|
};
|
|
@@ -2,4 +2,11 @@ import React from "react";
|
|
|
2
2
|
export declare const StyledHiddenMarkerButton: React.ForwardRefExoticComponent<Omit<import("@rowsncolumns/ui").IconButtonProps & React.RefAttributes<HTMLButtonElement>, "ref"> & {
|
|
3
3
|
isVertical?: boolean;
|
|
4
4
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
/**
|
|
6
|
+
* Two 1 px lines with a 1 px gap — Excel's marker for hidden rows / columns
|
|
7
|
+
* in the headers.
|
|
8
|
+
*/
|
|
9
|
+
export declare const HiddenDoubleLine: ({ isVertical }: {
|
|
10
|
+
isVertical?: boolean;
|
|
11
|
+
}) => React.JSX.Element;
|
|
5
12
|
//# sourceMappingURL=style.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../components/hidden-markers/style.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,wBAAwB;iBAEgC,OAAO;2CAY1E,CAAC"}
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../components/hidden-markers/style.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,wBAAwB;iBAEgC,OAAO;2CAY1E,CAAC;AAIH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,gBAAgB;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,sBAWxE,CAAC"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { cn, IconButton } from "@rowsncolumns/ui";
|
|
2
2
|
import React from "react";
|
|
3
|
-
export const StyledHiddenMarkerButton = React.forwardRef(({ className, isVertical, ...props }, ref) => (React.createElement(IconButton, { ref: ref, className: cn("flex absolute border-none p-0 rounded-
|
|
3
|
+
export const StyledHiddenMarkerButton = React.forwardRef(({ className, isVertical, ...props }, ref) => (React.createElement(IconButton, { ref: ref, className: cn("flex absolute border-none p-0 rounded-none left-0 top-0 pointer-events-auto w-[5px] -ml-[2px] justify-center items-stretch", "bg-transparent hover:bg-transparent print:hidden min-h-0 min-w-0", isVertical ? "h-[5px] -mt-[2px] ml-0 flex-col" : undefined, className), ...props })));
|
|
4
4
|
StyledHiddenMarkerButton.displayName = "StyledHiddenMarkerButton";
|
|
5
|
+
/**
|
|
6
|
+
* Two 1 px lines with a 1 px gap — Excel's marker for hidden rows / columns
|
|
7
|
+
* in the headers.
|
|
8
|
+
*/
|
|
9
|
+
export const HiddenDoubleLine = ({ isVertical }) => (React.createElement("span", { "aria-hidden": true, "data-hidden-double-line": "", className: cn("block border-rnc-foreground/60", isVertical
|
|
10
|
+
? "w-full h-[3px] border-y border-solid"
|
|
11
|
+
: "h-full w-[3px] border-x border-solid") }));
|