@rowsncolumns/spreadsheet 10.2.74 → 10.2.75

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 (194) hide show
  1. package/dist/cjs/api/excel-validation-kinds.d.ts +71 -0
  2. package/dist/cjs/api/excel-validation-kinds.d.ts.map +1 -0
  3. package/dist/cjs/api/excel-validation-kinds.js +304 -0
  4. package/dist/cjs/api/go-to-special.d.ts +32 -0
  5. package/dist/cjs/api/go-to-special.d.ts.map +1 -0
  6. package/dist/cjs/api/go-to-special.js +111 -0
  7. package/dist/cjs/api/validation-tooltip.d.ts +17 -0
  8. package/dist/cjs/api/validation-tooltip.d.ts.map +1 -0
  9. package/dist/cjs/api/validation-tooltip.js +42 -0
  10. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  11. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  12. package/dist/cjs/atoms/advanced-filter-dialog.atom.js +32 -0
  13. package/dist/cjs/atoms/go-to-dialog.atom.d.ts +11 -1
  14. package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -1
  15. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +29 -0
  16. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  17. package/dist/cjs/atoms/goal-seek-dialog.atom.js +30 -0
  18. package/dist/cjs/atoms/index.d.ts +1 -0
  19. package/dist/cjs/atoms/index.d.ts.map +1 -1
  20. package/dist/cjs/atoms/index.js +1 -0
  21. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts +39 -0
  22. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  23. package/dist/cjs/atoms/subtotal-dialog.atom.js +30 -0
  24. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  25. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  26. package/dist/cjs/atoms/text-to-columns-dialog.atom.js +36 -0
  27. package/dist/cjs/atoms/watch-window.atom.d.ts +37 -0
  28. package/dist/cjs/atoms/watch-window.atom.d.ts.map +1 -0
  29. package/dist/cjs/atoms/watch-window.atom.js +61 -0
  30. package/dist/cjs/components/advanced-filter-dialog/index.d.ts +28 -0
  31. package/dist/cjs/components/advanced-filter-dialog/index.d.ts.map +1 -0
  32. package/dist/cjs/components/advanced-filter-dialog/index.js +134 -0
  33. package/dist/cjs/components/calculation-options-dialog/index.d.ts +33 -0
  34. package/dist/cjs/components/calculation-options-dialog/index.d.ts.map +1 -0
  35. package/dist/cjs/components/calculation-options-dialog/index.js +69 -0
  36. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  37. package/dist/cjs/components/canvas-grid/index.js +104 -21
  38. package/dist/cjs/components/canvas-grid/typings.d.ts +19 -2
  39. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  40. package/dist/cjs/components/cell/alignment.d.ts +30 -0
  41. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  42. package/dist/cjs/components/cell/alignment.js +56 -1
  43. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  44. package/dist/cjs/components/cell/index.js +15 -7
  45. package/dist/cjs/components/cell-diff/index.d.ts +3 -2
  46. package/dist/cjs/components/cell-diff/index.d.ts.map +1 -1
  47. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  48. package/dist/cjs/components/cell-editor/index.js +2 -1
  49. package/dist/cjs/components/context-menu/index.d.ts +6 -1
  50. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  51. package/dist/cjs/components/context-menu/index.js +146 -3
  52. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  53. package/dist/cjs/components/embeds/embed-component.js +16 -1
  54. package/dist/cjs/components/go-to-dialog/index.d.ts +11 -1
  55. package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -1
  56. package/dist/cjs/components/go-to-dialog/index.js +67 -24
  57. package/dist/cjs/components/goal-seek-dialog/index.d.ts +32 -0
  58. package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -0
  59. package/dist/cjs/components/goal-seek-dialog/index.js +149 -0
  60. package/dist/cjs/components/subtotal-dialog/index.d.ts +30 -0
  61. package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -0
  62. package/dist/cjs/components/subtotal-dialog/index.js +126 -0
  63. package/dist/cjs/components/text-to-columns-dialog/index.d.ts +37 -0
  64. package/dist/cjs/components/text-to-columns-dialog/index.d.ts.map +1 -0
  65. package/dist/cjs/components/text-to-columns-dialog/index.js +166 -0
  66. package/dist/cjs/components/toolbar/background-color-selector.d.ts +13 -1
  67. package/dist/cjs/components/toolbar/background-color-selector.d.ts.map +1 -1
  68. package/dist/cjs/components/toolbar/background-color-selector.js +57 -11
  69. package/dist/cjs/components/toolbar/cell-style-selector.d.ts +15 -2
  70. package/dist/cjs/components/toolbar/cell-style-selector.d.ts.map +1 -1
  71. package/dist/cjs/components/toolbar/cell-style-selector.js +56 -3
  72. package/dist/cjs/components/toolbar/fill-selectors.d.ts +49 -0
  73. package/dist/cjs/components/toolbar/fill-selectors.d.ts.map +1 -0
  74. package/dist/cjs/components/toolbar/fill-selectors.js +196 -0
  75. package/dist/cjs/components/toolbar/index.d.ts +1 -0
  76. package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
  77. package/dist/cjs/components/toolbar/index.js +1 -0
  78. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  79. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  80. package/dist/cjs/components/toolbar/text-horizontal-align-selector.js +23 -4
  81. package/dist/cjs/components/watch-window/index.d.ts +25 -0
  82. package/dist/cjs/components/watch-window/index.d.ts.map +1 -0
  83. package/dist/cjs/components/watch-window/index.js +63 -0
  84. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  85. package/dist/cjs/hooks/use-cell-renderer.js +17 -6
  86. package/dist/cjs/hooks/use-get-tooltip.d.ts.map +1 -1
  87. package/dist/cjs/hooks/use-get-tooltip.js +7 -2
  88. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  89. package/dist/cjs/hooks/use-keyboard-handler.js +24 -12
  90. package/dist/cjs/index.d.ts +8 -0
  91. package/dist/cjs/index.d.ts.map +1 -1
  92. package/dist/cjs/index.js +8 -0
  93. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  94. package/dist/cjs/types.d.ts +117 -4
  95. package/dist/cjs/types.d.ts.map +1 -1
  96. package/dist/cjs/types.js +19 -1
  97. package/dist/esm/api/excel-validation-kinds.d.ts +71 -0
  98. package/dist/esm/api/excel-validation-kinds.d.ts.map +1 -0
  99. package/dist/esm/api/excel-validation-kinds.js +287 -0
  100. package/dist/esm/api/go-to-special.d.ts +32 -0
  101. package/dist/esm/api/go-to-special.d.ts.map +1 -0
  102. package/dist/esm/api/go-to-special.js +96 -0
  103. package/dist/esm/api/validation-tooltip.d.ts +17 -0
  104. package/dist/esm/api/validation-tooltip.d.ts.map +1 -0
  105. package/dist/esm/api/validation-tooltip.js +34 -0
  106. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  107. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  108. package/dist/esm/atoms/advanced-filter-dialog.atom.js +21 -0
  109. package/dist/esm/atoms/go-to-dialog.atom.d.ts +11 -1
  110. package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -1
  111. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +29 -0
  112. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  113. package/dist/esm/atoms/goal-seek-dialog.atom.js +21 -0
  114. package/dist/esm/atoms/index.d.ts +1 -0
  115. package/dist/esm/atoms/index.d.ts.map +1 -1
  116. package/dist/esm/atoms/index.js +1 -0
  117. package/dist/esm/atoms/subtotal-dialog.atom.d.ts +39 -0
  118. package/dist/esm/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  119. package/dist/esm/atoms/subtotal-dialog.atom.js +21 -0
  120. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  121. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  122. package/dist/esm/atoms/text-to-columns-dialog.atom.js +25 -0
  123. package/dist/esm/atoms/watch-window.atom.d.ts +37 -0
  124. package/dist/esm/atoms/watch-window.atom.d.ts.map +1 -0
  125. package/dist/esm/atoms/watch-window.atom.js +37 -0
  126. package/dist/esm/components/advanced-filter-dialog/index.d.ts +28 -0
  127. package/dist/esm/components/advanced-filter-dialog/index.d.ts.map +1 -0
  128. package/dist/esm/components/advanced-filter-dialog/index.js +125 -0
  129. package/dist/esm/components/calculation-options-dialog/index.d.ts +33 -0
  130. package/dist/esm/components/calculation-options-dialog/index.d.ts.map +1 -0
  131. package/dist/esm/components/calculation-options-dialog/index.js +61 -0
  132. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  133. package/dist/esm/components/canvas-grid/index.js +99 -20
  134. package/dist/esm/components/canvas-grid/typings.d.ts +19 -2
  135. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  136. package/dist/esm/components/cell/alignment.d.ts +30 -0
  137. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  138. package/dist/esm/components/cell/alignment.js +51 -0
  139. package/dist/esm/components/cell/index.d.ts.map +1 -1
  140. package/dist/esm/components/cell/index.js +16 -8
  141. package/dist/esm/components/cell-diff/index.d.ts +3 -2
  142. package/dist/esm/components/cell-diff/index.d.ts.map +1 -1
  143. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  144. package/dist/esm/components/cell-editor/index.js +2 -1
  145. package/dist/esm/components/context-menu/index.d.ts +6 -1
  146. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  147. package/dist/esm/components/context-menu/index.js +139 -4
  148. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  149. package/dist/esm/components/embeds/embed-component.js +17 -1
  150. package/dist/esm/components/go-to-dialog/index.d.ts +11 -1
  151. package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -1
  152. package/dist/esm/components/go-to-dialog/index.js +63 -23
  153. package/dist/esm/components/goal-seek-dialog/index.d.ts +32 -0
  154. package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -0
  155. package/dist/esm/components/goal-seek-dialog/index.js +125 -0
  156. package/dist/esm/components/subtotal-dialog/index.d.ts +30 -0
  157. package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -0
  158. package/dist/esm/components/subtotal-dialog/index.js +115 -0
  159. package/dist/esm/components/text-to-columns-dialog/index.d.ts +37 -0
  160. package/dist/esm/components/text-to-columns-dialog/index.d.ts.map +1 -0
  161. package/dist/esm/components/text-to-columns-dialog/index.js +147 -0
  162. package/dist/esm/components/toolbar/background-color-selector.d.ts +13 -1
  163. package/dist/esm/components/toolbar/background-color-selector.d.ts.map +1 -1
  164. package/dist/esm/components/toolbar/background-color-selector.js +61 -11
  165. package/dist/esm/components/toolbar/cell-style-selector.d.ts +15 -2
  166. package/dist/esm/components/toolbar/cell-style-selector.d.ts.map +1 -1
  167. package/dist/esm/components/toolbar/cell-style-selector.js +46 -2
  168. package/dist/esm/components/toolbar/fill-selectors.d.ts +49 -0
  169. package/dist/esm/components/toolbar/fill-selectors.d.ts.map +1 -0
  170. package/dist/esm/components/toolbar/fill-selectors.js +162 -0
  171. package/dist/esm/components/toolbar/index.d.ts +1 -0
  172. package/dist/esm/components/toolbar/index.d.ts.map +1 -1
  173. package/dist/esm/components/toolbar/index.js +1 -0
  174. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  175. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  176. package/dist/esm/components/toolbar/text-horizontal-align-selector.js +21 -5
  177. package/dist/esm/components/watch-window/index.d.ts +25 -0
  178. package/dist/esm/components/watch-window/index.d.ts.map +1 -0
  179. package/dist/esm/components/watch-window/index.js +54 -0
  180. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  181. package/dist/esm/hooks/use-cell-renderer.js +17 -6
  182. package/dist/esm/hooks/use-get-tooltip.d.ts.map +1 -1
  183. package/dist/esm/hooks/use-get-tooltip.js +7 -2
  184. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  185. package/dist/esm/hooks/use-keyboard-handler.js +24 -12
  186. package/dist/esm/index.d.ts +8 -0
  187. package/dist/esm/index.d.ts.map +1 -1
  188. package/dist/esm/index.js +8 -0
  189. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  190. package/dist/esm/types.d.ts +117 -4
  191. package/dist/esm/types.d.ts.map +1 -1
  192. package/dist/esm/types.js +18 -0
  193. package/dist/spreadsheet.min.css +1 -1
  194. package/package.json +6 -6
