@svgrid/grid 2.6.16 → 2.6.18

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 (212) hide show
  1. package/dist/DockNodeView.svelte.d.ts +1 -1
  2. package/dist/DockPopoutHost.svelte.d.ts +1 -1
  3. package/dist/FlexRender.svelte.d.ts +1 -1
  4. package/dist/GridFooter.svelte +6 -3
  5. package/dist/GridFooter.svelte.d.ts +3 -3
  6. package/dist/GridMenus.svelte.d.ts +3 -3
  7. package/dist/SvAccordion.svelte.d.ts +3 -3
  8. package/dist/SvAutoComplete.svelte.d.ts +2 -2
  9. package/dist/SvBreadcrumb.svelte.d.ts +2 -2
  10. package/dist/SvButtonGroup.svelte.d.ts +3 -3
  11. package/dist/SvCalendar.svelte.d.ts +7 -7
  12. package/dist/SvCarousel.svelte.d.ts +1 -1
  13. package/dist/SvCheckBox.svelte.d.ts +1 -1
  14. package/dist/SvColorInput.svelte.d.ts +1 -1
  15. package/dist/SvComboBox.svelte.d.ts +2 -2
  16. package/dist/SvCommand.svelte.d.ts +2 -2
  17. package/dist/SvCountryInput.svelte.d.ts +1 -1
  18. package/dist/SvDateRangeInput.svelte.d.ts +3 -3
  19. package/dist/SvDateTimePicker.svelte.d.ts +4 -4
  20. package/dist/SvDockLayout.svelte.d.ts +2 -2
  21. package/dist/SvDockManager.svelte.d.ts +2 -2
  22. package/dist/SvDropDownList.svelte.d.ts +2 -2
  23. package/dist/SvDurationInput.svelte.d.ts +1 -1
  24. package/dist/SvField.svelte.d.ts +1 -1
  25. package/dist/SvFileUpload.svelte.d.ts +3 -3
  26. package/dist/SvForm.svelte.d.ts +4 -4
  27. package/dist/SvGauge.svelte.d.ts +1 -1
  28. package/dist/SvGrid.controller.svelte.d.ts +28 -28
  29. package/dist/SvGrid.controller.svelte.js +117 -45
  30. package/dist/SvGrid.css +42 -2
  31. package/dist/SvGrid.helpers.d.ts +2 -2
  32. package/dist/SvGrid.svelte.d.ts +3 -3
  33. package/dist/SvGrid.types.d.ts +28 -7
  34. package/dist/SvGridCellEditor.svelte.d.ts +2 -2
  35. package/dist/SvGridChart.svelte.d.ts +1 -1
  36. package/dist/SvGridChartPanel.svelte.d.ts +2 -2
  37. package/dist/SvGridChartView.svelte.d.ts +1 -1
  38. package/dist/SvGridDropdown.svelte.d.ts +1 -1
  39. package/dist/SvGridSelect.svelte.d.ts +4 -4
  40. package/dist/SvGroupCell.svelte.d.ts +1 -1
  41. package/dist/SvHoverCard.svelte.d.ts +1 -1
  42. package/dist/SvListBox.svelte.d.ts +2 -2
  43. package/dist/SvMaskedInput.svelte.d.ts +1 -1
  44. package/dist/SvMenu.svelte.d.ts +1 -1
  45. package/dist/SvMenuList.svelte.d.ts +3 -3
  46. package/dist/SvMenubar.svelte.d.ts +3 -3
  47. package/dist/SvMultiSelect.svelte.d.ts +3 -3
  48. package/dist/SvNavPane.svelte.d.ts +1 -1
  49. package/dist/SvNumberInput.svelte.d.ts +1 -1
  50. package/dist/SvOtpInput.svelte.d.ts +1 -1
  51. package/dist/SvPasswordInput.svelte.d.ts +1 -1
  52. package/dist/SvPhoneInput.svelte.d.ts +2 -2
  53. package/dist/SvPopconfirm.svelte.d.ts +1 -1
  54. package/dist/SvPopover.svelte.d.ts +1 -1
  55. package/dist/SvRadioGroup.svelte.d.ts +3 -3
  56. package/dist/SvRating.svelte.d.ts +1 -1
  57. package/dist/SvSegmented.svelte.d.ts +3 -3
  58. package/dist/SvSlider.svelte.d.ts +1 -1
  59. package/dist/SvSparkline.svelte.d.ts +1 -1
  60. package/dist/SvSplitter.svelte.d.ts +3 -3
  61. package/dist/SvStepper.svelte.d.ts +2 -2
  62. package/dist/SvSwitchButton.svelte.d.ts +1 -1
  63. package/dist/SvTabs.svelte.d.ts +3 -3
  64. package/dist/SvTagsInput.svelte.d.ts +1 -1
  65. package/dist/SvTextArea.svelte.d.ts +1 -1
  66. package/dist/SvTextInput.svelte.d.ts +1 -1
  67. package/dist/SvTimePicker.svelte.d.ts +3 -3
  68. package/dist/SvTimeline.svelte.d.ts +2 -2
  69. package/dist/SvToggleButton.svelte.d.ts +1 -1
  70. package/dist/SvTooltip.svelte.d.ts +1 -1
  71. package/dist/SvTour.svelte.d.ts +3 -3
  72. package/dist/SvTree.svelte.d.ts +3 -3
  73. package/dist/SvTreeSelect.svelte.d.ts +3 -3
  74. package/dist/advanced-filter.svelte.d.ts +1 -1
  75. package/dist/ai.d.ts +1 -1
  76. package/dist/ai.js +1 -1
  77. package/dist/build-api.d.ts +2 -2
  78. package/dist/build-api.js +8 -8
  79. package/dist/builtin-editors.js +1 -1
  80. package/dist/cdn/{GridMenus-CPdy5dxw.js → GridMenus-B0F9iBrG.js} +1 -1
  81. package/dist/cdn/{GridMenus-BLajq_RP.js → GridMenus-IHK_l7m6.js} +1 -1
  82. package/dist/cdn/{src-CKpl94Cx.js → src-B1TdiyS8.js} +272 -270
  83. package/dist/cdn/{src-ogpR-lHu.js → src-Cd0tearp.js} +272 -270
  84. package/dist/cdn/svgrid.js +2 -2
  85. package/dist/cdn/svgrid.svelte-external.js +2 -2
  86. package/dist/cell-render.d.ts +3 -3
  87. package/dist/cell-render.js +6 -6
  88. package/dist/cell-values.d.ts +1 -1
  89. package/dist/cell-values.js +1 -1
  90. package/dist/chart-export.d.ts +1 -1
  91. package/dist/clipboard.d.ts +2 -2
  92. package/dist/clipboard.js +5 -5
  93. package/dist/column-groups.js +1 -1
  94. package/dist/columns.d.ts +2 -2
  95. package/dist/columns.js +1 -1
  96. package/dist/core.d.ts +1 -1
  97. package/dist/core.js +1 -1
  98. package/dist/createAutocomplete.svelte.d.ts +1 -1
  99. package/dist/createAutocomplete.svelte.js +2 -2
  100. package/dist/createButtonGroup.svelte.js +1 -1
  101. package/dist/createCalendar.svelte.d.ts +4 -4
  102. package/dist/createCalendar.svelte.js +4 -4
  103. package/dist/createCarousel.svelte.d.ts +1 -1
  104. package/dist/createCheckbox.svelte.js +1 -1
  105. package/dist/createColorInput.svelte.js +1 -1
  106. package/dist/createCombobox.svelte.d.ts +1 -1
  107. package/dist/createCombobox.svelte.js +2 -2
  108. package/dist/createCommand.svelte.d.ts +1 -1
  109. package/dist/createCommand.svelte.js +2 -2
  110. package/dist/createCountryInput.svelte.d.ts +1 -1
  111. package/dist/createCountryInput.svelte.js +2 -2
  112. package/dist/createDateTimePicker.svelte.d.ts +1 -1
  113. package/dist/createDateTimePicker.svelte.js +3 -3
  114. package/dist/createDropdownList.svelte.d.ts +1 -1
  115. package/dist/createDropdownList.svelte.js +2 -2
  116. package/dist/createFileUpload.svelte.js +1 -1
  117. package/dist/createForm.svelte.d.ts +1 -1
  118. package/dist/createForm.svelte.js +2 -2
  119. package/dist/createGrid.svelte.d.ts +1 -1
  120. package/dist/createGrid.svelte.js +1 -1
  121. package/dist/createGridState.svelte.d.ts +1 -1
  122. package/dist/createListbox.svelte.d.ts +1 -1
  123. package/dist/createListbox.svelte.js +2 -2
  124. package/dist/createMaskedInput.svelte.js +2 -2
  125. package/dist/createMenu.svelte.d.ts +2 -2
  126. package/dist/createMenu.svelte.js +2 -2
  127. package/dist/createNumberInput.svelte.js +1 -1
  128. package/dist/createOverlay.svelte.js +3 -3
  129. package/dist/createPagination.d.ts +1 -1
  130. package/dist/createPagination.js +1 -1
  131. package/dist/createPasswordInput.svelte.js +1 -1
  132. package/dist/createPhoneInput.svelte.js +3 -3
  133. package/dist/createPopoverSelect.svelte.d.ts +1 -1
  134. package/dist/createPopoverSelect.svelte.js +3 -3
  135. package/dist/createRadioGroup.svelte.js +1 -1
  136. package/dist/createRating.svelte.js +1 -1
  137. package/dist/createSlider.svelte.js +1 -1
  138. package/dist/createSwitch.svelte.js +1 -1
  139. package/dist/createTabs.svelte.d.ts +1 -1
  140. package/dist/createTagsInput.svelte.js +1 -1
  141. package/dist/createToggle.svelte.js +1 -1
  142. package/dist/createTooltip.svelte.js +1 -1
  143. package/dist/createTree.svelte.d.ts +1 -1
  144. package/dist/datetime/date-restrict.d.ts +1 -1
  145. package/dist/datetime/date-restrict.js +1 -1
  146. package/dist/datetime/date-selection.js +1 -1
  147. package/dist/dock-context.d.ts +1 -1
  148. package/dist/dock-manager-model.d.ts +1 -1
  149. package/dist/dock-manager-model.js +1 -1
  150. package/dist/dock-popout.d.ts +1 -1
  151. package/dist/dock-popout.js +1 -1
  152. package/dist/editing.d.ts +2 -2
  153. package/dist/editing.js +5 -5
  154. package/dist/editor-registry.d.ts +1 -1
  155. package/dist/editors/cell-editors.js +1 -1
  156. package/dist/export-format.d.ts +2 -2
  157. package/dist/export-format.js +2 -2
  158. package/dist/export-provider.d.ts +1 -1
  159. package/dist/facet-buckets.d.ts +1 -1
  160. package/dist/facet-buckets.js +1 -1
  161. package/dist/features.d.ts +2 -2
  162. package/dist/features.js +2 -2
  163. package/dist/filter-operators.d.ts +2 -2
  164. package/dist/filter-operators.js +1 -1
  165. package/dist/form-field.d.ts +1 -1
  166. package/dist/grid-messages.js +1 -1
  167. package/dist/headless.d.ts +11 -4
  168. package/dist/headless.js +11 -4
  169. package/dist/index.d.ts +120 -120
  170. package/dist/index.js +111 -111
  171. package/dist/keyboard-handlers.d.ts +2 -2
  172. package/dist/keyboard-handlers.js +2 -2
  173. package/dist/keyboard.d.ts +1 -1
  174. package/dist/menus.d.ts +3 -3
  175. package/dist/menus.js +3 -3
  176. package/dist/named-views.d.ts +1 -1
  177. package/dist/pivot-view.svelte.d.ts +1 -1
  178. package/dist/recurrence.d.ts +1 -1
  179. package/dist/recurrence.js +1 -1
  180. package/dist/row-drag.js +1 -1
  181. package/dist/scheduler-ical.d.ts +1 -1
  182. package/dist/scheduler-model.d.ts +3 -3
  183. package/dist/scheduler-model.js +2 -2
  184. package/dist/scroll-sync.d.ts +2 -2
  185. package/dist/scroll-sync.js +1 -1
  186. package/dist/selection.d.ts +2 -2
  187. package/dist/selection.js +3 -3
  188. package/dist/server-data-source.d.ts +1 -1
  189. package/dist/server-group-model.d.ts +1 -1
  190. package/dist/static-functions.d.ts +1 -1
  191. package/dist/static-functions.js +1 -1
  192. package/dist/subscribe.d.ts +1 -1
  193. package/dist/summaries.d.ts +2 -2
  194. package/dist/summaries.js +3 -3
  195. package/dist/svgrid-wrapper.types.d.ts +5 -5
  196. package/dist/themes/index.d.ts +3 -1
  197. package/dist/themes/index.js +4 -2
  198. package/dist/toast-store.svelte.js +1 -1
  199. package/dist/tree-select.d.ts +1 -1
  200. package/dist/virtualization/column-virtualizer.d.ts +3 -3
  201. package/dist/virtualization/column-virtualizer.js +1 -1
  202. package/dist/virtualization/svelte-virtualizer.svelte.d.ts +3 -3
  203. package/dist/virtualization/svelte-virtualizer.svelte.js +1 -1
  204. package/dist/virtualization/virtualizer.d.ts +1 -1
  205. package/package.json +14 -2
  206. package/src/GridFooter.svelte +6 -3
  207. package/src/SvGrid.controller.svelte.ts +90 -14
  208. package/src/SvGrid.css +42 -2
  209. package/src/SvGrid.types.ts +21 -0
  210. package/src/headless.ts +7 -0
  211. package/src/svgrid.behavior.test.ts +208 -0
  212. package/src/themes/index.ts +4 -2
