@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.
Files changed (186) 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 +83 -1
  31. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  32. package/dist/cjs/components/cell/alignment.js +182 -1
  33. package/dist/cjs/components/cell/cell-background.d.ts +18 -0
  34. package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
  35. package/dist/cjs/components/cell/cell-background.js +145 -59
  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.d.ts +12 -5
  39. package/dist/cjs/components/cell/cell-text-runs.d.ts.map +1 -1
  40. package/dist/cjs/components/cell/cell-text-runs.js +19 -21
  41. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  42. package/dist/cjs/components/cell/index.js +392 -45
  43. package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
  44. package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
  45. package/dist/cjs/components/cell/number-format-layout.js +106 -0
  46. package/dist/cjs/components/cell/typings.d.ts +22 -0
  47. package/dist/cjs/components/cell/typings.d.ts.map +1 -1
  48. package/dist/cjs/components/cell-editor/index.js +2 -2
  49. package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
  50. package/dist/cjs/components/cell-filter/index.js +3 -3
  51. package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
  52. package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
  53. package/dist/cjs/components/cell-overlay/index.js +155 -28
  54. package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
  55. package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
  56. package/dist/cjs/components/cf-icon-preview/index.js +48 -0
  57. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  58. package/dist/cjs/components/embeds/embed-component.js +3 -2
  59. package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
  60. package/dist/cjs/components/hidden-markers/index.js +8 -7
  61. package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
  62. package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
  63. package/dist/cjs/components/hidden-markers/style.js +13 -2
  64. package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
  65. package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
  66. package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
  67. package/dist/cjs/components/toolbar/types.d.ts +1 -1
  68. package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
  69. package/dist/cjs/config.d.ts +13 -1
  70. package/dist/cjs/config.d.ts.map +1 -1
  71. package/dist/cjs/config.js +15 -3
  72. package/dist/cjs/helpers.d.ts +15 -5
  73. package/dist/cjs/helpers.d.ts.map +1 -1
  74. package/dist/cjs/helpers.js +51 -35
  75. package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
  76. package/dist/cjs/hooks/use-border-styles.js +5 -28
  77. package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
  78. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  79. package/dist/cjs/hooks/use-cell-renderer.js +85 -47
  80. package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
  81. package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
  82. package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
  83. package/dist/cjs/index.d.ts +5 -0
  84. package/dist/cjs/index.d.ts.map +1 -1
  85. package/dist/cjs/index.js +5 -0
  86. package/dist/cjs/release-date.js +1 -1
  87. package/dist/cjs/themes.d.ts +8 -0
  88. package/dist/cjs/themes.d.ts.map +1 -1
  89. package/dist/cjs/themes.js +21 -3
  90. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  91. package/dist/cjs/types.d.ts +81 -4
  92. package/dist/cjs/types.d.ts.map +1 -1
  93. package/dist/esm/api/cf-data-bar.d.ts +73 -0
  94. package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
  95. package/dist/esm/api/cf-data-bar.js +178 -0
  96. package/dist/esm/api/cf-icons.d.ts +73 -0
  97. package/dist/esm/api/cf-icons.d.ts.map +1 -0
  98. package/dist/esm/api/cf-icons.js +306 -0
  99. package/dist/esm/api/cf-overlays.d.ts +89 -3
  100. package/dist/esm/api/cf-overlays.d.ts.map +1 -1
  101. package/dist/esm/api/cf-overlays.js +223 -67
  102. package/dist/esm/api/cf-priority.d.ts +34 -0
  103. package/dist/esm/api/cf-priority.d.ts.map +1 -0
  104. package/dist/esm/api/cf-priority.js +61 -0
  105. package/dist/esm/api/heatmap.d.ts +7 -1
  106. package/dist/esm/api/heatmap.d.ts.map +1 -1
  107. package/dist/esm/api/heatmap.js +24 -9
  108. package/dist/esm/api/selections.d.ts +2 -2
  109. package/dist/esm/api/validation.d.ts +6 -0
  110. package/dist/esm/api/validation.d.ts.map +1 -1
  111. package/dist/esm/api/validation.js +6 -0
  112. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  113. package/dist/esm/components/canvas-grid/index.js +163 -47
  114. package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
  115. package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
  116. package/dist/esm/components/canvas-grid/overflow.js +39 -0
  117. package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
  118. package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
  119. package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
  120. package/dist/esm/components/canvas-grid/typings.d.ts +25 -0
  121. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  122. package/dist/esm/components/cell/alignment.d.ts +83 -1
  123. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  124. package/dist/esm/components/cell/alignment.js +143 -1
  125. package/dist/esm/components/cell/cell-background.d.ts +18 -0
  126. package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
  127. package/dist/esm/components/cell/cell-background.js +110 -41
  128. package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
  129. package/dist/esm/components/cell/cell-backgrounds.js +5 -1
  130. package/dist/esm/components/cell/cell-text-runs.d.ts +12 -5
  131. package/dist/esm/components/cell/cell-text-runs.d.ts.map +1 -1
  132. package/dist/esm/components/cell/cell-text-runs.js +19 -24
  133. package/dist/esm/components/cell/index.d.ts.map +1 -1
  134. package/dist/esm/components/cell/index.js +352 -46
  135. package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
  136. package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
  137. package/dist/esm/components/cell/number-format-layout.js +99 -0
  138. package/dist/esm/components/cell/typings.d.ts +22 -0
  139. package/dist/esm/components/cell/typings.d.ts.map +1 -1
  140. package/dist/esm/components/cell-editor/index.js +2 -2
  141. package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
  142. package/dist/esm/components/cell-filter/index.js +4 -4
  143. package/dist/esm/components/cell-overlay/index.d.ts +20 -0
  144. package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
  145. package/dist/esm/components/cell-overlay/index.js +111 -25
  146. package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
  147. package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
  148. package/dist/esm/components/cf-icon-preview/index.js +41 -0
  149. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  150. package/dist/esm/components/embeds/embed-component.js +4 -3
  151. package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
  152. package/dist/esm/components/hidden-markers/index.js +9 -8
  153. package/dist/esm/components/hidden-markers/style.d.ts +7 -0
  154. package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
  155. package/dist/esm/components/hidden-markers/style.js +8 -1
  156. package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
  157. package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
  158. package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
  159. package/dist/esm/components/toolbar/types.d.ts +1 -1
  160. package/dist/esm/components/toolbar/types.d.ts.map +1 -1
  161. package/dist/esm/config.d.ts +13 -1
  162. package/dist/esm/config.d.ts.map +1 -1
  163. package/dist/esm/config.js +13 -1
  164. package/dist/esm/helpers.d.ts +15 -5
  165. package/dist/esm/helpers.d.ts.map +1 -1
  166. package/dist/esm/helpers.js +48 -32
  167. package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
  168. package/dist/esm/hooks/use-border-styles.js +5 -26
  169. package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
  170. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  171. package/dist/esm/hooks/use-cell-renderer.js +83 -42
  172. package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
  173. package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
  174. package/dist/esm/hooks/use-conditional-formatting.js +215 -120
  175. package/dist/esm/index.d.ts +5 -0
  176. package/dist/esm/index.d.ts.map +1 -1
  177. package/dist/esm/index.js +5 -0
  178. package/dist/esm/release-date.js +1 -1
  179. package/dist/esm/themes.d.ts +8 -0
  180. package/dist/esm/themes.d.ts.map +1 -1
  181. package/dist/esm/themes.js +20 -3
  182. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  183. package/dist/esm/types.d.ts +81 -4
  184. package/dist/esm/types.d.ts.map +1 -1
  185. package/dist/spreadsheet.min.css +1 -1
  186. package/package.json +4 -4