@@ -14,7 +14,7 @@ import { CellFilter } from "../cell-filter";
14
14
  import { CellGroup } from "../cell-group";
15
15
  import { CellTextRuns } from "./cell-text-runs";
16
16
  import { hasRenderableRuns } from "./rich-text";
17
- import { computeShrinkToFitFontSize, getKonvaRotationDegrees, getRotatedTextLayout, stackTextVertically, } from "./alignment";
17
+ import { alignmentImpliesWrap, computeShrinkToFitFontSize, fillCellText, getKonvaRotationDegrees, getRotatedTextLayout, resolveCanvasTextAlign, stackTextVertically, } from "./alignment";
18
18
  import { getLeftSpacing, getRightSpacing } from "./helpers";
19
19
  const LOADING_VALUE = "Loading...";
20
20
  // CSS-equivalent scale for sup/sub baseline offset (matches browser default).
@@ -38,6 +38,10 @@ export const Cell = memo((props) => {
38
38
  (getDefaultHorizontalAlignment(sheetId, rowIndex, columnIndex) ||
39
39
  CELL_HORIZONTAL_ALIGNMENT);
40
40
  const verticalAlignment = cellFormat?.verticalAlignment || CELL_VERTICAL_ALIGNMENT;
41
+ // Excel-only modes (justify / distributed / fill / centerContinuous)
42
+ // collapse onto what the canvas text node can paint.
43
+ const canvasTextAlign = resolveCanvasTextAlign(horizontalAlignment);
44
+ const isFillAlignment = horizontalAlignment === "fill";
41
45
  // Text format
42
46
  const { color: colorObject, bold, italic, strikethrough, underline, baselineOffset, } = textFormat ?? {};
43
47
  const fontSizePt = textFormat?.fontSize ?? defaultFontSizePoint;
@@ -151,20 +155,24 @@ export const Cell = memo((props) => {
151
155
  const effectiveFontSize = shrinkEnabled
152
156
  ? computeShrinkToFitFontSize(textWidth, shrinkAvailableWidth, fontSize, true)
153
157
  : fontSize;
154
- // Wrap — disabled in stacked, shrink, or rotated modes.
158
+ // Wrap — disabled in stacked, shrink, or rotated modes. Justify /
159
+ // distributed alignment wraps implicitly, as in Excel.
160
+ const wrapRequested = wrapStrategy === "wrap" || alignmentImpliesWrap(horizontalAlignment);
155
161
  const textWrapStrategy = isStackedVertical || shrinkEnabled || hasNumericRotation
156
162
  ? "none"
157
- : wrapStrategy === "wrap"
163
+ : wrapRequested
158
164
  ? "word"
159
165
  : "none";
160
- const shouldWrap = wrapStrategy === "wrap" &&
166
+ const shouldWrap = wrapRequested &&
161
167
  !isStackedVertical &&
162
168
  !shrinkEnabled &&
163
169
  !hasNumericRotation;
164
170
  const baseDisplayValue = normalizeDisplayText(value, shouldWrap);
165
171
  const displayValue = isStackedVertical
166
172
  ? stackTextVertically(baseDisplayValue ?? "")
167
- : baseDisplayValue;
173
+ : isFillAlignment && !hasNumericRotation
174
+ ? fillCellText(baseDisplayValue, _textWidth, finalTextWidth - 2 * padding)
175
+ : baseDisplayValue;
168
176
  // For rotated text, anchor the rotation pivot to an alignment-aware
169
177
  // corner of the cell so the text stays inside instead of sliding off
170
178
  // (Konva otherwise rotates around the Text's top-left at x/y).
@@ -219,7 +227,7 @@ export const Cell = memo((props) => {
219
227
  conditionalIcon ? (React.createElement(Text, { x: x + 2, y: y, width: CF_ICON_WIDTH * scale, height: height, text: conditionalIcon.glyph, fill: conditionalIcon.color ?? color ?? defaultColor, verticalAlign: "middle", align: "center", fontSize: fontSize, listening: false, perfectDrawEnabled: false })) : null,
220
228
  showCheckbox ? (React.createElement(CellCheckbox, { x: x, y: y, scale: scale, width: width, height: height, checked: isChecked, onChange: onCheckboxClick, rowIndex: props.rowIndex, columnIndex: props.columnIndex, verticalAlignment: verticalAlignment, horizontalAlignment: horizontalAlignment })) : showText ? (React.createElement(Group, { clipY: y + borderWidth, clipHeight: height, clipX: clipX, clipWidth: clipWidth }, showChip ? (React.createElement(Label, { width: width - CHIP_SPACING * scale, height: CHIP_HEIGHT * scale, x: textLeftPadding, y: getChipVerticalPosition(y, height, scale, verticalAlignment), offsetX: -CHIP_SPACING * scale, offsetY: -CHIP_SPACING * scale },
221
229
  React.createElement(Tag, { height: CHIP_HEIGHT * scale, fill: chipBackgroundColor, cornerRadius: CHIP_RADIUS * scale, perfectDrawEnabled: false, hitStrokeWidth: 0 }),
222
- React.createElement(Text, { text: displayValue, fill: color ?? defaultColor, verticalAlign: effectiveVerticalAlignment, align: horizontalAlignment, fontFamily: fontFamily, fontStyle: textStyle, fontSize: fontSize, textDecoration: textDecoration, padding: padding, lineHeight: 1, offsetY: -1, perfectDrawEnabled: false, wrap: "none" }))) : useRichTextRunPath ? (
230
+ React.createElement(Text, { text: displayValue, fill: color ?? defaultColor, verticalAlign: effectiveVerticalAlignment, align: canvasTextAlign, fontFamily: fontFamily, fontStyle: textStyle, fontSize: fontSize, textDecoration: textDecoration, padding: padding, lineHeight: 1, offsetY: -1, perfectDrawEnabled: false, wrap: "none" }))) : useRichTextRunPath ? (
223
231
  // Per-segment styled paint. Bounded by the same clip rect
224
232
  // and padding the default Text path uses, so cell chrome
225
233
  // (filter button, expand caret, error tag) overlays at
@@ -236,7 +244,7 @@ export const Cell = memo((props) => {
236
244
  // sup/sub font scale itself (exactly once). Shrink-to-
237
245
  // fit never reaches this path, so `baseFontSize` equals
238
246
  // `effectiveFontSize` for every other cell.
239
- baseFontSize: baseFontSize, baseBold: !!bold, baseItalic: !!italic, baseUnderline: !!underline, baseStrikethrough: !!strikethrough, baseBaselineOffset: baselineOffset ?? undefined, horizontalAlign: horizontalAlignment, verticalAlign: effectiveVerticalAlignment, lineHeight: lineHeight, wrap: shouldWrap, theme: theme })) : (React.createElement(Text, { x: rotatedLayout?.x ?? textLeftPadding, y: rotatedLayout?.y ?? y + cellSpacingY, offsetX: rotatedLayout?.offsetX, offsetY: rotatedLayout?.offsetY, height: rotatedLayout ? approxTextHeight : height, width: rotatedLayout?.width ?? finalTextWidth, text: displayValue, fill: color ?? defaultColor, verticalAlign: rotatedLayout ? "top" : effectiveVerticalAlignment, align: rotatedLayout ? "left" : horizontalAlignment, fontFamily: fontFamily, fontStyle: textStyle, fontSize: effectiveFontSize, textDecoration: textDecoration, padding: padding, wrap: textWrapStrategy, lineHeight: lineHeight, rotation: rotationDegrees, hitStrokeWidth: 0, perfectDrawEnabled: false })))) : imageUrl ? (React.createElement(Image, { x: x, y: y, spacing: 1, width: width, height: height, url: imageUrl, perfectDrawEnabled: false, horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment })) : null,
247
+ baseFontSize: baseFontSize, baseBold: !!bold, baseItalic: !!italic, baseUnderline: !!underline, baseStrikethrough: !!strikethrough, baseBaselineOffset: baselineOffset ?? undefined, horizontalAlign: canvasTextAlign, verticalAlign: effectiveVerticalAlignment, lineHeight: lineHeight, wrap: shouldWrap, theme: theme })) : (React.createElement(Text, { x: rotatedLayout?.x ?? textLeftPadding, y: rotatedLayout?.y ?? y + cellSpacingY, offsetX: rotatedLayout?.offsetX, offsetY: rotatedLayout?.offsetY, height: rotatedLayout ? approxTextHeight : height, width: rotatedLayout?.width ?? finalTextWidth, text: displayValue, fill: color ?? defaultColor, verticalAlign: rotatedLayout ? "top" : effectiveVerticalAlignment, align: rotatedLayout ? "left" : canvasTextAlign, fontFamily: fontFamily, fontStyle: textStyle, fontSize: effectiveFontSize, textDecoration: textDecoration, padding: padding, wrap: textWrapStrategy, lineHeight: lineHeight, rotation: rotationDegrees, hitStrokeWidth: 0, perfectDrawEnabled: false })))) : imageUrl ? (React.createElement(Image, { x: x, y: y, spacing: 1, width: width, height: height, url: imageUrl, perfectDrawEnabled: false, horizontalAlignment: canvasTextAlign === "justify" ? "left" : canvasTextAlign, verticalAlignment: verticalAlignment })) : null,
240
248
  showFilter ? (React.createElement(CellFilter, { scale: scale, isActive: isFilterActive, onClick: readonly ? undefined : onFilterClick, rowIndex: props.rowIndex, columnIndex: props.columnIndex, x: x, y: y, height: height, width: width, filterIconColor: filterIconColor, verticalAlignment: verticalAlignment, backgroundColor: defaultBackgroundColor, sortOrder: sortOrder })) : showArrow && !readonly ? (React.createElement(CellArrow, { scale: scale, onClick: onRequestEdit, rowIndex: rowIndex, columnIndex: columnIndex, x: x, y: y, height: height, width: width, verticalAlignment: verticalAlignment })) : null,