@@ -1,33 +1,33 @@
1
- import { applyGroupAggregate, applyRowPredicate, compileExcelFilter, getAdvancedFilterEngine, normalizeForFilter, createColumnVirtualizer, createCoreRowModel, createExpandedRowModel, createFilteredRowModel, createGroupedRowModel, createTreeRowModel, createSvelteVirtualizer, createSortedRowModel, createSvGrid, getGridCellDomId, sortFns, } from "./index";
2
- import { createRowScrollScaling, resolveMaxDomHeight, } from "./virtualization/scroll-scaling";
3
- import { buildPreMeasureItems } from "./virtualization/virtualizer";
4
- import "./sv-grid-scrollbar";
5
- import { computeColumnStat, formatsNeedingStats, formatNeedsStats, } from "./conditional-formatting";
6
- import { rawToNumber, } from "./SvGrid.helpers";
7
- import { createFeatures } from "./features";
8
- import { createScrollSync, } from "./scroll-sync";
9
- import { createKeyboard, } from "./keyboard-handlers";
10
- import { createSummaries, } from "./summaries";
11
- import { createMenus, } from "./menus";
12
- import { createCellRender, } from "./cell-render";
13
- import { createEditing, } from "./editing";
14
- import { createSelection, } from "./selection";
15
- import { createColumns, } from "./columns";
16
- import { createRowDrag, } from "./row-drag";
17
- import { createAlignedGrids, } from "./aligned-grids";
18
- import { resolveColumnTypes, } from "./column-types";
19
- import { computeColumnGroupMeta, hiddenLeavesForCollapse, } from "./column-groups";
20
- import { resolveColumnId } from "./column-id";
21
- import { buildAutoGroupColumns, insertGroupFooters, paginateGroupedRows } from "./group-display";
22
- import { createGridApi, } from "./build-api";
23
- import { createClipboard, } from "./clipboard";
24
- import { resolveGridMessages } from "./grid-messages";
25
- import { announce } from "./a11y/live-region";
26
- import { filterAnnouncement, selectionAnnouncement, } from "./a11y/grid-announcements";
27
- import { getPivotEngine, hasPivotEngine } from "./pivot-view.svelte";
28
- import { filterOperatorOptions, fallbackOperatorOption, TEXT_OPERATORS, NUMBER_OPERATORS, DATE_OPERATORS, CHECKBOX_OPERATORS, operatorOption, operatorsForColumn, defaultOperatorFor, operatorLabelFor, } from "./filter-operators";
29
- import { isBucketableColumn, buildBuckets, isInBucket, } from "./facet-buckets";
30
- import { getColumnBaseValue, isGroupRow, toolPanelHeaderLabel, formatSummaryNumeric, getColumnAlign, getPinnedCellValue, getColumnAccessorValue, columnDefMatchesId, } from "./cell-values";
1
+ import { applyGroupAggregate, applyRowPredicate, compileExcelFilter, getAdvancedFilterEngine, normalizeForFilter, createColumnVirtualizer, createCoreRowModel, createExpandedRowModel, createFilteredRowModel, createGroupedRowModel, createTreeRowModel, createSvelteVirtualizer, createSortedRowModel, createSvGrid, getGridCellDomId, sortFns, } from "./index.js";
2
+ import { createRowScrollScaling, resolveMaxDomHeight, } from "./virtualization/scroll-scaling.js";
3
+ import { buildPreMeasureItems } from "./virtualization/virtualizer.js";
4
+ import "./sv-grid-scrollbar.js";
5
+ import { computeColumnStat, formatsNeedingStats, formatNeedsStats, } from "./conditional-formatting.js";
6
+ import { rawToNumber, } from "./SvGrid.helpers.js";
7
+ import { createFeatures } from "./features.js";
8
+ import { createScrollSync, } from "./scroll-sync.js";
9
+ import { createKeyboard, } from "./keyboard-handlers.js";
10
+ import { createSummaries, } from "./summaries.js";
11
+ import { createMenus, } from "./menus.js";
12
+ import { createCellRender, } from "./cell-render.js";
13
+ import { createEditing, } from "./editing.js";
14
+ import { createSelection, } from "./selection.js";
15
+ import { createColumns, } from "./columns.js";
16
+ import { createRowDrag, } from "./row-drag.js";
17
+ import { createAlignedGrids, } from "./aligned-grids.js";
18
+ import { resolveColumnTypes, } from "./column-types.js";
19
+ import { computeColumnGroupMeta, hiddenLeavesForCollapse, } from "./column-groups.js";
20
+ import { resolveColumnId } from "./column-id.js";
21
+ import { buildAutoGroupColumns, insertGroupFooters, paginateGroupedRows } from "./group-display.js";
22
+ import { createGridApi, } from "./build-api.js";
23
+ import { createClipboard, } from "./clipboard.js";
24
+ import { resolveGridMessages } from "./grid-messages.js";
25
+ import { announce } from "./a11y/live-region.js";
26
+ import { filterAnnouncement, selectionAnnouncement, } from "./a11y/grid-announcements.js";
27
+ import { getPivotEngine, hasPivotEngine } from "./pivot-view.svelte.js";
28
+ import { filterOperatorOptions, fallbackOperatorOption, TEXT_OPERATORS, NUMBER_OPERATORS, DATE_OPERATORS, CHECKBOX_OPERATORS, operatorOption, operatorsForColumn, defaultOperatorFor, operatorLabelFor, } from "./filter-operators.js";
29
+ import { isBucketableColumn, buildBuckets, isInBucket, } from "./facet-buckets.js";
30
+ import { getColumnBaseValue, isGroupRow, toolPanelHeaderLabel, formatSummaryNumeric, getColumnAlign, getPinnedCellValue, getColumnAccessorValue, columnDefMatchesId, } from "./cell-values.js";
31
31
  import { untrack } from "svelte";
