@rowsncolumns/spreadsheet 10.6.0 → 10.6.4

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.
Files changed (182) hide show
  1. package/dist/cjs/api/cf-data-bar.d.ts +73 -0
  2. package/dist/cjs/api/cf-data-bar.d.ts.map +1 -0
  3. package/dist/cjs/api/cf-data-bar.js +182 -0
  4. package/dist/cjs/api/cf-icons.d.ts +73 -0
  5. package/dist/cjs/api/cf-icons.d.ts.map +1 -0
  6. package/dist/cjs/api/cf-icons.js +322 -0
  7. package/dist/cjs/api/cf-overlays.d.ts +89 -3
  8. package/dist/cjs/api/cf-overlays.d.ts.map +1 -1
  9. package/dist/cjs/api/cf-overlays.js +256 -80
  10. package/dist/cjs/api/cf-priority.d.ts +34 -0
  11. package/dist/cjs/api/cf-priority.d.ts.map +1 -0
  12. package/dist/cjs/api/cf-priority.js +94 -0
  13. package/dist/cjs/api/heatmap.d.ts +7 -1
  14. package/dist/cjs/api/heatmap.d.ts.map +1 -1
  15. package/dist/cjs/api/heatmap.js +27 -11
  16. package/dist/cjs/api/selections.d.ts +2 -2
  17. package/dist/cjs/api/validation.d.ts +6 -0
  18. package/dist/cjs/api/validation.d.ts.map +1 -1
  19. package/dist/cjs/api/validation.js +10 -1
  20. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  21. package/dist/cjs/components/canvas-grid/index.js +194 -51
  22. package/dist/cjs/components/canvas-grid/overflow.d.ts +37 -0
  23. package/dist/cjs/components/canvas-grid/overflow.d.ts.map +1 -0
  24. package/dist/cjs/components/canvas-grid/overflow.js +49 -0
  25. package/dist/cjs/components/canvas-grid/page-breaks.d.ts +15 -0
  26. package/dist/cjs/components/canvas-grid/page-breaks.d.ts.map +1 -0
  27. package/dist/cjs/components/canvas-grid/page-breaks.js +77 -0
  28. package/dist/cjs/components/canvas-grid/typings.d.ts +25 -0
  29. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  30. package/dist/cjs/components/cell/alignment.d.ts +58 -1
  31. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  32. package/dist/cjs/components/cell/alignment.js +144 -1
  33. package/dist/cjs/components/cell/cell-background.d.ts +2 -0
  34. package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
  35. package/dist/cjs/components/cell/cell-background.js +5 -6
  36. package/dist/cjs/components/cell/cell-backgrounds.d.ts.map +1 -1
  37. package/dist/cjs/components/cell/cell-backgrounds.js +5 -1
  38. package/dist/cjs/components/cell/cell-text-runs.js +1 -1
  39. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  40. package/dist/cjs/components/cell/index.js +378 -37
  41. package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
  42. package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
  43. package/dist/cjs/components/cell/number-format-layout.js +106 -0
  44. package/dist/cjs/components/cell/typings.d.ts +22 -0
  45. package/dist/cjs/components/cell/typings.d.ts.map +1 -1
  46. package/dist/cjs/components/cell-editor/index.js +2 -2
  47. package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
  48. package/dist/cjs/components/cell-filter/index.js +3 -3
  49. package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
  50. package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
  51. package/dist/cjs/components/cell-overlay/index.js +155 -28
  52. package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
  53. package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
  54. package/dist/cjs/components/cf-icon-preview/index.js +48 -0
  55. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  56. package/dist/cjs/components/embeds/embed-component.js +3 -2
  57. package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
  58. package/dist/cjs/components/hidden-markers/index.js +8 -7
  59. package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
  60. package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
  61. package/dist/cjs/components/hidden-markers/style.js +13 -2
  62. package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
  63. package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
  64. package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
  65. package/dist/cjs/components/toolbar/types.d.ts +1 -1
  66. package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
  67. package/dist/cjs/config.d.ts +13 -1
  68. package/dist/cjs/config.d.ts.map +1 -1
  69. package/dist/cjs/config.js +15 -3
  70. package/dist/cjs/helpers.d.ts +10 -5
  71. package/dist/cjs/helpers.d.ts.map +1 -1
  72. package/dist/cjs/helpers.js +43 -31
  73. package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
  74. package/dist/cjs/hooks/use-border-styles.js +5 -28
  75. package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
  76. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  77. package/dist/cjs/hooks/use-cell-renderer.js +85 -47
  78. package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
  79. package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
  80. package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
  81. package/dist/cjs/index.d.ts +5 -0
  82. package/dist/cjs/index.d.ts.map +1 -1
  83. package/dist/cjs/index.js +5 -0
  84. package/dist/cjs/release-date.js +1 -1
  85. package/dist/cjs/themes.d.ts +8 -0
  86. package/dist/cjs/themes.d.ts.map +1 -1
  87. package/dist/cjs/themes.js +21 -3
  88. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  89. package/dist/cjs/types.d.ts +81 -4
  90. package/dist/cjs/types.d.ts.map +1 -1
  91. package/dist/esm/api/cf-data-bar.d.ts +73 -0
  92. package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
  93. package/dist/esm/api/cf-data-bar.js +178 -0
  94. package/dist/esm/api/cf-icons.d.ts +73 -0
  95. package/dist/esm/api/cf-icons.d.ts.map +1 -0
  96. package/dist/esm/api/cf-icons.js +306 -0
  97. package/dist/esm/api/cf-overlays.d.ts +89 -3
  98. package/dist/esm/api/cf-overlays.d.ts.map +1 -1
  99. package/dist/esm/api/cf-overlays.js +223 -67
  100. package/dist/esm/api/cf-priority.d.ts +34 -0
  101. package/dist/esm/api/cf-priority.d.ts.map +1 -0
  102. package/dist/esm/api/cf-priority.js +61 -0
  103. package/dist/esm/api/heatmap.d.ts +7 -1
  104. package/dist/esm/api/heatmap.d.ts.map +1 -1
  105. package/dist/esm/api/heatmap.js +24 -9
  106. package/dist/esm/api/selections.d.ts +2 -2
  107. package/dist/esm/api/validation.d.ts +6 -0
  108. package/dist/esm/api/validation.d.ts.map +1 -1
  109. package/dist/esm/api/validation.js +6 -0
  110. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  111. package/dist/esm/components/canvas-grid/index.js +163 -47
  112. package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
  113. package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
  114. package/dist/esm/components/canvas-grid/overflow.js +39 -0
  115. package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
  116. package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
  117. package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
  118. package/dist/esm/components/canvas-grid/typings.d.ts +25 -0
  119. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  120. package/dist/esm/components/cell/alignment.d.ts +58 -1
  121. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  122. package/dist/esm/components/cell/alignment.js +110 -1
  123. package/dist/esm/components/cell/cell-background.d.ts +2 -0
  124. package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
  125. package/dist/esm/components/cell/cell-background.js +4 -5
  126. package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
  127. package/dist/esm/components/cell/cell-backgrounds.js +5 -1
  128. package/dist/esm/components/cell/cell-text-runs.js +2 -2
  129. package/dist/esm/components/cell/index.d.ts.map +1 -1
  130. package/dist/esm/components/cell/index.js +339 -39
  131. package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
  132. package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
  133. package/dist/esm/components/cell/number-format-layout.js +99 -0
  134. package/dist/esm/components/cell/typings.d.ts +22 -0
  135. package/dist/esm/components/cell/typings.d.ts.map +1 -1
  136. package/dist/esm/components/cell-editor/index.js +2 -2
  137. package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
  138. package/dist/esm/components/cell-filter/index.js +4 -4
  139. package/dist/esm/components/cell-overlay/index.d.ts +20 -0
  140. package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
  141. package/dist/esm/components/cell-overlay/index.js +111 -25
  142. package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
  143. package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
  144. package/dist/esm/components/cf-icon-preview/index.js +41 -0
  145. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  146. package/dist/esm/components/embeds/embed-component.js +4 -3
  147. package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
  148. package/dist/esm/components/hidden-markers/index.js +9 -8
  149. package/dist/esm/components/hidden-markers/style.d.ts +7 -0
  150. package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
  151. package/dist/esm/components/hidden-markers/style.js +8 -1
  152. package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
  153. package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
  154. package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
  155. package/dist/esm/components/toolbar/types.d.ts +1 -1
  156. package/dist/esm/components/toolbar/types.d.ts.map +1 -1
  157. package/dist/esm/config.d.ts +13 -1
  158. package/dist/esm/config.d.ts.map +1 -1
  159. package/dist/esm/config.js +13 -1
  160. package/dist/esm/helpers.d.ts +10 -5
  161. package/dist/esm/helpers.d.ts.map +1 -1
  162. package/dist/esm/helpers.js +40 -28
  163. package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
  164. package/dist/esm/hooks/use-border-styles.js +5 -26
  165. package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
  166. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  167. package/dist/esm/hooks/use-cell-renderer.js +83 -42
  168. package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
  169. package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
  170. package/dist/esm/hooks/use-conditional-formatting.js +215 -120
  171. package/dist/esm/index.d.ts +5 -0
  172. package/dist/esm/index.d.ts.map +1 -1
  173. package/dist/esm/index.js +5 -0
  174. package/dist/esm/release-date.js +1 -1
  175. package/dist/esm/themes.d.ts +8 -0
  176. package/dist/esm/themes.d.ts.map +1 -1
  177. package/dist/esm/themes.js +20 -3
  178. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  179. package/dist/esm/types.d.ts +81 -4
  180. package/dist/esm/types.d.ts.map +1 -1
  181. package/dist/spreadsheet.min.css +1 -1
  182. 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":"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"}
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;AAYrD,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,CAmGhD,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 = "green", backgroundColor, verticalAlignment, sortOrder, }) => {
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 ?? "green")
42
- : backgroundColor ?? undefined, cornerRadius: 0, perfectDrawEnabled: false, stroke: filterIconColor ?? undefined, strokeWidth: 1, hitStrokeWidth: 0 }),
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;AA6MF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,6BA+ElE,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
- /* Diagonal: top-left to bottom-right (diagonalDown) */
116
- if (strokeDiagonalDownColor) {
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
- context.moveTo(0, 0);
119
- context.lineTo(shape.width(), shape.height());
120
- context.setAttr("strokeStyle", strokeDiagonalDownColor);
121
- context.setAttr("lineWidth", strokeDiagonalDownWidth);
122
- context.setAttr("lineCap", lineCap);
123
- context.setLineDash(strokeDiagonalDownDash);
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(strokeDiagonalUpDash);
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,uBA4NvB,CAAC"}
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 || undefined,
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":"AAOA,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,sBAyB1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,sDAI9B,qBAAqB,sBA6BvB,CAAC"}
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(TriangleLeftIcon, null),
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(TriangleUpIcon, null),
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-sm bg-none left-0 top-0 pointer-events-auto w-[30px] h-[15px] mt-[5px] -ml-[15px]", "bg-transparent text-rnc-foreground hover:bg-rnc-background hover:shadow-md print:hidden min-h-0 min-w-0", isVertical ? "w-[15px] h-[30px] ml-px -mt-[15px] flex-col" : undefined, className), ...props })));
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") }));