241
249
  expandable ? (React.createElement(CellGroup, { scale: scale, onClick: (cell) => {
242
250
  onExpandCollapse?.(cell, !expanded);
@@ -247,7 +255,7 @@ export const Cell = memo((props) => {
247
255
  showComment ? (React.createElement(CellError, { color: COMMENT_COLOR, x: x + width - ERROR_TAG_WIDTH * scale, y: y + 1, scale: scale })) : null,
248
256
  structuredValue ? (React.createElement(StructuredResult, { x: x, y: y, width: width, height: height,
249
257
  // Text props
250
- textX: textLeftPadding, textY: y + cellSpacingY, textWidth: finalTextWidth, textFill: color ?? defaultColor, textVerticalAlign: verticalAlignment, textAlign: horizontalAlignment, textFontFamily: fontFamily, textFontStyle: textStyle, textFontSize: fontSize, textDecoration: textDecoration, textPadding: padding, textWrap: textWrapStrategy, textLineHeight: lineHeight,
258
+ textX: textLeftPadding, textY: y + cellSpacingY, textWidth: finalTextWidth, textFill: color ?? defaultColor, textVerticalAlign: verticalAlignment, textAlign: canvasTextAlign, textFontFamily: fontFamily, textFontStyle: textStyle, textFontSize: fontSize, textDecoration: textDecoration, textPadding: padding, textWrap: textWrapStrategy, textLineHeight: lineHeight,
251
259
  // / Text props
252
260
  color: defaultBackgroundColor
253
261
  ? getContrastColor(getStringifiedColor(defaultBackgroundColor, theme), getStringifiedColor({ theme: 1 }, theme), getStringifiedColor({ theme: 1, tint: 1 }, theme))
@@ -1,3 +1,4 @@
1
+ import type { HorizontalAlign } from "../../types";
1
2
  import React from "react";
2
3
  import type { CellDiffHighlight } from "@rowsncolumns/version-comparison";
3
4
  export type CellDiffProps = {
@@ -27,8 +28,8 @@ export type CellDiffProps = {
27
28
  bold?: boolean | null;
28
29
  /** Italic */
29
30
  italic?: boolean | null;
30
- /** Horizontal alignment */
31
- horizontalAlignment?: "left" | "center" | "right" | null;
31
+ /** Horizontal alignment (Excel-only modes are read as left / center) */
32
+ horizontalAlignment?: HorizontalAlign | null;
32
33
  /** Vertical alignment */
33
34
  verticalAlignment?: "top" | "middle" | "bottom" | null;
34
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-diff/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAW1E,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,aAAa,EAAE,iBAAiB,CAAC;IACjC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW;IACX,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,aAAa;IACb,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,2BAA2B;IAC3B,mBAAmB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC;IACzD,yBAAyB;IACzB,iBAAiB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,oCAAgB,aAAa,8BAqLhD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-diff/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAW1E,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,aAAa,EAAE,iBAAiB,CAAC;IACjC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW;IACX,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,aAAa;IACb,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7C,yBAAyB;IACzB,iBAAiB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,oCAAgB,aAAa,8BAqLhD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-editor/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-editor/index.tsx"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import { useTextDimension } from "../../hooks/use-text-dimensions";
13
13
  import { getStringifiedColor } from "../../themes";
14
14
  import { CalendarPopup } from "./calendar-popup";
15
15
  import { FormulaResultPreview } from "./formula-result-preview";
16
+ import { resolveCanvasTextAlign } from "../cell/alignment";
16
17
  import { getDirectionFromKey, shouldShowCalendarPopup } from "./helpers";
17
18
  import { dropdownStyles, StyledAddress, StyledAddressContainer, StyledEditor, } from "./style";
18
19
  export const CellEditor = memo(({ value = "", effectiveValue, isNewValue, onChange, sheetId, editingSheetId, cell, position, format, locale, scale = 1, autoFocus, maxWidth, maxHeight, containerWidth, onSubmit, onCancel, getNextFocusableCell, dataValidation, getRangeValues, getRangeValuesAsync, horizontalAlignment, editingSheetName, address, isScrolling, showFormulaHelp, onHideFormulaHelp, onShowFormulaHelp, onKeyDown, tokenizer, defaultBackgroundColor, defaultTextColor, theme, functionDescriptions, getNamedRanges, getTableNames, getTableColumnNames, getStructuredProperties, onRequestCalculate, editorBorderColor, isPointerDevice, SuggestionsDropdown, stickyEditor, defaultFontSizePoint, textFormatRuns, getMentions, getFunctionParameterSuggestions, shouldFetchFunctionParameters, MentionTagComponent, MentionDropdownItemComponent, navigationMode, onCopy, onPaste, onCut, onBlur, }) => {
@@ -234,7 +235,7 @@ export const CellEditor = memo(({ value = "", effectiveValue, isNewValue, onChan
234
235
  color: formulaMode ? defaultTextColor : editorColor,
235
236
  fontSize: fontSize * scale,
236
237
  fontFamily,
237
- textAlign: finalHorizontalAlignment,
238
+ textAlign: resolveCanvasTextAlign(finalHorizontalAlignment),
238
239
  fontWeight,
239
240
  fontStyle,
240
241
  textDecoration,
@@ -62,6 +62,9 @@ export type ContextMenuProps = {
62
62
  onSortTable: CanvasGridProps["onSortTable"];
63
63
  onSplitTextToColumns: CanvasGridProps["onSplitTextToColumns"];
64
64
  onRemoveDuplicates: CanvasGridProps["onRemoveDuplicates"];
65
+ onGoalSeek?: CanvasGridProps["onGoalSeek"];
66
+ onSubtotal?: CanvasGridProps["onSubtotal"];
67
+ onAdvancedFilter?: CanvasGridProps["onAdvancedFilter"];
65
68
  /** Writes a table totals-row aggregation formula into the active cell. */
66
69
  onChange?: CanvasGridProps["onChange"];
67
70
  /** Reads the active cell's formula to highlight its totals-row function. */
@@ -84,10 +87,12 @@ export type ContextMenuProps = {
84
87
  onRequestEvaluateFormula?(sheetId: number, cell: CellInterface): void;
85
88
  /** Whether the active cell holds a formula (drives the Evaluate Formula item). */
86
89
  isActiveCellFormula?: boolean;
90
+ /** Adds the active cell to the Watch Window (only while a host is mounted). */
91
+ onRequestAddWatch?(sheetId: number, cell: CellInterface): void;
87
92
  onCut?(): void;
88
93
  readonly?: boolean;
89
94
  onAddQuickEdit(range: SheetRange): void;
90
95
  enableMagicFill?: boolean;
91
96
  };
92
- export declare const ContextMenu: ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly, onAddQuickEdit, enableMagicFill, }: ContextMenuProps) => React.JSX.Element;
97
+ export declare const ContextMenu: ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, onRequestAddWatch, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onGoalSeek, onSubtotal, onAdvancedFilter, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly, onAddQuickEdit, enableMagicFill, }: ContextMenuProps) => React.JSX.Element;
93
98
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/context-menu/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/context-menu/index.tsx"],"names":[],"mappings":"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"}
@@ -1,15 +1,19 @@
1
1
  import { Direction, isCellWithinBounds, selectionFromActiveCell, } from "@rowsncolumns/grid";
2
2
  import { ArrowLeftIcon, ArrowRightIcon, CheckIcon, ChevronRightIcon, ClipboardIcon, CodeIcon, CopyIcon, Cross1Icon, DotsVerticalIcon, EyeNoneIcon, EyeOpenIcon, FunnelIcon, MdBrush, MdOutlineFactCheck, PaintBrush, PlusIcon, ReaderIcon, RemoveDuplicatesIcon, ScissorsIcon, SizeIcon, SortDownIcon, SortUpIcon, SpaceBetweenHorizontallyIcon, TableIcon, TrashIcon, ViewGridIcon, WandIcon, } from "@rowsncolumns/icons";
3
3
  import { DropdownLeftSlot, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownRightSlot, } from "@rowsncolumns/ui";
4
- import { number2Alpha } from "@rowsncolumns/utils";
4
+ import { addressToCell, cellToAddress, number2Alpha } from "@rowsncolumns/utils";
5
5
  import React, { useCallback, useMemo, useRef } from "react";
6
6
  import { getProtectedRange, isProtectedRange } from "../../api/validation";
7
7
  import { useGetContentfulRangeAroundCell } from "../../atoms";
8
+ import { useIsAdvancedFilterDialogMounted, useOpenAdvancedFilterDialog, } from "../../atoms/advanced-filter-dialog.atom";
9
+ import { useIsGoalSeekDialogMounted, useOpenGoalSeekDialog, } from "../../atoms/goal-seek-dialog.atom";
8
10
  import { useIsRemoveDuplicatesDialogMounted, useOpenRemoveDuplicatesDialog, } from "../../atoms/remove-duplicates-dialog.atom";
11
+ import { useIsSubtotalDialogMounted, useOpenSubtotalDialog, } from "../../atoms/subtotal-dialog.atom";
12
+ import { useIsTextToColumnsDialogMounted, useOpenTextToColumnsDialog, } from "../../atoms/text-to-columns-dialog.atom";
9
13
  import { BLANK_LABEL } from "../../config";
10
14
  import { createArrayRange, generateMultiDimTitle } from "../../helpers";
11
15
  import { getTotalRowFunctionFormula, getTotalRowFunctionFromFormula, TOTAL_ROW_FUNCTIONS, } from "./total-row-functions";
12
- export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly = false, onAddQuickEdit, enableMagicFill, }) => {
16
+ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, onRequestAddWatch, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onGoalSeek, onSubtotal, onAdvancedFilter, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly = false, onAddQuickEdit, enableMagicFill, }) => {
13
17
  const isHeader = isColumnHeader || isRowHeader;
14
18
  const shouldFocusSheetRef = useRef(true);
15
19
  const multiColumnTitle = generateMultiDimTitle(selectedColumnHeadersIds, "y");
@@ -39,6 +43,114 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
39
43
  const lastSelectedRowIndex = selectedRowHeadersIds.reduce((m, v) => (v > m ? v : m), -Infinity);
40
44
  // Get contentful range
41
45
  const getContentfulRangeAroundCell = useGetContentfulRangeAroundCell();
46
+ // The data block the data tools act on: a table's own rows, the selection,
47
+ // or (from a lone cell) the contentful region around it — like Excel.
48
+ const dataRangeAroundSelection = useCallback(() => {
49
+ if (activeTable) {
50
+ return {
51
+ ...activeTable.range,
52
+ endRowIndex: activeTable.range.endRowIndex - (activeTable.totalRow ? 1 : 0),
53
+ };
54
+ }
55
+ if (selections.length) {
56
+ return selection.range;
57
+ }
58
+ return getContentfulRangeAroundCell?.(sheetId, activeCell) ?? selection.range;
59
+ }, [activeTable, selections.length, selection.range, getContentfulRangeAroundCell, sheetId, activeCell]);
60
+ // Excel pre-ticks "my data has headers" when the first row reads as labels:
61
+ // every cell filled and none of them a number.
62
+ const headerColumnsOf = useCallback((range) => {
63
+ const columns = [];
64
+ for (let columnIndex = range.startColumnIndex; columnIndex <= range.endColumnIndex; columnIndex++) {
65
+ const header = activeTable?.columns?.[columnIndex - activeTable.range.startColumnIndex]
66
+ ?.name ?? getFormattedValue(sheetId, range.startRowIndex, columnIndex);
67
+ columns.push({
68
+ columnIndex,
69
+ label: `Column ${number2Alpha(columnIndex - 1)}`,
70
+ header: header || undefined,
71
+ });
72
+ }
73
+ const hasHeader = activeTable
74
+ ? (activeTable.headerRow ?? true)
75
+ : range.endRowIndex > range.startRowIndex &&
76
+ columns.every((column) => !!column.header && Number.isNaN(Number(column.header)));
77
+ return { columns, hasHeader };
78
+ }, [activeTable, getFormattedValue, sheetId]);
79
+ const rangeAddress = (range) => `${cellToAddress({ rowIndex: range.startRowIndex, columnIndex: range.startColumnIndex })}:${cellToAddress({ rowIndex: range.endRowIndex, columnIndex: range.endColumnIndex })}`;
80
+ // Text to Columns → Fixed width (dialog with a ruler over the selected column).
81
+ const isTextToColumnsDialogMounted = useIsTextToColumnsDialogMounted();
82
+ const openTextToColumnsDialog = useOpenTextToColumnsDialog();
83
+ const handleTextToColumnsDialog = useCallback(() => {
84
+ const range = selections.length ? selection.range : dataRangeAroundSelection();
85
+ const columnIndex = selections.length ? range.startColumnIndex : activeCell.columnIndex;
86
+ const preview = [];
87
+ const firstRow = selections.length ? range.startRowIndex : activeCell.rowIndex;
88
+ const lastRow = selections.length ? range.endRowIndex : range.endRowIndex;
89
+ for (let rowIndex = firstRow; rowIndex <= lastRow && preview.length < 8; rowIndex++) {
90
+ preview.push(getFormattedValue(sheetId, rowIndex, columnIndex) ?? "");
91
+ }
92
+ const target = selections.length
93
+ ? selections
94
+ : [
95
+ {
96
+ range: {
97
+ startRowIndex: activeCell.rowIndex,
98
+ endRowIndex: range.endRowIndex,
99
+ startColumnIndex: columnIndex,
100
+ endColumnIndex: columnIndex,
101
+ },
102
+ },
103
+ ];
104
+ openTextToColumnsDialog({
105
+ preview,
106
+ onApply: ({ delimiter, columnBreaks }) => onSplitTextToColumns?.(sheetId, activeCell, target, delimiter, { columnBreaks }),
107
+ });
108
+ }, [
109
+ selections,
110
+ selection.range,
111
+ dataRangeAroundSelection,
112
+ activeCell,
113
+ getFormattedValue,
114
+ sheetId,
115
+ openTextToColumnsDialog,
116
+ onSplitTextToColumns,
117
+ ]);
118
+ // Data → Subtotal.
119
+ const isSubtotalDialogMounted = useIsSubtotalDialogMounted();
120
+ const openSubtotalDialog = useOpenSubtotalDialog();
121
+ const handleSubtotal = useCallback(() => {
122
+ const range = dataRangeAroundSelection();
123
+ const { columns, hasHeader } = headerColumnsOf(range);
124
+ openSubtotalDialog({
125
+ columns,
126
+ hasHeader,
127
+ onApply: (choices) => onSubtotal?.(sheetId, { range, ...choices }),
128
+ });
129
+ }, [dataRangeAroundSelection, headerColumnsOf, openSubtotalDialog, onSubtotal, sheetId]);
130
+ // Data → Advanced filter.
131
+ const isAdvancedFilterDialogMounted = useIsAdvancedFilterDialogMounted();
132
+ const openAdvancedFilterDialog = useOpenAdvancedFilterDialog();
133
+ const handleAdvancedFilter = useCallback(() => {
134
+ openAdvancedFilterDialog({
135
+ listRange: rangeAddress(dataRangeAroundSelection()),
136
+ onApply: (options) => onAdvancedFilter?.(sheetId, options),
137
+ });
138
+ }, [openAdvancedFilterDialog, dataRangeAroundSelection, onAdvancedFilter, sheetId]);
139
+ // Data → What-If Analysis → Goal Seek.
140
+ const isGoalSeekDialogMounted = useIsGoalSeekDialogMounted();
141
+ const openGoalSeekDialog = useOpenGoalSeekDialog();
142
+ const handleGoalSeek = useCallback(() => {
143
+ openGoalSeekDialog({
144
+ setCell: cellToAddress(activeCell) ?? "",
145
+ onApply: async (setCellAddress, targetValue, changingCellAddress) => {
146
+ const setCell = addressToCell(setCellAddress);
147
+ const changingCell = addressToCell(changingCellAddress);
148
+ if (!setCell || !changingCell || !onGoalSeek)
149
+ return undefined;
150
+ return onGoalSeek(sheetId, setCell, targetValue, changingCell);
151
+ },
152
+ });
153
+ }, [openGoalSeekDialog, activeCell, onGoalSeek, sheetId]);
42
154
  // Remove duplicates — Excel's dialog (column checklist + "my data has
43
155
  // headers") when a host mounts `RemoveDuplicatesDialogHost`, otherwise the
44
156
  // one-click de-dupe over the selection.
@@ -654,7 +766,14 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
654
766
  } },
655
767
  React.createElement(DropdownLeftSlot, null,
656
768
  React.createElement(CodeIcon, null)),
657
- "Evaluate formula")) : null)),
769
+ "Evaluate formula")) : null,
770
+ onRequestAddWatch ? (React.createElement(DropdownMenuItem, { onClick: () => {
771
+ shouldFocusSheetRef.current = false;
772
+ onRequestAddWatch(sheetId, activeCell);
773
+ } },
774
+ React.createElement(DropdownLeftSlot, null,
775
+ React.createElement(EyeOpenIcon, null)),
776
+ "Add to Watch Window")) : null)),
658
777
  React.createElement(DropdownMenuSeparator, null),
659
778
  React.createElement(DropdownMenuItem, { onClick: handleRemoveDuplicates, disabled: readonly },
660
779
  React.createElement(DropdownLeftSlot, null,
@@ -672,7 +791,23 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
672
791
  React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, ";") }, "Semicolon"),