32
32
  /**
33
33
  * Conservative fallback for the browser's max element height, used during SSR
@@ -399,7 +399,12 @@ export function createSvGridController(rawProps, domIdBase) {
399
399
  const showRowSelectionEffective = $derived(props.showRowSelection ??
400
400
  ((props.selectionMode ?? "both") === "row" ||
401
401
  (props.selectionMode ?? "both") === "both"));
402
- const enableCellSelectionEffective = $derived(props.enableCellSelection ??
402
+ // `selectable` is the shortcut alias, so it wins over the fine-grained prop,
403
+ // which in turn wins over `selectionMode` - the same precedence the other
404
+ // shortcuts use. Unlike them it starts ON (selectionMode defaults to 'both'),
405
+ // so its real work is `selectable={false}`.
406
+ const enableCellSelectionEffective = $derived(props.selectable ??
407
+ props.enableCellSelection ??
403
408
  ((props.selectionMode ?? "both") === "cell" ||
404
409
  (props.selectionMode ?? "both") === "both"));
405
410
  // Internal source-of-truth for data and column defs. Seeded from props and
@@ -1766,7 +1771,7 @@ export function createSvGridController(rawProps, domIdBase) {
1766
1771
  let chartEngine = $state(null);
1767
1772
  $effect(() => {
1768
1773
  if (chartingEnabled && !chartEngine)
1769
- import("./chart").then((m) => (chartEngine = m.rowsToChartSpec));
1774
+ import("./chart.js").then((m) => (chartEngine = m.rowsToChartSpec));
1770
1775
  });
1771
1776
  const chartSpec = $derived.by(() => {
1772
1777
  if (!chartingEnabled || !chartCfg)
@@ -2180,7 +2185,50 @@ export function createSvGridController(rawProps, domIdBase) {
2180
2185
  // before the grid ever appears. Smaller grids compute inline so the
2181
2186
  // footer is correct on the first frame (no flicker).
2182
2187
  const SUMMARY_DEFER_CELL_LIMIT = 50000;
2183
- let summaryByColumn = $state({});
2188
+ /** Deferred summaries for a grid too big to total inline. A grid under the
2189
+ * cell limit is handled by `eagerSummaries` below - synchronously, so the
2190
+ * totals are in the SERVER-rendered footer too. */
2191
+ let deferredSummaries = $state({});
2192
+ /**
2193
+ * The aggregator, handed over once `createSummaries(ctx)` has run - it needs
2194
+ * `ctx`, which cannot exist this early. Held in `$state` so `eagerSummaries`
2195
+ * recomputes when it lands.
2196
+ *
2197
+ * The whole dance is to keep the declaration ABOVE `ctx`: a `$derived`
2198
+ * referenced before its declaration is mis-compiled (the binding is dropped
2199
+ * and the `ctx` getter comes out with an empty body, so the footer read
2200
+ * `undefined` and threw on the first column id).
2201
+ */
2202
+ let summarize = $state(null);
2203
+ /**
2204
+ * Footer totals for a grid small enough to aggregate inline, derived rather
2205
+ * than assigned from an `$effect`.
2206
+ *
2207
+ * Effects never run during SSR, so when the totals lived only in the effect
2208
+ * the server emitted a summary row of EMPTY cells: the numbers appeared only
2209
+ * after hydration (a visible pop-in), and never at all for a reader with
2210
+ * JavaScript off - while the row still took up space and drew its border.
2211
+ * A `$derived` runs on the server too, so the totals ship with the HTML.
2212
+ *
2213
+ * `null` above the cell limit - that case stays on the rAF-deferred effect,
2214
+ * which keeps a huge grid painting before it totals.
2215
+ */
2216
+ const eagerSummaries = $derived.by(() => {
2217
+ if (!summarize)
2218
+ return null;
2219
+ if (!(props.enableRowSummaries ?? true))
2220
+ return null;
2221
+ const rows = allRows;
2222
+ const columns = allColumns;
2223
+ if (rows.length * columns.length > SUMMARY_DEFER_CELL_LIMIT)
2224
+ return null;
2225
+ // `computeSummaries` reads `editedCellValues` through `ctx`, so an inline
2226
+ // edit re-runs this too.
2227
+ return summarize(rows, columns);
2228
+ });
2229
+ /** What the footer renders: the inline totals when the grid is small enough,
2230
+ * otherwise the rAF-deferred ones. */
2231
+ const summaryByColumn = $derived(eagerSummaries ?? deferredSummaries);
2184
2232
  $effect(() => {
2185
2233
  // Re-aggregate whenever the data / columns / edits change. We depend on
2186
2234
  // `allRows` / `allColumns` / `editedCellValues` DIRECTLY - not the
@@ -2194,19 +2242,20 @@ export function createSvGridController(rawProps, domIdBase) {
2194
2242
  const rows = allRows;
2195
2243
  const columns = allColumns;
2196
2244
  if (!(props.enableRowSummaries ?? true)) {
2197
- summaryByColumn = {};
2245
+ deferredSummaries = {};
2198
2246
  return;
2199
2247
  }
2200
2248
  if (rows.length * columns.length <= SUMMARY_DEFER_CELL_LIMIT ||
2201
2249
  typeof requestAnimationFrame === "undefined") {
2202
- summaryByColumn = computeSummaries(rows, columns);
2250
+ // Small enough to total inline - `eagerSummaries` already did, and it
2251
+ // wins in the getter, so there is nothing to recompute here.
2203
2252
  return;
2204
2253
  }
2205
2254
  // Large grid: paint first, total a frame later.
2206
2255
  let cancelled = false;
2207
2256
  const handle = requestAnimationFrame(() => {
2208
2257
  if (!cancelled)
2209
- summaryByColumn = computeSummaries(rows, columns);
2258
+ deferredSummaries = computeSummaries(rows, columns);
2210
2259
  });
2211
2260
  return () => {
2212
2261
  cancelled = true;
@@ -2409,18 +2458,39 @@ export function createSvGridController(rawProps, domIdBase) {
2409
2458
  // width/height stays in sync. Always attached (window resize / parent
2410
2459
  // layout shift / sidebar collapse can change the size whether the
2411
2460
  // consumer passed a numeric or "100%" containerHeight).
2412
- /** True after the first ResizeObserver tick - i.e. once the grid has
2413
- * measured its real container size and `fitColumns` has had a chance
2414
- * to scale the columns to that width. Used to gate the scrollbar
2415
- * visibility: rendering it before this flips paints a horizontal
2416
- * scrollbar for ONE frame (based on the base column widths summing
2417
- * larger than the viewport), then immediately hides it once fit
2418
- * scaling kicks in - visible as a "flashing horizontal scrollbar"
2419
- * every time a demo first loads. */
2461
+ /** True once the grid has measured its real container size and `fitColumns`
2462
+ * has had a chance to scale the columns to that width. Gates the scrollbar
2463
+ * visibility, the scrollbar gutter on a trailing right-aligned column and
2464
+ * the top pager: rendering those before this flips paints a horizontal
2465
+ * scrollbar for ONE frame (based on the base column widths summing larger
2466
+ * than the viewport), then immediately hides it once fit scaling kicks in -
2467
+ * visible as a "flashing horizontal scrollbar" every time a demo first
2468
+ * loads. */
2420
2469
  let hasMeasured = $state(false);
2421
2470
  $effect(() => {
2422
2471
  if (!scrollContainer)
2423
2472
  return;
2473
+ // Measure SYNCHRONOUSLY here, not just from the observer below. Effects run
2474
+ // after the DOM is in place but before the browser paints, so reading the
2475
+ // container now lets the very first painted frame already carry the
2476
+ // scrollbars, the fit-scaled column widths, the 16px gutter on a trailing
2477
+ // right-aligned column and the top pager (which has a `border-top`).
2478
+ // `observeSizeRaf` has to defer its callback by a frame (or the
2479
+ // ResizeObserver re-notifies within one delivery cycle), so relying on it
2480
+ // alone guarantees one painted frame in the unmeasured state - a visible
2481
+ // flash on EVERY mount, and therefore on every navigation in an app that
2482
+ // recreates the grid (e.g. a `{#key}` around it, or a route that remounts).
2483
+ // `untrack` keeps the writes below from making this effect depend on
2484
+ // `viewportVersion` (it would then re-run and re-attach the observer).
2485
+ untrack(() => {
2486
+ // A zero-height container means the grid is not laid out yet (hidden
2487
+ // ancestor, `display: none`); leave it unmeasured and let the observer
2488
+ // flip it when the box becomes real.
2489
+ if (scrollContainer && scrollContainer.clientHeight > 0) {
2490
+ viewportVersion += 1;
2491
+ hasMeasured = true;
2492
+ }
2493
+ });
2424
2494
  return observeSizeRaf(scrollContainer, () => {
2425
2495
  viewportVersion += 1;
2426
2496
  if (!hasMeasured)
@@ -3225,7 +3295,6 @@ export function createSvGridController(rawProps, domIdBase) {
3225
3295
  get computeSummaries() { return computeSummaries; },
3226
3296
  get SUMMARY_DEFER_CELL_LIMIT() { return SUMMARY_DEFER_CELL_LIMIT; },
3227
3297
  get summaryByColumn() { return summaryByColumn; },
3228
- set summaryByColumn(v) { summaryByColumn = v; },
3229
3298
  get hasMeasured() { return hasMeasured; },
3230
3299
  set hasMeasured(v) { hasMeasured = v; },
3231
3300
  get scrollBottomArmed() { return scrollBottomArmed; },
@@ -3379,6 +3448,9 @@ export function createSvGridController(rawProps, domIdBase) {
3379
3448
  const { showTooltipFor, hideTooltip, flushScheduledScrollSync, scheduleScrollSync, onBodyScroll } = createScrollSync(ctx);
3380
3449
  const { onGridKeyDown, onWindowKeydown, onHeaderSortClick } = createKeyboard(ctx);
3381
3450
  const { computeSummaries, hasRenderedColumn } = createSummaries(ctx);
3451
+ // Hand the aggregator to `eagerSummaries` (declared above `ctx`, which this
3452
+ // needs). Plain assignment during init - no effect, so SSR gets it too.
3453
+ summarize = computeSummaries;
3382
3454
  const { updateFilterRow, updateFilterOperator, updateFilterMenuValue, updateFilterMenuValueTo, addFilterToken, removeFilterToken, toggleFilterToken, toggleCheckboxWithKeyboard, isColumnFiltered, closeMenus, openInSuggest, closeInSuggest, openChooseColumns, openColumnMenu, openFilterMenu, openOperatorMenu, sortColumnFromMenu, clearColumnSort, groupByColumnFromMenu, clearGroupingFromMenu, isFacetChecked, toggleFacetValue, setFacetSelection, setFilterTokens, isAllFacetsChecked, toggleAllFacets, clearColumnFilter, changePage, goToPage, setPageSize, openContextMenu, closeContextMenu, contextMenuItems, saveComment, removeComment, closeCommentEditor } = createMenus(ctx);
3383
3455
  const { cellConditionalFormat, computeRowClass, computeCellClass, computeCellTooltip, computeCellValidity, computeCellNote, getColumnEditorOptions, areEditorOptionsLoading, formatListCellValue, formatCellValue, formatPinnedValue, computePinnedCellClass } = createCellRender(ctx);
3384
3456
  const { isCellEditable, isCellEditableAt, getRowColumnValue, getCellDisplayValue, startEditingWithChar, startEditing, stopEditing, startFullRowEdit, setFullRowDraft, commitFullRowEdit, cancelFullRowEdit, saveEditingCell, applyHistoryStep, updateEditingCellValue, onEditorKeyDown, commitAndMoveByTab, focusOnMount, onCellDoubleClick, pasteFromClipboard, onGridPaste } = createEditing(ctx);
package/dist/SvGrid.css CHANGED
@@ -2495,13 +2495,53 @@ select.sv-grid-fr-editor {
2495
2495
  border-radius: 5px;
2496
2496
  background: var(--sg-input-bg, #fff);
2497
2497
  }
2498
- .sv-grid-pagination-pagesize-dd .sv-grid-dropdown,
2499
- .sv-grid-pagination-pagesize-dd .sv-grid-dropdown-trigger {
2498
+ /* The closed page-size trigger is plain markup until the real SvGridDropdown
2499
+ chunk loads on the first click (GridFooter.svelte keeps that component lazy).
2500
+ SvGridDropdown's own trigger rules are scoped to the component, so they never
2501
+ reach the placeholder - it needs the same box here, or the pager shows a
2502
+ stock <button> (UA border + padding, hugging the left) until the first click.
2503
+ Keep these in step with the .sv-grid-dropdown* rules in SvGridDropdown.svelte. */
2504
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown {
2505
+ position: absolute;
2506
+ inset: 0;
2507
+ height: 100%;
2500
2508
  background: transparent;
2501
2509
  border-radius: 5px;
2502
2510
  font-size: 13px;
2503
2511
  color: var(--sg-fg, #0f172a);
2504
2512
  }
2513
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown-trigger {
2514
+ display: flex;
2515
+ align-items: center;
2516
+ gap: 6px;
2517
+ width: 100%;
2518
+ height: 100%;
2519
+ min-height: 28px;
2520
+ padding: 0 8px;
2521
+ border: 0;
2522
+ outline: none;
2523
+ border-radius: 5px;
2524
+ background: transparent;
2525
+ color: var(--sg-fg, #0f172a);
2526
+ font: inherit;
2527
+ font-size: 13px;
2528
+ text-align: start;
2529
+ cursor: pointer;
2530
+ box-sizing: border-box;
2531
+ }
2532
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown-label {
2533
+ flex: 1 1 auto;
2534
+ min-width: 0;
2535
+ overflow: hidden;
2536
+ text-overflow: ellipsis;
2537
+ white-space: nowrap;
2538
+ }
2539
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown-caret {
2540
+ flex: 0 0 auto;
2541
+ font-size: 10px;
2542
+ opacity: 0.7;
2543
+ line-height: 1;
2544
+ }
2505
2545
  .sv-grid-pagination-pagesize-dd:focus-within {
2506
2546
  border-color: var(--sg-accent, #2563eb);
2507
2547
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--sg-accent, #2563eb) 30%, transparent);
@@ -1,5 +1,5 @@
1
- import type { CellEditorType, CellEditorOption } from "./index";
2
- import type { ResolvedCellFormat } from "./conditional-formatting";
1
+ import type { CellEditorType, CellEditorOption } from "./index.js";
2
+ import type { ResolvedCellFormat } from "./conditional-formatting.js";
3
3
  export declare function cfTextStyle(cf: ResolvedCellFormat): string;
4
4
  export declare function fmtStat(n: number): string;
5
5
  export declare function getCellKey(rowId: string, columnId: string): string;
@@ -1,7 +1,7 @@
1
- import { type RowData, type TableFeatures } from "./index";
2
- import "./sv-grid-scrollbar";
1
+ import { type RowData, type TableFeatures } from "./index.js";
2
+ import "./sv-grid-scrollbar.js";
3
3
  import "./SvGrid.css";
4
- import type { Props } from "./SvGrid.types";
4
+ import type { Props } from "./SvGrid.types.js";
5
5
  declare function $$render<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(): {
6
6
  props: Props<TFeatures, TData>;
7
7
  exports: {};
@@ -1,10 +1,10 @@
1
1
  import type { Snippet } from "svelte";
2
- import type { CellEditorType, ColumnDef, RowData, SvGridApi, TableFeatures } from "./index";
3
- import type { ConditionalFormat } from "./conditional-formatting";
4
- import type { GroupDisplayType } from "./group-display";
5
- import type { GridMessages } from "./grid-messages";
6
- import type { GridPivotConfig } from "./pivot-view.svelte";
7
- import type { GridPredicateExpr } from "./filtering/predicate-expr";
2
+ import type { CellEditorType, ColumnDef, RowData, SvGridApi, TableFeatures } from "./index.js";
3
+ import type { ConditionalFormat } from "./conditional-formatting.js";
4
+ import type { GroupDisplayType } from "./group-display.js";
5
+ import type { GridMessages } from "./grid-messages.js";
6
+ import type { GridPivotConfig } from "./pivot-view.svelte.js";
7
+ import type { GridPredicateExpr } from "./filtering/predicate-expr.js";
8
8
  import type { MenuItem } from "./SvMenuList.svelte";
9
9
  /** The calendar views the scheduler can render. {@link SchedulerConfig}. The
10
10
  * `timeline*` views are horizontal: time runs left→right and resources are
@@ -51,7 +51,7 @@ export type SchedulerResource = {
51
51
  }>;
52
52
  }>;
53
53
  };
54
- import type { ChartType, ChartSpec, ChartAnnotation, ChartReferenceLine, ChartValueFormat } from "./chart";
54
+ import type { ChartType, ChartSpec, ChartAnnotation, ChartReferenceLine, ChartValueFormat } from "./chart.js";
55
55
  /** One aggregated bucket returned by a server-side `getAggregate`. */
56
56
  export type ChartAggregateBucket = {
57
57
  category: string;
@@ -984,6 +984,7 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
984
984
  * `sortable` - column sorting (injects `rowSortingFeature`)
985
985
  * `filterable` - column filtering (injects `columnFilteringFeature`)
986
986
  * `editable` - inline cell editing (alias of `enableInlineEditing`)
987
+ * `selectable` - cell selection (alias of `enableCellSelection`)
987
988
  * `groupable` - row grouping controls(alias of `showGroupingControls`,
988
989
  * also injects `columnGroupingFeature`)
989
990
  * `pageable` - pagination footer (alias of `showPagination`)
@@ -994,6 +995,26 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
994
995
  sortable?: boolean;
995
996
  filterable?: boolean;
996
997
  editable?: boolean;
998
+ /**
999
+ * Cell selection - click a cell to select it, drag or shift-click to extend
1000
+ * the selection to a range. Alias of `enableCellSelection`, and the highest
1001
+ * priority of the three inputs that decide it:
1002
+ * `selectable` -> `enableCellSelection` -> `selectionMode`.
1003
+ *
1004
+ * NOTE the asymmetry with its siblings, which are all off until you opt in:
1005
+ * this one is **ON by default**, because `selectionMode` defaults to
1006
+ * `'both'`. It is named here so the capability is discoverable next to the
1007
+ * other shortcuts, and so `selectable={false}` is a one-word way to turn
1008
+ * cell selection off (the longhand being `selectionMode="none"`, which also
1009
+ * removes the row-selection surface).
1010
+ *
1011
+ * This is the CELL surface only. The selection **checkbox column** is the
1012
+ * other half of `selectionMode`, controlled by `showRowSelection` - also on
1013
+ * by default, and it needs no feature import (verified: the column renders
1014
+ * and toggles rows with an empty `features` set). Use `selectionMode` when
1015
+ * you want to move both surfaces at once.
1016
+ */
1017
+ selectable?: boolean;
997
1018
  /**
998
1019
  * Client-side tree data: nest rows into a hierarchy by parent id.
999
1020
  *
@@ -12,8 +12,8 @@
12
12
  * and a static import from anywhere reachable by SvGrid.svelte has silently
13
13
  * defeated a lazy boundary in this codebase before.
14
14
  */
15
- import { type Column, type Row, type RowData, type TableFeatures } from "./index";
16
- import type { SvGridController } from "./SvGrid.controller.svelte";
15
+ import { type Column, type Row, type RowData, type TableFeatures } from "./index.js";
16
+ import type { SvGridController } from "./SvGrid.controller.svelte.js";
17
17
  declare function $$render<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(): {
18
18
  props: {
19
19
  ctrl: SvGridController<TFeatures, TData>;
@@ -6,7 +6,7 @@
6
6
  * focus tooltips, a clickable legend that toggles series, optional data
7
7
  * labels, and an `onSelect` drill hook. No external charting dependency.
8
8
  */
9
- import { type ChartSpec, type ChartSelection } from './chart';
9
+ import { type ChartSpec, type ChartSelection } from './chart.js';
10
10
  type Props = {
11
11
  spec: ChartSpec;
12
12
  /** Show the (clickable) legend. Default true. */
@@ -1,5 +1,5 @@
1
- import type { RowData, TableFeatures } from "./index";
2
- import type { SvGridController } from "./SvGrid.controller.svelte";
1
+ import type { RowData, TableFeatures } from "./index.js";
2
+ import type { SvGridController } from "./SvGrid.controller.svelte.js";
3
3
  declare function $$render<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData>(): {
4
4
  props: {
5
5
  ctrl: SvGridController<TFeatures, TData>;
@@ -1,4 +1,4 @@
1
- import type { ChartViewConfig } from "./SvGrid.types";
1
+ import type { ChartViewConfig } from "./SvGrid.types.js";
2
2
  type $$ComponentProps = {
3
3
  data: ReadonlyArray<Record<string, unknown>>;
4
4
  /** Present for parity with board/scheduler renderers; unused here. */
@@ -17,7 +17,7 @@
17
17
  * Escape - close + onCancel.
18
18
  * Tab - commit and let focus escape.
19
19
  */
20
- import type { CellEditorOption } from './editors/cell-editors';
20
+ import type { CellEditorOption } from './editors/cell-editors.js';
21
21
  type Props = {
22
22
  options: ReadonlyArray<CellEditorOption>;
23
23
  value: unknown;
@@ -1,4 +1,4 @@
1
- export type { GridSelectColumn } from './ui-app.types';
1
+ export type { GridSelectColumn } from './ui-app.types.js';
2
2
  /**
3
3
  * SvGridSelect - a "grid in a dropdown" single-select: the panel shows the
4
4
  * options as a compact multi-column table (header row + optional search), so
@@ -7,9 +7,9 @@ export type { GridSelectColumn } from './ui-app.types';
7
7
  * this component adds the multi-column table. It does NOT embed the full
8
8
  * SvGrid. Emits the chosen row's id. Parity: Smart multicolumn combobox.
9
9
  */
10
- import type { GridSelectColumn } from './ui-app.types';
11
- import { type SvEditorProps } from './editor-contract';
12
- import { type Row } from './grid-select';
10
+ import type { GridSelectColumn } from './ui-app.types.js';
11
+ import { type SvEditorProps } from './editor-contract.js';
12
+ import { type Row } from './grid-select.js';
13
13
  type Props = Pick<SvEditorProps, 'disabled' | 'readonly' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel' | 'loading'> & {
14
14
  columns: ReadonlyArray<GridSelectColumn>;
15
15
  options: ReadonlyArray<Row>;
@@ -1,4 +1,4 @@
1
- import type { ServerDisplayRow } from './server-data-source';
1
+ import type { ServerDisplayRow } from './server-data-source.js';
2
2
  declare function $$render<TData>(): {
3
3
  props: {
4
4
  /** The grid row from `serverGroupRows` (carries the `__group` marker). */
@@ -15,7 +15,7 @@
15
15
  * ```
16
16
  */
17
17
  import type { Snippet } from 'svelte';
18
- import type { Placement } from './positioning';
18
+ import type { Placement } from './positioning.js';
19
19
  type Props = {
20
20
  /** Controlled open state (bindable). */
21
21
  open?: boolean;
@@ -13,8 +13,8 @@
13
13
  * fast thumb-drag" flash); driving the offset in JS removes that async gap.
14
14
  */
15
15
  import { type Snippet } from 'svelte';
16
- import { type ListOption, type RowHeight } from './list-option';
17
- import { type SvEditorProps } from './editor-contract';
16
+ import { type ListOption, type RowHeight } from './list-option.js';
17
+ import { type SvEditorProps } from './editor-contract.js';
18
18
  type Props = SvEditorProps & {
19
19
  options: ReadonlyArray<ListOption>;
20
20
  value?: string | number | ReadonlyArray<string | number> | ReadonlySet<string | number> | null;
@@ -9,7 +9,7 @@
9
9
  * `frame` chrome.
10
10
  */
11
11
  import type { Snippet } from 'svelte';
12
- import { type SvEditorProps } from './editor-contract';
12
+ import { type SvEditorProps } from './editor-contract.js';
13
13
  type Props = SvEditorProps & {
14
14
  value?: string;
15
15
  /** Called with (masked, raw, complete). */
@@ -12,7 +12,7 @@ export type { MenuItem } from './SvMenuList.svelte';
12
12
  * ```
13
13
  */
14
14
  import type { Snippet } from 'svelte';
15
- import { type EditorDir } from './editor-contract';
15
+ import { type EditorDir } from './editor-contract.js';
16
16
  import { type MenuItem } from './SvMenuList.svelte';
17
17
  type $$ComponentProps = {
18
18
  items: ReadonlyArray<MenuItem>;
@@ -1,6 +1,6 @@
1
- export type { MenuItem } from './menu-item';
2
- import { type EditorDir } from './editor-contract';
3
- import type { MenuItem } from './menu-item';
1
+ export type { MenuItem } from './menu-item.js';
2
+ import { type EditorDir } from './editor-contract.js';
3
+ import type { MenuItem } from './menu-item.js';
4
4
  type $$ComponentProps = {
5
5
  items: ReadonlyArray<MenuItem>;
6
6
  /** Close the WHOLE menu (a leaf was chosen, Escape, or outside-click). */
@@ -2,11 +2,11 @@ export type MenubarMenu = {
2
2
  /** Trigger label on the bar. */
3
3
  label: string;
4
4
  /** The dropdown's items (submenus, separators, icons, shortcuts all work). */
5
- items: import('./menu-item').MenuItem[];
5
+ items: import('./menu-item.js').MenuItem[];
6
6
  disabled?: boolean;
7
7
  };
8
- import { type EditorDir } from './editor-contract';
9
- import type { MenuItem } from './menu-item';
8
+ import { type EditorDir } from './editor-contract.js';
9
+ import type { MenuItem } from './menu-item.js';
10
10
  type Props = {
11
11
  menus: ReadonlyArray<MenubarMenu>;
12
12
  onSelect?: (item: MenuItem) => void;
@@ -1,4 +1,4 @@
1
- export type { MultiSelectOption } from './ui-app.types';
1
+ export type { MultiSelectOption } from './ui-app.types.js';
2
2
  /**
3
3
  * SvMultiSelect - a multi-select dropdown: a trigger showing the picked items
4
4
  * as chips (collapsing to "+N"), and a portalled panel with an optional search
@@ -7,8 +7,8 @@ export type { MultiSelectOption } from './ui-app.types';
7
7
  * the multi-select toggle, chips and search UI. Distinct from SvTagsInput
8
8
  * (free-form tags) - this picks from a fixed set.
9
9
  */
10
- import type { MultiSelectOption } from './ui-app.types';
11
- import { type SvEditorProps } from './editor-contract';
10
+ import type { MultiSelectOption } from './ui-app.types.js';
11
+ import { type SvEditorProps } from './editor-contract.js';
12
12
  type Props = Pick<SvEditorProps, 'disabled' | 'readonly' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel' | 'loading'> & {
13
13
  options: ReadonlyArray<MultiSelectOption>;
14
14
  value?: ReadonlyArray<string | number>;
@@ -29,7 +29,7 @@ export type NavModule = {
29
29
  * highlight, arrow-key navigation, and an icon-only `collapsed` rail. A common
30
30
  * app shell primitive (mail folders, workspace nav, settings).
31
31
  */
32
- import { type EditorDir } from './editor-contract';
32
+ import { type EditorDir } from './editor-contract.js';
33
33
  type $$ComponentProps = {
34
34
  sections: ReadonlyArray<NavSection>;
35
35
  value?: string | null;
@@ -11,7 +11,7 @@
11
11
  * right-aligned number), and the spinner + clear live in the trailing slot.
12
12
  */
13
13
  import type { Snippet } from 'svelte';
14
- import { type SvEditorProps } from './editor-contract';
14
+ import { type SvEditorProps } from './editor-contract.js';
15
15
  type Props = SvEditorProps & {
16
16
  value?: number | null;
17
17
  onChange?: (value: number | null) => void;
@@ -1,4 +1,4 @@
1
- import { type SvEditorProps } from './editor-contract';
1
+ import { type SvEditorProps } from './editor-contract.js';
2
2
  type Props = Pick<SvEditorProps, 'disabled' | 'label' | 'hint' | 'error' | 'required' | 'dir' | 'size' | 'id' | 'name' | 'invalid'> & {
3
3
  value?: string;
4
4
  onChange?: (value: string) => void;
@@ -9,7 +9,7 @@
9
9
  * below the field.
10
10
  */
11
11
  import type { Snippet } from 'svelte';
12
- import { type SvEditorProps } from './editor-contract';
12
+ import { type SvEditorProps } from './editor-contract.js';
13
13
  /** User-facing strings for the password input (localizable via `messages`). */
14
14
  type PasswordMessages = {
15
15
  show: string;
@@ -1,5 +1,5 @@
1
- import { type SvEditorProps } from './editor-contract';
2
- import { type PhoneParts } from './createPhoneInput.svelte';
1
+ import { type SvEditorProps } from './editor-contract.js';
2
+ import { type PhoneParts } from './createPhoneInput.svelte.js';
3
3
  /** User-facing strings for the phone input (localizable via `messages`). */
4
4
  type PhoneMessages = {
5
5
  country: string;
@@ -14,7 +14,7 @@
14
14
  * ```
15
15
  */
16
16
  import type { Snippet } from 'svelte';
17
- import type { Placement } from './positioning';
17
+ import type { Placement } from './positioning.js';
18
18
  type Props = {
19
19
  /** Controlled open state (bindable). */
20
20
  open?: boolean;
@@ -15,7 +15,7 @@
15
15
  * ```
16
16
  */
17
17
  import type { Snippet } from 'svelte';
18
- import { type Placement } from './positioning';
18
+ import { type Placement } from './positioning.js';
19
19
  type Props = {
20
20
  /** Controlled open state (bindable). */
21
21
  open?: boolean;
@@ -1,6 +1,6 @@
1
- export type { RadioOption } from './createRadioGroup.svelte';
2
- import { type SvEditorProps } from './editor-contract';
3
- import { type RadioOption } from './createRadioGroup.svelte';
1
+ export type { RadioOption } from './createRadioGroup.svelte.js';
2
+ import { type SvEditorProps } from './editor-contract.js';
3
+ import { type RadioOption } from './createRadioGroup.svelte.js';
4
4
  type Props = SvEditorProps & {
5
5
  options: ReadonlyArray<RadioOption>;
6
6
  value?: string | number | null;
@@ -1,4 +1,4 @@
1
- import { type SvEditorProps } from './editor-contract';
1
+ import { type SvEditorProps } from './editor-contract.js';
2
2
  /** User-facing strings (localizable via `messages`). */
3
3
  type RatingMessages = {
4
4
  label: string;