@@ -2,30 +2,102 @@ import { isSameColor, lightenColor, normalizeColor } from "@rowsncolumns/utils";
2
2
  import React from "react";
3
3
  import { Shape } from "react-konva";
4
4
  import { getPatternCanvas } from "../../api/fill-patterns";
5
- // Build a CanvasGradient matching the OOXML <gradientFill> spec.
6
- // linear: `degree` rotates the axis (0 = left→right, 90 = top→bottom,
7
- // 180 = right→left, 270 = bottom→top). Excel's axis runs through the
8
- // cell's centroid at the given angle and the gradient spans the full
9
- // cell along it.
10
- // path: rectangular radial — `left`/`right`/`top`/`bottom` (each 0..1)
11
- // describe the inset of the inner stop's "core" rectangle. We
12
- // approximate as a single radial gradient anchored at that core's
13
- // center, with radius = distance to the farthest corner.
5
+ /** Excel's Automatic pattern colour: a pattern with no colour of its own. */
6
+ export const AUTOMATIC_PATTERN_COLOR = "#000000";
7
+ /**
8
+ * Excel's path gradient over the rectangle `[x0, y0]–[x1, y1]`: the core
9
+ * rectangle (inner stop colour) and four trapezoids cut along the
10
+ * core-to-corner diagonals, each a linear gradient from the core edge out
11
+ * to its cell edge — together, concentric rectangles of colour.
12
+ */
13
+ export const getPathGradientRegions = (gradient, x0, y0, x1, y1) => {
14
+ const width = x1 - x0;
15
+ const height = y1 - y0;
16
+ const cl = x0 + (gradient.left ?? 0) * width;
17
+ const cr = x1 - (gradient.right ?? 0) * width;
18
+ const ct = y0 + (gradient.top ?? 0) * height;
19
+ const cb = y1 - (gradient.bottom ?? 0) * height;
20
+ const coreLeft = Math.min(cl, cr);
21
+ const coreRight = Math.max(cl, cr);
22
+ const coreTop = Math.min(ct, cb);
23
+ const coreBottom = Math.max(ct, cb);
24
+ return {
25
+ core: [coreLeft, coreTop, coreRight, coreBottom],
26
+ regions: [
27
+ {
28
+ points: [
29
+ [x0, y0],
30
+ [x1, y0],
31
+ [coreRight, coreTop],
32
+ [coreLeft, coreTop],
33
+ ],
34
+ axis: [coreLeft, coreTop, coreLeft, y0],
35
+ },
36
+ {
37
+ points: [
38
+ [x1, y0],
39
+ [x1, y1],
40
+ [coreRight, coreBottom],
41
+ [coreRight, coreTop],
42
+ ],
43
+ axis: [coreRight, coreTop, x1, coreTop],
44
+ },
45
+ {
46
+ points: [
47
+ [x1, y1],
48
+ [x0, y1],
49
+ [coreLeft, coreBottom],
50
+ [coreRight, coreBottom],
51
+ ],
52
+ axis: [coreLeft, coreBottom, coreLeft, y1],
53
+ },
54
+ {
55
+ points: [
56
+ [x0, y1],
57
+ [x0, y0],
58
+ [coreLeft, coreTop],
59
+ [coreLeft, coreBottom],
60
+ ],
61
+ axis: [coreLeft, coreTop, x0, coreTop],
62
+ },
63
+ ],
64
+ };
65
+ };
66
+ const addStops = (canvasGrad, gradient) => {
67
+ for (const stop of gradient.stops) {
68
+ // Clamp position to [0,1] — Canvas API rejects out-of-range values.
69
+ const pos = Math.max(0, Math.min(1, stop.position));
70
+ try {
71
+ canvasGrad.addColorStop(pos, stop.color);
72
+ }
73
+ catch {
74
+ // Invalid color string — skip rather than blow up the render.
75
+ }
76
+ }
77
+ };
78
+ const paintPathGradient = (context, native, gradient, rect) => {
79
+ const { core, regions } = getPathGradientRegions(gradient, ...rect);
80
+ const sorted = [...gradient.stops].sort((a, b) => a.position - b.position);
81
+ context.setAttr("fillStyle", sorted[0].color);
82
+ context.fillRect(core[0], core[1], core[2] - core[0], core[3] - core[1]);
83
+ for (const region of regions) {
84
+ const [ax0, ay0, ax1, ay1] = region.axis;
85
+ if (ax0 === ax1 && ay0 === ay1)
86
+ continue;
87
+ const canvasGrad = native.createLinearGradient(ax0, ay0, ax1, ay1);
88
+ addStops(canvasGrad, gradient);
89
+ context.beginPath();
90
+ region.points.forEach(([px, py], index) => index ? context.lineTo(px, py) : context.moveTo(px, py));
91
+ context.closePath();
92
+ context.setAttr("fillStyle", canvasGrad);
93
+ context.fill();
94
+ }
95
+ };
14
96
  const buildCanvasGradient = (native, gradient, width, height) => {
15
97
  if (!gradient.stops?.length)
16
98
  return null;
17
99
  let canvasGrad;
18
- if (gradient.type === "path") {
19
- const left = gradient.left ?? 0;
20
- const right = gradient.right ?? 0;
21
- const top = gradient.top ?? 0;
22
- const bottom = gradient.bottom ?? 0;
23
- const cx = ((left + (1 - right)) / 2) * width;
24
- const cy = ((top + (1 - bottom)) / 2) * height;
25
- const farthestCorner = Math.max(Math.hypot(cx, cy), Math.hypot(width - cx, cy), Math.hypot(cx, height - cy), Math.hypot(width - cx, height - cy));
26
- canvasGrad = native.createRadialGradient(cx, cy, 0, cx, cy, farthestCorner || 1);
27
- }
28
- else {
100
+ {
29
101
  // Linear. Map degrees → axis vector. Excel: degree=0 runs the
30
102
  // gradient from LEFT to RIGHT. degree increases clockwise.
31
103
  const deg = (((gradient.degree ?? 0) % 360) + 360) % 360;
@@ -58,16 +130,7 @@ const buildCanvasGradient = (native, gradient, width, height) => {
58
130
  const y1 = cy + dy * maxProj;
59
131
  canvasGrad = native.createLinearGradient(x0, y0, x1, y1);
60
132
  }
61
- for (const stop of gradient.stops) {
62
- // Clamp position to [0,1] — Canvas API rejects out-of-range values.
63
- const pos = Math.max(0, Math.min(1, stop.position));
64
- try {
65
- canvasGrad.addColorStop(pos, stop.color);
66
- }
67
- catch {
68
- // Invalid color string — skip rather than blow up the render.
69
- }
70
- }
133
+ addStops(canvasGrad, gradient);
71
134
  return canvasGrad;
72
135
  };
73
136
  export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBackgroundColor, scale, showGridLines, isMergedCell, fillPattern, foregroundColor, gradient, }) => {
@@ -91,13 +154,17 @@ export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBa
91
154
  // bgColor is ignored when pattern=solid). For "none" or absent, fall
92
155
  // back to the regular backgroundColor path.
93
156
  const useSolid = fillPattern === "solid" && foregroundColor;
94
- const useTile = fillPattern &&
95
- fillPattern !== "solid" &&
96
- fillPattern !== "none" &&
97
- foregroundColor;
157
+ const useTile = fillPattern && fillPattern !== "solid" && fillPattern !== "none";
98
158
  const useGradient = !!gradient && (gradient.stops?.length ?? 0) > 0;
99
159
  const native = context._context;
100
- if (useGradient && native) {
160
+ const fillRectArea = (isMergedCell || !showFaintBorder) && showGridLines
161
+ ? [1, 1, shape.width(), shape.height()]
162
+ : [0, 0, shape.width() + 1, shape.height() + 1];
163
+ const usePathGradient = useGradient && native && gradient.type === "path";
164
+ if (usePathGradient) {
165
+ paintPathGradient(context, native, gradient, fillRectArea);
166
+ }
167
+ else if (useGradient && native) {
101
168
  const canvasGrad = buildCanvasGradient(native, gradient, shape.width(), shape.height());
102
169
  if (canvasGrad) {
103
170
  context.setAttr("fillStyle", canvasGrad);
@@ -110,7 +177,7 @@ export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBa
110
177
  context.setAttr("fillStyle", foregroundColor);
111
178
  }
112
179
  else if (useTile) {
113
- const tile = getPatternCanvas(fillPattern, foregroundColor, backgroundColor);
180
+ const tile = getPatternCanvas(fillPattern, foregroundColor ?? AUTOMATIC_PATTERN_COLOR, backgroundColor);
114
181
  const ctxPattern = tile && native?.createPattern(tile, "repeat");
115
182
  if (ctxPattern) {
116
183
  context.setAttr("fillStyle", ctxPattern);
@@ -122,11 +189,13 @@ export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBa
122
189
  else {
123
190
  context.setAttr("fillStyle", finalBackgroundColor);
124
191
  }
125
- if ((isMergedCell || !showFaintBorder) && showGridLines) {
126
- context.fillRect(1, 1, shape.width() - 1, shape.height() - 1);
127
- }
128
- else {
129
- context.fillRect(0, 0, shape.width() + 1, shape.height() + 1);
192
+ if (!usePathGradient) {
193
+ if ((isMergedCell || !showFaintBorder) && showGridLines) {
194
+ context.fillRect(1, 1, shape.width() - 1, shape.height() - 1);
195
+ }
196
+ else {
197
+ context.fillRect(0, 0, shape.width() + 1, shape.height() + 1);
198
+ }
130
199
  }
131
200
  if (showFaintBorder) {
132
201
  const lightColor = lightenColor(-0.1, backgroundColor);
@@ -1 +1 @@
1
- {"version":3,"file":"cell-backgrounds.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-backgrounds.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,KAAkB,MAAM,OAAO,CAAC;AAkBvC,MAAM,WAAW,oBAAoB;IACnC,mGAAmG;IACnG,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,uFAAuF;IACvF,SAAS,EAAE,CACT,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,8FAA8F;IAC9F,YAAY,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IAC3E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,mFAO7B,oBAAoB,sBAiHtB,CAAC"}
1
+ {"version":3,"file":"cell-backgrounds.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-backgrounds.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,KAAkB,MAAM,OAAO,CAAC;AAkBvC,MAAM,WAAW,oBAAoB;IACnC,mGAAmG;IACnG,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,uFAAuF;IACvF,SAAS,EAAE,CACT,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,8FAA8F;IAC9F,YAAY,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IAC3E,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,mFAO7B,oBAAoB,sBAqHtB,CAAC"}
@@ -26,7 +26,11 @@ export const CellBackgrounds = ({ cells, getFormat, resolveColor, defaultBackgro
26
26
  const fillPattern = format?.fillPattern ?? null;
27
27
  const gradient = format?.gradient ?? null;
28
28
  const foregroundColor = resolveColor(format?.foregroundColor);
29
- const hasPaintedPattern = fillPattern && fillPattern !== "none" ? !!foregroundColor : false;
29
+ // A pattern with no colour of its own paints in Excel's Automatic
30
+ // (black); a solid pattern needs its foreground.
31
+ const hasPaintedPattern = fillPattern === "solid"
32
+ ? !!foregroundColor
33
+ : !!fillPattern && fillPattern !== "none";
30
34
  const hasGradient = !!gradient && (gradient.stops?.length ?? 0) > 0;
31
35
  const backgroundColor = resolveColor(format?.backgroundColor);
32
36
  const isMergedCell = !!cell.isMergedCell;
@@ -46,6 +46,13 @@ export type CellTextRunsProps = {
46
46
  wrap: boolean;
47
47
  /** Theme — used to resolve segment `color` objects to CSS strings. */
48
48
  theme: SpreadsheetTheme;
49
+ /**
50
+ * Multiplier for run font sizes given in points (zoom × shrink-to-fit),
51
+ * so a run's own size follows the cell's.
52
+ */
53
+ fontScale?: number;
54
+ /** Konva rotation (degrees, clockwise) of the whole block — rotated text. */
55
+ rotation?: number;
49
56
  };
50
57
  export type Resolved = {
51
58
  bold: boolean;
@@ -64,7 +71,7 @@ export type Resolved = {
64
71
  * merged style carries a `baselineOffset` (own or inherited from the
65
72
  * base) the sup/sub font scale is applied here, exactly once.
66
73
  */
67
- export declare const resolveSegmentStyle: (seg: RichTextSegment, base: Resolved, theme: SpreadsheetTheme) => Resolved;
74
+ export declare const resolveSegmentStyle: (seg: RichTextSegment, base: Resolved, theme: SpreadsheetTheme, fontScale?: number) => Resolved;
68
75
  /** A segment paired with its fully-resolved paint style. */
69
76
  export type ResolvedSegment = {
70
77
  seg: RichTextSegment;
@@ -83,10 +90,10 @@ export declare const computeLineMetrics: (resolvedLines: ResolvedSegment[][], ba
83
90
  };
84
91
  /**
85
92
  * Vertical draw position (textBaseline="top") for one segment within
86
- * its line box. Normal runs share the line's alphabetic baseline
87
- * (smaller runs shift down), superscript hugs the line top, subscript
88
- * hugs the line bottom. All three reduce to `lineTop` when the run's
89
- * size equals the line's. Exported for unit tests.
93
+ * its line box. Every run shares the line's alphabetic baseline (smaller
94
+ * runs shift down); superscript / subscript runs then move that baseline
95
+ * up / down by Excel's shift ({@link getScriptBaselineShift}). Exported
96
+ * for unit tests.
90
97
  */
91
98
  export declare const computeSegmentTop: (lineTop: number, lineFontSize: number, segFontSize: number, baselineOffset: "superscript" | "subscript" | undefined) => number;
92
99
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cell-text-runs.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-text-runs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,8DAA8D;IAC9D,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC;IACjD,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC;CAC9C,CAAC;AAkCF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,KAAK,eAAe,EACpB,MAAM,QAAQ,EACd,OAAO,gBAAgB,KACtB,QA0BF,CAAC;AAKF,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,eAAe,CAAC;IACrB,CAAC,EAAE,QAAQ,CAAC;CACb,CAAC;AAYF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,eAAe,eAAe,EAAE,EAAE,EAClC,MAAM,QAAQ,EACd,WAAW,CAAC,CAAC,EAAE,QAAQ,KAAK,MAAM,KACjC;IAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CASvE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,aAAa,MAAM,EACnB,gBAAgB,aAAa,GAAG,WAAW,GAAG,SAAS,KACtD,MAMF,CAAC;AAoHF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,oCAAsB,iBAAiB,uBA2P9D,CAAC"}
1
+ {"version":3,"file":"cell-text-runs.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-text-runs.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback } from "react";
2
2
  import { Shape } from "react-konva";
3
- import { getStringifiedColor } from "../../themes";
3
+ import { getStringifiedColor, resolveThemeFontFamily } from "../../themes";
4
+ import { getScriptBaselineShift } from "./alignment";
4
5
  import { getLineAdvance } from "./line-height";
5
6
  import { buildRichTextSegments, segmentsToLines, segmentToAtoms, } from "./rich-text";
6
7
  const BASELINE_OFFSET_FONT_SCALE = 0.58;
@@ -39,12 +40,10 @@ const buildFontString = (r) => {
39
40
  * merged style carries a `baselineOffset` (own or inherited from the
40
41
  * base) the sup/sub font scale is applied here, exactly once.
41
42
  */
42
- export const resolveSegmentStyle = (seg, base, theme) => {
43
+ export const resolveSegmentStyle = (seg, base, theme, fontScale = 1) => {
43
44
  const f = seg.format;
44
45
  const baselineOffset = f.baselineOffset ?? base.baselineOffset;
45
- const fontSize = typeof f.fontSize === "number"
46
- ? (f.fontSize / pointFromPx(base.fontSize)) * base.fontSize
47
- : base.fontSize;
46
+ const fontSize = typeof f.fontSize === "number" ? f.fontSize * PT_TO_PX * fontScale : base.fontSize;
48
47
  return {
49
48
  bold: f.bold ?? base.bold,
50
49
  italic: f.italic ?? base.italic,
@@ -53,7 +52,7 @@ export const resolveSegmentStyle = (seg, base, theme) => {
53
52
  color: f.color != null
54
53
  ? getStringifiedColor(f.color, theme) || base.color
55
54
  : base.color,
56
- fontFamily: f.fontFamily ?? base.fontFamily,
55
+ fontFamily: resolveThemeFontFamily(f.fontFamily, theme) ?? base.fontFamily,
57
56
  // f.fontSize is in points to mirror the editor's TextFormat type,
58
57
  // but at this paint layer everything is in pixels — scale ratio is
59
58
  // applied by the caller via baseFontSize. For per-segment override
@@ -64,8 +63,8 @@ export const resolveSegmentStyle = (seg, base, theme) => {
64
63
  baselineOffset,
65
64
  };
66
65
  };
67
- /** Inverse of pointToPixel — used only when computing a per-segment scale. */
68
- const pointFromPx = (px) => px / 1.3333;
66
+ /** CSS pixels per point (96 / 72), as `pointToPixel`. */
67
+ const PT_TO_PX = 96 / 72;
69
68
  /**
70
69
  * Fraction of the em box above the alphabetic baseline for typical
71
70
  * Latin fonts. Used to baseline-align mixed-size runs on one line:
@@ -89,19 +88,14 @@ export const computeLineMetrics = (resolvedLines, base, advanceOf) => {
89
88
  };
90
89
  /**
91
90
  * Vertical draw position (textBaseline="top") for one segment within
92
- * its line box. Normal runs share the line's alphabetic baseline
93
- * (smaller runs shift down), superscript hugs the line top, subscript
94
- * hugs the line bottom. All three reduce to `lineTop` when the run's
95
- * size equals the line's. Exported for unit tests.
91
+ * its line box. Every run shares the line's alphabetic baseline (smaller
92
+ * runs shift down); superscript / subscript runs then move that baseline
93
+ * up / down by Excel's shift ({@link getScriptBaselineShift}). Exported
94
+ * for unit tests.
96
95
  */
97
- export const computeSegmentTop = (lineTop, lineFontSize, segFontSize, baselineOffset) => {
98
- if (baselineOffset === "superscript")
99
- return lineTop;
100
- if (baselineOffset === "subscript") {
101
- return lineTop + (lineFontSize - segFontSize);
102
- }
103
- return lineTop + (lineFontSize - segFontSize) * ALPHABETIC_BASELINE_RATIO;
104
- };
96
+ export const computeSegmentTop = (lineTop, lineFontSize, segFontSize, baselineOffset) => lineTop +
97
+ (lineFontSize - segFontSize) * ALPHABETIC_BASELINE_RATIO +
98
+ getScriptBaselineShift(baselineOffset, lineFontSize);
105
99
  /**
106
100
  * Sum of advance widths of a single line of resolved segments, using
107
101
  * the supplied context's `measureText`. Mutates ctx font as it walks
@@ -214,7 +208,7 @@ const atomsToSegments = (atoms) => {
214
208
  * - Mention runs render as their inline label only (no chrome).
215
209
  */
216
210
  export const CellTextRuns = React.memo((props) => {
217
- const { x, y, width, height, padding, value, runs, baseColor, baseFontFamily, baseFontSize, baseBold, baseItalic, baseUnderline, baseStrikethrough, baseBaselineOffset, horizontalAlign, verticalAlign, lineHeight, lineHeightMode, scale, wrap, theme, } = props;
211
+ const { x, y, width, height, padding, value, runs, baseColor, baseFontFamily, baseFontSize, baseBold, baseItalic, baseUnderline, baseStrikethrough, baseBaselineOffset, horizontalAlign, verticalAlign, lineHeight, lineHeightMode, scale, wrap, theme, fontScale = 1, rotation, } = props;
218
212
  const sceneFunc = useCallback((context, _shape) => {
219
213
  const baseResolved = {
220
214
  bold: baseBold,
@@ -238,7 +232,7 @@ export const CellTextRuns = React.memo((props) => {
238
232
  // it walks; the per-segment paint loop below sets it again per
239
233
  // segment so the mutation here is safe.
240
234
  const measureAtom = (atom) => {
241
- const r = resolveSegmentStyle({ text: atom.text, format: atom.format }, baseResolved, theme);
235
+ const r = resolveSegmentStyle({ text: atom.text, format: atom.format }, baseResolved, theme, fontScale);
242
236
  context.setAttr("font", buildFontString(r));
243
237
  return context.measureText(atom.text).width;
244
238
  };
@@ -280,7 +274,7 @@ export const CellTextRuns = React.memo((props) => {
280
274
  // layout: the run font's `getLineAdvance` per line.
281
275
  const resolvedLines = lines.map((lineSegments) => lineSegments.map((seg) => ({
282
276
  seg,
283
- r: resolveSegmentStyle(seg, baseResolved, theme),
277
+ r: resolveSegmentStyle(seg, baseResolved, theme, fontScale),
284
278
  })));
285
279
  const { lineFontSizes, lineHeights, totalHeight: totalH } = computeLineMetrics(resolvedLines, baseResolved, (r) => getLineAdvance(r, lineHeightMode, lineHeight, scale));
286
280
  let topY;
@@ -378,7 +372,8 @@ export const CellTextRuns = React.memo((props) => {
378
372
  height,
379
373
  padding,
380
374
  theme,
375
+ fontScale,
381
376
  ]);
382
- return (React.createElement(Shape, { x: x, y: y, width: width, height: height, sceneFunc: sceneFunc, listening: false, perfectDrawEnabled: false }));
377
+ return (React.createElement(Shape, { x: x, y: y, width: width, height: height, rotation: rotation, sceneFunc: sceneFunc, listening: false, perfectDrawEnabled: false }));
383
378
  });
384
379
  CellTextRuns.displayName = "CellTextRuns";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA4B,MAAM,OAAO,CAAC;AA4CjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C,eAAO,MAAM,IAAI,oCAAgB,SAAS,uBA0oBxC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAuDjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAO3C,eAAO,MAAM,IAAI,oCAAgB,SAAS,uBAoiCxC,CAAC"}