673
792
  React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, ".") }, "Period"),
674
793
  React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, " ") }, "Space"),
675
- React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, "|") }, "Pipe"))),
794
+ React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, "|") }, "Pipe"),
795
+ isTextToColumnsDialogMounted ? (React.createElement(React.Fragment, null,
796
+ React.createElement(DropdownMenuSeparator, null),
797
+ React.createElement(DropdownMenuItem, { onClick: handleTextToColumnsDialog }, "Fixed width\u2026"))) : null)),
798
+ (isSubtotalDialogMounted && onSubtotal) ||
799
+ (isAdvancedFilterDialogMounted && onAdvancedFilter) ||
800
+ (isGoalSeekDialogMounted && onGoalSeek) ? (React.createElement(DropdownMenuSub, null,
801
+ React.createElement(DropdownMenuSubTrigger, { disabled: readonly },
802
+ React.createElement(DropdownLeftSlot, null,
803
+ React.createElement(SpaceBetweenHorizontallyIcon, null)),
804
+ "Data tools",
805
+ React.createElement(DropdownRightSlot, null,
806
+ React.createElement(ChevronRightIcon, null))),
807
+ React.createElement(DropdownMenuSubContent, { sideOffset: 2, alignOffset: -5 },
808
+ isSubtotalDialogMounted && onSubtotal ? (React.createElement(DropdownMenuItem, { onClick: handleSubtotal }, "Subtotal\u2026")) : null,
809
+ isAdvancedFilterDialogMounted && onAdvancedFilter ? (React.createElement(DropdownMenuItem, { onClick: handleAdvancedFilter }, "Advanced filter\u2026")) : null,
810
+ isGoalSeekDialogMounted && onGoalSeek ? (React.createElement(DropdownMenuItem, { onClick: handleGoalSeek }, "Goal seek\u2026")) : null))) : null,
676
811
  React.createElement(DropdownMenuSub, null,
677
812
  React.createElement(DropdownMenuSubTrigger, { disabled: readonly },
678
813
  React.createElement(DropdownLeftSlot, null,
@@ -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,EAIf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAIhF,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+LvB,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,uBA4NvB,CAAC"}
@@ -2,6 +2,7 @@ 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
4
  import { getStringifiedColor } from "../../themes";
5
+ import { resolveCanvasTextAlign } from "../cell/alignment";
5
6
  import { ShapeSvg } from "./shape-svg";
6
7
  export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected, onDeleteEmbed, onRequestEditEmbed, theme, }) => {
7
8
  const renderTextBox = (spec) => {
@@ -39,7 +40,9 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
39
40
  height: "100%",
40
41
  backgroundColor,
41
42
  padding: spec.padding ? `${spec.padding}px` : "4px",
42
- textAlign: spec.horizontalAlignment || undefined,
43
+ textAlign: spec.horizontalAlignment
44
+ ? resolveCanvasTextAlign(spec.horizontalAlignment)
45
+ : undefined,
43
46
  display: "flex",
44
47
  flexDirection: "column",
45
48
  justifyContent: spec.verticalAlignment === "top"
@@ -110,6 +113,19 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
110
113
  type: "textbox",
111
114
  ...embed.spec.textBody,
112
115
  }))) : null)) : null,
116
+ embed?.spec.type === "formControl" ? (
117
+ // Excel form controls round-trip but are not interactive here: draw
118
+ // the caption in a control-shaped placeholder so the layout reads.
119
+ React.createElement("div", { className: "flex h-full w-full items-center gap-1 overflow-hidden whitespace-nowrap px-1 text-xs", title: embed.spec.name ?? undefined },
120
+ embed.spec.objectType === "CheckBox" ||
121
+ embed.spec.objectType === "Radio" ? (React.createElement("span", { className: "inline-block h-3 w-3 shrink-0 border border-current", style: {
122
+ borderRadius: embed.spec.objectType === "Radio"
123
+ ? "50%"
124
+ : 2,
125
+ } })) : null,
126
+ React.createElement("span", { className: "truncate" }, embed.spec.text ??
127
+ embed.spec.name ??
128
+ embed.spec.objectType))) : null,
113
129
  readonly || !isSelected ? null : (React.createElement(DropdownMenu, null,
114
130
  React.createElement(DropdownMenuTrigger, { asChild: true, className: "print:hidden" },
115
131
  React.createElement(IconButton, { className: "absolute right-1 top-1 z-10" },
@@ -1,4 +1,6 @@
1
+ import type { GridRange } from "@rowsncolumns/grid";
1
2
  import React from "react";
3
+ import { type GoToSpecialKind } from "../../api/go-to-special";
2
4
  import type { NamedRange, SheetRange } from "../../types";
3
5
  export type GoToDialogProps = {
4
6
  /** Controls visibility. */
@@ -15,6 +17,14 @@ export type GoToDialogProps = {
15
17
  resolve(reference: string): SheetRange | undefined;
16
18
  /** Receives the resolved range; the host selects and scrolls to it. */
17
19
  onNavigate(range: SheetRange): void;
20
+ /**
21
+ * Go To Special. `resolve` returns the matching cell runs for a category;
22
+ * `onSelectRanges` receives them. Omit to hide the "Special…" panel.
23
+ */
24
+ special?: {
25
+ resolve(kind: GoToSpecialKind): GridRange[];
26
+ onSelectRanges(ranges: GridRange[]): void;
27
+ };
18
28
  };
19
29
  /**
20
30
  * Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
@@ -22,7 +32,7 @@ export type GoToDialogProps = {
22
32
  * jumps there. Resolution is delegated to `resolve` so the dialog stays
23
33
  * UI-only.
24
34
  */
25
- export declare const GoToDialog: React.MemoExoticComponent<({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, }: GoToDialogProps) => React.JSX.Element>;
35
+ export declare const GoToDialog: React.MemoExoticComponent<({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, special, }: GoToDialogProps) => React.JSX.Element>;
26
36
  /**
27
37
  * Host-mounted, atom-driven wrapper around {@link GoToDialog}. Mount it once
28
38
  * in the host alongside the other editor dialogs; the grid opens it on
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/go-to-dialog/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,uEAAuE;IACvE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACrC,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,wGAQlB,eAAe,uBA4GnB,CAAC;AAUF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;CA8B1B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/go-to-dialog/index.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,uEAAuE;IACvE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,EAAE,CAAC;QAC5C,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;KAC3C,CAAC;CACH,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,iHASlB,eAAe,uBA0MnB,CAAC;AAUF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;CA+B1B,CAAC"}
@@ -2,17 +2,32 @@ import { Button, cn, Dialog, DialogBody, DialogCloseButton, DialogContent, Dialo
2
2
  import { cellToAddress } from "@rowsncolumns/utils";
3
3
  import React, { memo, useCallback, useState } from "react";
4
4
  import { resolveGoToReference } from "../../api/go-to";
5
+ import { GO_TO_SPECIAL_OPTIONS, } from "../../api/go-to-special";
5
6
  import { useGoToDialogState, useRegisterGoToDialogHost, } from "../../atoms/go-to-dialog.atom";
6
7
  const INVALID_REFERENCE = "Reference is not valid.";
8
+ const NO_CELLS_FOUND = "No cells were found.";
7
9
  /**
8
10
  * Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
9
11
  * optionally sheet-qualified, or pick a defined name, and the selection
10
12
  * jumps there. Resolution is delegated to `resolve` so the dialog stays
11
13
  * UI-only.
12
14
  */
13
- export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, }) => {
15
+ export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, special, }) => {
14
16
  const [reference, setReference] = useState("");
15
17
  const [error, setError] = useState(undefined);
18
+ const [showSpecial, setShowSpecial] = useState(false);
19
+ const [specialKind, setSpecialKind] = useState("blanks");
20
+ const selectSpecial = useCallback(() => {
21
+ if (!special)
22
+ return;
23
+ const ranges = special.resolve(specialKind);
24
+ if (!ranges.length) {
25
+ setError(NO_CELLS_FOUND);
26
+ return;
27
+ }
28
+ special.onSelectRanges(ranges);
29
+ onOpenChange(false);
30
+ }, [special, specialKind, onOpenChange]);
16
31
  const navigate = useCallback((text) => {
17
32
  const range = resolve(text);
18
33
  if (!range) {
@@ -25,30 +40,55 @@ export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddres
25
40
  const names = (namedRanges ?? []).filter((range) => range.range && !range.hidden);
26
41
  return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
27
42
  React.createElement(DialogContent, { className: "w-[360px] max-w-[92vw] pointer-events-auto" },
28
- React.createElement(DialogTitle, null, "Go To"),
43
+ React.createElement(DialogTitle, null, showSpecial ? "Go To Special" : "Go To"),
29
44
  React.createElement(DialogCloseButton, null),
30
- React.createElement(DialogBody, { className: "flex flex-col gap-3" },
31
- React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
32
- e.preventDefault();
33
- navigate(reference);
34
- } },
35
- React.createElement("div", { className: "flex flex-col gap-1" },
36
- React.createElement("span", { className: "text-xs font-medium" }, "Go to:"),
37
- React.createElement("div", { role: "listbox", "aria-label": "Defined names", className: "h-[140px] overflow-auto rounded border border-rnc-border text-xs" }, names.length === 0 ? (React.createElement("div", { className: "px-2 py-1.5 text-rnc-foreground/60" }, "No defined names")) : (names.map((range) => (React.createElement("div", { key: String(range.namedRangeId), role: "option", "aria-selected": reference === range.name, className: cn("px-2 py-1 cursor-default select-none hover:bg-rnc-accent", reference === range.name && "bg-rnc-accent"), onClick: () => {
38
- setReference(range.name);
39
- setError(undefined);
40
- }, onDoubleClick: () => navigate(range.name) }, range.name)))))),
41
- React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
42
- "Reference:",
43
- React.createElement(Input, { autoFocus: true, value: reference, placeholder: currentAddress, "aria-invalid": error ? true : undefined, onChange: (e) => {
44
- setReference(e.target.value);
45
+ React.createElement(DialogBody, { className: "flex flex-col gap-3" }, showSpecial && special ? (React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
46
+ e.preventDefault();
47
+ selectSpecial();
48
+ } },
49
+ React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
50
+ React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Select"),
51
+ GO_TO_SPECIAL_OPTIONS.map(({ kind, label }) => (React.createElement("label", { key: kind, className: "flex items-center gap-2 text-xs cursor-pointer" },
52
+ React.createElement("input", { type: "radio", name: "goToSpecial", value: kind, checked: specialKind === kind, onChange: () => {
53
+ setSpecialKind(kind);
45
54
  setError(undefined);
46
- } })),
47
- error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
48
- React.createElement(Separator, null),
49
- React.createElement("div", { className: "flex justify-end gap-2" },
55
+ } }),
56
+ label)))),
57
+ error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
58
+ React.createElement(Separator, null),
59
+ React.createElement("div", { className: "flex justify-between gap-2" },
60
+ React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
61
+ setShowSpecial(false);
62
+ setError(undefined);
63
+ } }, "Back"),
64
+ React.createElement("div", { className: "flex gap-2" },
65
+ React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
66
+ React.createElement(Button, { type: "submit", size: "sm" }, "OK"))))) : (React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
67
+ e.preventDefault();
68
+ navigate(reference);
69
+ } },
70
+ React.createElement("div", { className: "flex flex-col gap-1" },
71
+ React.createElement("span", { className: "text-xs font-medium" }, "Go to:"),
72
+ React.createElement("div", { role: "listbox", "aria-label": "Defined names", className: "h-[140px] overflow-auto rounded border border-rnc-border text-xs" }, names.length === 0 ? (React.createElement("div", { className: "px-2 py-1.5 text-rnc-foreground/60" }, "No defined names")) : (names.map((range) => (React.createElement("div", { key: String(range.namedRangeId), role: "option", "aria-selected": reference === range.name, className: cn("px-2 py-1 cursor-default select-none hover:bg-rnc-accent", reference === range.name && "bg-rnc-accent"), onClick: () => {
73
+ setReference(range.name);
74
+ setError(undefined);
75
+ }, onDoubleClick: () => navigate(range.name) }, range.name)))))),
76
+ React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
77
+ "Reference:",
78
+ React.createElement(Input, { autoFocus: true, value: reference, placeholder: currentAddress, "aria-invalid": error ? true : undefined, onChange: (e) => {
79
+ setReference(e.target.value);
80
+ setError(undefined);
81
+ } })),
82
+ error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
83
+ React.createElement(Separator, null),
84
+ React.createElement("div", { className: "flex justify-between gap-2" },
85
+ special ? (React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
86
+ setShowSpecial(true);
87
+ setError(undefined);
88
+ } }, "Special\u2026")) : (React.createElement("span", null)),
89
+ React.createElement("div", { className: "flex gap-2" },
50
90
  React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
51
- React.createElement(Button, { type: "submit", size: "sm", disabled: !reference.trim() }, "OK")))))));
91
+ React.createElement(Button, { type: "submit", size: "sm", disabled: !reference.trim() }, "OK")))))))));
52
92
  });
53
93
  GoToDialog.displayName = "GoToDialog";
54
94
  const currentAddressOf = (request) => {
@@ -79,6 +119,6 @@ export const GoToDialogHost = () => {
79
119
  return (React.createElement(GoToDialog, { open: true, onOpenChange: (open) => {
80
120
  if (!open)
81
121
  close();
82
- }, namedRanges: request.namedRanges, currentAddress: currentAddressOf(request), resolve: resolve, onNavigate: request.onNavigate }));
122
+ }, namedRanges: request.namedRanges, currentAddress: currentAddressOf(request), resolve: resolve, onNavigate: request.onNavigate, special: request.special }));
83
123
  };
84
124
  GoToDialogHost.displayName = "GoToDialogHost";
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import type { GoalSeekResult } from "../../types";
3
+ export type GoalSeekDialogProps = {
4
+ /** Controls visibility. */
5
+ open: boolean;
6
+ onOpenChange(open: boolean): void;
7
+ /** Default "Set cell" (A1 reference of the active cell). */
8
+ initialSetCell: string;
9
+ /**
10
+ * Runs the search with the three fields (A1 references + the numeric
11
+ * target). Resolves to the result, or `undefined` when the engine reports
12
+ * none (the rnc engine iterates natively and streams the cells back).
13
+ */
14
+ onApply(setCell: string, targetValue: number, changingCell: string): Promise<GoalSeekResult | undefined>;
15
+ };
16
+ /** Excel's status sentence for a finished search. */
17
+ export declare const goalSeekStatusText: (setCell: string, result: GoalSeekResult | undefined) => string;
18
+ /**
19
+ * Excel's Goal Seek dialog: Set cell / To value / By changing cell, then the
20
+ * Goal Seek Status sentence with target and current value.
21
+ */
22
+ export declare const GoalSeekDialog: React.MemoExoticComponent<({ open, onOpenChange, initialSetCell, onApply }: GoalSeekDialogProps) => React.JSX.Element>;
23
+ /**
24
+ * Host-mounted, atom-driven wrapper around {@link GoalSeekDialog}. Mount
25
+ * once in the host; the context menu opens it via `useOpenGoalSeekDialog`
26
+ * and only offers the item while a host is mounted.
27
+ */
28
+ export declare const GoalSeekDialogHost: {
29
+ (): React.JSX.Element;
30
+ displayName: string;
31
+ };
32
+ //# sourceMappingURL=index.d.ts.map