@svgrid/grid 2.2.16 → 2.2.17

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 (290) hide show
  1. package/README.md +1 -1
  2. package/dist/GridFooter.svelte +12 -11
  3. package/dist/SvAnchor.svelte +65 -0
  4. package/dist/SvAnchor.svelte.d.ts +24 -0
  5. package/dist/SvAspectRatio.svelte +38 -0
  6. package/dist/SvAspectRatio.svelte.d.ts +16 -0
  7. package/dist/SvAutoComplete.svelte +52 -7
  8. package/dist/SvAutoComplete.svelte.d.ts +4 -1
  9. package/dist/SvBlockquote.svelte +43 -0
  10. package/dist/SvBlockquote.svelte.d.ts +16 -0
  11. package/dist/SvCalendar.svelte +33 -2
  12. package/dist/SvCalendar.svelte.d.ts +8 -1
  13. package/dist/SvCheckBox.svelte +6 -2
  14. package/dist/SvCode.svelte +52 -0
  15. package/dist/SvCode.svelte.d.ts +19 -0
  16. package/dist/SvCollapsible.svelte +75 -0
  17. package/dist/SvCollapsible.svelte.d.ts +27 -0
  18. package/dist/SvColorInput.svelte +11 -17
  19. package/dist/SvColorInput.svelte.d.ts +2 -0
  20. package/dist/SvComboBox.svelte +85 -8
  21. package/dist/SvComboBox.svelte.d.ts +14 -0
  22. package/dist/SvCountryInput.svelte +2 -2
  23. package/dist/SvCountryInput.svelte.d.ts +1 -1
  24. package/dist/SvDropDownList.svelte +154 -51
  25. package/dist/SvDropDownList.svelte.d.ts +17 -3
  26. package/dist/SvDurationInput.svelte +59 -41
  27. package/dist/SvDurationInput.svelte.d.ts +18 -0
  28. package/dist/SvField.svelte +203 -12
  29. package/dist/SvField.svelte.d.ts +45 -8
  30. package/dist/SvForm.svelte +195 -21
  31. package/dist/SvForm.svelte.d.ts +23 -0
  32. package/dist/SvGrid.controller.svelte.d.ts +12 -1
  33. package/dist/SvGrid.controller.svelte.js +87 -7
  34. package/dist/SvGrid.svelte +383 -181
  35. package/dist/SvGrid.types.d.ts +123 -2
  36. package/dist/SvGridChartView.svelte +70 -0
  37. package/dist/SvGridChartView.svelte.d.ts +11 -0
  38. package/dist/SvGridDropdown.svelte +9 -2
  39. package/dist/SvGridSelect.svelte +5 -2
  40. package/dist/SvGridSelect.svelte.d.ts +1 -1
  41. package/dist/SvGroup.svelte +41 -0
  42. package/dist/SvGroup.svelte.d.ts +27 -0
  43. package/dist/SvHoverCard.svelte +70 -0
  44. package/dist/SvHoverCard.svelte.d.ts +41 -0
  45. package/dist/SvKbd.svelte +51 -0
  46. package/dist/SvKbd.svelte.d.ts +18 -0
  47. package/dist/SvList.svelte +55 -0
  48. package/dist/SvList.svelte.d.ts +23 -0
  49. package/dist/SvListBox.svelte +166 -77
  50. package/dist/SvListBox.svelte.d.ts +17 -4
  51. package/dist/SvLoadingOverlay.svelte +53 -0
  52. package/dist/SvLoadingOverlay.svelte.d.ts +28 -0
  53. package/dist/SvMark.svelte +36 -0
  54. package/dist/SvMark.svelte.d.ts +14 -0
  55. package/dist/SvMaskedInput.svelte +50 -35
  56. package/dist/SvMaskedInput.svelte.d.ts +17 -2
  57. package/dist/SvMenuList.svelte +32 -3
  58. package/dist/SvMenubar.svelte +200 -0
  59. package/dist/SvMenubar.svelte.d.ts +18 -0
  60. package/dist/SvMultiSelect.svelte +7 -4
  61. package/dist/SvMultiSelect.svelte.d.ts +1 -1
  62. package/dist/SvNumberInput.svelte +79 -42
  63. package/dist/SvNumberInput.svelte.d.ts +25 -0
  64. package/dist/SvOtpInput.svelte +2 -2
  65. package/dist/SvPasswordInput.svelte +51 -31
  66. package/dist/SvPasswordInput.svelte.d.ts +17 -0
  67. package/dist/SvPhoneInput.svelte +39 -28
  68. package/dist/SvPhoneInput.svelte.d.ts +4 -0
  69. package/dist/SvPopconfirm.svelte +79 -0
  70. package/dist/SvPopconfirm.svelte.d.ts +42 -0
  71. package/dist/SvPopover.svelte +87 -29
  72. package/dist/SvPopover.svelte.d.ts +18 -4
  73. package/dist/SvRadioGroup.svelte +5 -1
  74. package/dist/SvResult.svelte +73 -0
  75. package/dist/SvResult.svelte.d.ts +28 -0
  76. package/dist/SvSegmented.svelte +114 -0
  77. package/dist/SvSegmented.svelte.d.ts +29 -0
  78. package/dist/SvSimpleGrid.svelte +41 -0
  79. package/dist/SvSimpleGrid.svelte.d.ts +25 -0
  80. package/dist/SvSlider.svelte +23 -10
  81. package/dist/SvSpinner.svelte +43 -0
  82. package/dist/SvSpinner.svelte.d.ts +20 -0
  83. package/dist/SvStack.svelte +37 -0
  84. package/dist/SvStack.svelte.d.ts +24 -0
  85. package/dist/SvSwitchButton.svelte +6 -1
  86. package/dist/SvTagsInput.svelte +9 -5
  87. package/dist/SvText.svelte +76 -0
  88. package/dist/SvText.svelte.d.ts +31 -0
  89. package/dist/SvTextInput.svelte +75 -43
  90. package/dist/SvTextInput.svelte.d.ts +28 -1
  91. package/dist/SvTimePicker.svelte +32 -2
  92. package/dist/SvTimePicker.svelte.d.ts +8 -9
  93. package/dist/SvTitle.svelte +57 -0
  94. package/dist/SvTitle.svelte.d.ts +24 -0
  95. package/dist/SvToaster.svelte +41 -6
  96. package/dist/SvToggleButton.svelte +4 -1
  97. package/dist/SvTooltip.svelte +68 -34
  98. package/dist/SvTooltip.svelte.d.ts +14 -2
  99. package/dist/SvTree.svelte +81 -21
  100. package/dist/SvTree.svelte.d.ts +3 -2
  101. package/dist/SvTreeSelect.svelte +5 -2
  102. package/dist/SvTreeSelect.svelte.d.ts +1 -1
  103. package/dist/SvVisuallyHidden.svelte +49 -0
  104. package/dist/SvVisuallyHidden.svelte.d.ts +19 -0
  105. package/dist/ai.d.ts +289 -0
  106. package/dist/ai.js +1013 -0
  107. package/dist/board-view.svelte.d.ts +22 -0
  108. package/dist/board-view.svelte.js +13 -0
  109. package/dist/build-api.js +36 -6
  110. package/dist/cdn/GridMenus-0AK9O7qG.js +420 -0
  111. package/dist/cdn/GridMenus-BjUoCXoD.js +416 -0
  112. package/dist/cdn/SvDateTimePicker-CYC7gRER.js +2176 -0
  113. package/dist/cdn/SvDateTimePicker-DtQKd4Ns.js +2198 -0
  114. package/dist/cdn/SvGridChart-BcLCYvw9.js +1195 -0
  115. package/dist/cdn/SvGridChart-BhnFdLd0.js +1203 -0
  116. package/dist/cdn/SvGridChartPanel-Cmx9DHAS.js +561 -0
  117. package/dist/cdn/SvGridChartPanel-DvjwxLvK.js +577 -0
  118. package/dist/cdn/SvGridChartView-B40DTJSX.js +54 -0
  119. package/dist/cdn/SvGridChartView-PwqI4s02.js +53 -0
  120. package/dist/cdn/SvGridDropdown-DjALc_4f.js +255 -0
  121. package/dist/cdn/SvGridDropdown-hpnHvOGt.js +254 -0
  122. package/dist/cdn/chart-T1usDN0o.js +1212 -0
  123. package/dist/cdn/disclose-version-DoD9AFD_.js +2958 -0
  124. package/dist/cdn/export-format-JT5pWVT8.js +561 -0
  125. package/dist/cdn/popover-P-9P2YYn.js +69 -0
  126. package/dist/cdn/rolldown-runtime-Dy4uBu1J.js +11 -0
  127. package/dist/cdn/src-BLhdLmoN.js +25707 -0
  128. package/dist/cdn/src-BwnUVj3T.js +25623 -0
  129. package/dist/cdn/svgrid.js +9 -32897
  130. package/dist/cdn/svgrid.svelte-external.js +9 -30052
  131. package/dist/cell-formatting.d.ts +2 -2
  132. package/dist/cell-render.js +4 -4
  133. package/dist/chart-view.svelte.d.ts +25 -0
  134. package/dist/chart-view.svelte.js +14 -0
  135. package/dist/createCombobox.svelte.d.ts +5 -0
  136. package/dist/createCombobox.svelte.js +21 -5
  137. package/dist/createDropdownList.svelte.d.ts +3 -0
  138. package/dist/createDropdownList.svelte.js +8 -2
  139. package/dist/createForm.svelte.d.ts +18 -0
  140. package/dist/createForm.svelte.js +51 -6
  141. package/dist/createMenu.svelte.js +27 -0
  142. package/dist/createPopoverSelect.svelte.d.ts +3 -0
  143. package/dist/createPopoverSelect.svelte.js +9 -1
  144. package/dist/createSlider.svelte.d.ts +8 -21
  145. package/dist/createSlider.svelte.js +34 -0
  146. package/dist/createTooltip.svelte.d.ts +12 -0
  147. package/dist/createTooltip.svelte.js +72 -9
  148. package/dist/editor-contract.d.ts +15 -0
  149. package/dist/export-provider.d.ts +27 -0
  150. package/dist/export-provider.js +9 -0
  151. package/dist/filter-operators.d.ts +6 -0
  152. package/dist/filter-operators.js +33 -0
  153. package/dist/form-field.d.ts +45 -2
  154. package/dist/grid-messages.d.ts +61 -0
  155. package/dist/grid-messages.js +72 -0
  156. package/dist/group-display.d.ts +62 -0
  157. package/dist/group-display.js +78 -0
  158. package/dist/index.d.ts +36 -4
  159. package/dist/index.js +43 -2
  160. package/dist/js-scroller.svelte.d.ts +35 -0
  161. package/dist/js-scroller.svelte.js +154 -0
  162. package/dist/list-option.d.ts +46 -0
  163. package/dist/list-option.js +53 -0
  164. package/dist/menus.js +25 -11
  165. package/dist/pivot-view.svelte.d.ts +72 -0
  166. package/dist/pivot-view.svelte.js +13 -0
  167. package/dist/positioning.d.ts +111 -0
  168. package/dist/positioning.js +191 -0
  169. package/dist/scheduler-model.d.ts +3 -0
  170. package/dist/scheduler-model.js +22 -5
  171. package/dist/svgrid-wrapper.types.d.ts +18 -0
  172. package/dist/toast-store.svelte.d.ts +54 -0
  173. package/dist/toast-store.svelte.js +65 -15
  174. package/package.json +9 -1
  175. package/src/GridFooter.svelte +12 -11
  176. package/src/SvAnchor.svelte +65 -0
  177. package/src/SvAspectRatio.svelte +38 -0
  178. package/src/SvAutoComplete.svelte +52 -7
  179. package/src/SvBlockquote.svelte +43 -0
  180. package/src/SvCalendar.svelte +33 -2
  181. package/src/SvCalendar.test.ts +15 -0
  182. package/src/SvCheckBox.svelte +6 -2
  183. package/src/SvCode.svelte +52 -0
  184. package/src/SvCollapsible.svelte +75 -0
  185. package/src/SvColorInput.svelte +11 -17
  186. package/src/SvComboBox.svelte +85 -8
  187. package/src/SvCountryInput.svelte +2 -2
  188. package/src/SvDropDownList.svelte +154 -51
  189. package/src/SvDurationInput.svelte +59 -41
  190. package/src/SvField.svelte +203 -12
  191. package/src/SvForm.svelte +195 -21
  192. package/src/SvForm.test.ts +112 -0
  193. package/src/SvGrid.controller.svelte.ts +88 -7
  194. package/src/SvGrid.svelte +383 -181
  195. package/src/SvGrid.types.ts +125 -1
  196. package/src/SvGridChartView.svelte +70 -0
  197. package/src/SvGridDropdown.svelte +9 -2
  198. package/src/SvGridSelect.svelte +5 -2
  199. package/src/SvGroup.svelte +41 -0
  200. package/src/SvHoverCard.svelte +70 -0
  201. package/src/SvKbd.svelte +51 -0
  202. package/src/SvList.svelte +55 -0
  203. package/src/SvListBox.svelte +166 -77
  204. package/src/SvLoadingOverlay.svelte +53 -0
  205. package/src/SvMark.svelte +36 -0
  206. package/src/SvMaskedInput.svelte +50 -35
  207. package/src/SvMenuList.svelte +32 -3
  208. package/src/SvMenubar.svelte +200 -0
  209. package/src/SvMultiSelect.svelte +7 -4
  210. package/src/SvNumberInput.svelte +79 -42
  211. package/src/SvOtpInput.svelte +2 -2
  212. package/src/SvPasswordInput.svelte +51 -31
  213. package/src/SvPhoneInput.svelte +39 -28
  214. package/src/SvPopconfirm.svelte +79 -0
  215. package/src/SvPopover.svelte +87 -29
  216. package/src/SvRadioGroup.svelte +5 -1
  217. package/src/SvResult.svelte +73 -0
  218. package/src/SvSegmented.svelte +114 -0
  219. package/src/SvSimpleGrid.svelte +41 -0
  220. package/src/SvSlider.svelte +23 -10
  221. package/src/SvSpinner.svelte +43 -0
  222. package/src/SvStack.svelte +37 -0
  223. package/src/SvSwitchButton.svelte +6 -1
  224. package/src/SvTagsInput.svelte +9 -5
  225. package/src/SvText.svelte +76 -0
  226. package/src/SvTextInput.svelte +75 -43
  227. package/src/SvTimePicker.svelte +32 -2
  228. package/src/SvTitle.svelte +57 -0
  229. package/src/SvToaster.svelte +41 -6
  230. package/src/SvToaster.test.ts +32 -0
  231. package/src/SvToggleButton.svelte +4 -1
  232. package/src/SvTooltip.svelte +68 -34
  233. package/src/SvTree.svelte +81 -21
  234. package/src/SvTreeSelect.svelte +5 -2
  235. package/src/SvVisuallyHidden.svelte +49 -0
  236. package/src/ai.test.ts +502 -0
  237. package/src/ai.ts +1391 -0
  238. package/src/board-view.svelte.ts +33 -0
  239. package/src/build-api.coverage.test.ts +101 -0
  240. package/src/build-api.ts +43 -18
  241. package/src/builtin-editors.grid.test.ts +1 -1
  242. package/src/cell-formatting.ts +5 -5
  243. package/src/cell-render.ts +4 -4
  244. package/src/chart-view.svelte.ts +36 -0
  245. package/src/createCombobox.svelte.ts +17 -5
  246. package/src/createDropdownList.svelte.ts +8 -2
  247. package/src/createForm.svelte.ts +59 -6
  248. package/src/createMenu.svelte.ts +23 -0
  249. package/src/createPopoverSelect.svelte.ts +8 -1
  250. package/src/createSlider.svelte.ts +20 -0
  251. package/src/createTooltip.svelte.ts +67 -9
  252. package/src/editor-contract.ts +16 -0
  253. package/src/export-provider.ts +40 -0
  254. package/src/filter-operators.ts +37 -0
  255. package/src/form-field.ts +42 -2
  256. package/src/grid-messages.test.ts +24 -0
  257. package/src/grid-messages.ts +137 -0
  258. package/src/group-display.test.ts +77 -0
  259. package/src/group-display.ts +117 -0
  260. package/src/i18n.grid.test.ts +73 -0
  261. package/src/index.ts +91 -2
  262. package/src/js-scroller.svelte.ts +173 -0
  263. package/src/list-option.test.ts +56 -0
  264. package/src/list-option.ts +81 -0
  265. package/src/menus.test.ts +32 -0
  266. package/src/menus.ts +25 -12
  267. package/src/pivot-view.svelte.ts +90 -0
  268. package/src/pivot-view.test.ts +38 -0
  269. package/src/pivot.grid.test.ts +102 -0
  270. package/src/positioning.test.ts +141 -0
  271. package/src/positioning.ts +266 -0
  272. package/src/scheduler-model.test.ts +16 -0
  273. package/src/scheduler-model.ts +24 -5
  274. package/src/svgrid-wrapper.types.ts +23 -0
  275. package/src/svgrid.charting.test.ts +8 -1
  276. package/src/svgrid.comments-autocomplete.test.ts +7 -2
  277. package/src/svgrid.context-menu.test.ts +8 -3
  278. package/src/toast-store.svelte.ts +98 -0
  279. package/src/toast-store.test.ts +62 -1
  280. package/src/ui-breadth.test.ts +138 -0
  281. package/src/ui-buttons.test.ts +39 -0
  282. package/src/ui-inputs.test.ts +2 -2
  283. package/src/ui-range.test.ts +9 -0
  284. package/src/ui-selection.test.ts +36 -0
  285. package/src/ui-tier1.test.ts +1 -1
  286. package/src/virtual.test.ts +20 -6
  287. package/dist/SvGridBoard.svelte +0 -2339
  288. package/dist/SvGridBoard.svelte.d.ts +0 -31
  289. package/src/SvGridBoard.svelte +0 -2339
  290. package/src/board.test.ts +0 -927
@@ -1,6 +1,8 @@
1
1
  import type { Snippet } from "svelte";
2
2
  import type { CellEditorType, ColumnDef, RowData, SvGridApi, TableFeatures } from "./index";
3
3
  import type { ConditionalFormat } from "./conditional-formatting";
4
+ import type { GridMessages } from "./grid-messages";
5
+ import type { GridPivotConfig } from "./pivot-view.svelte";
4
6
  import type { MenuItem } from "./SvMenuList.svelte";
5
7
  /** The calendar views the scheduler can render. {@link SchedulerConfig}. The
6
8
  * `timeline*` views are horizontal: time runs left→right and resources are
@@ -47,7 +49,7 @@ export type SchedulerResource = {
47
49
  }>;
48
50
  }>;
49
51
  };
50
- import type { ChartType, ChartSpec, ChartAnnotation, ChartReferenceLine } from "./chart";
52
+ import type { ChartType, ChartSpec, ChartAnnotation, ChartReferenceLine, ChartValueFormat } from "./chart";
51
53
  /** One aggregated bucket returned by a server-side `getAggregate`. */
52
54
  export type ChartAggregateBucket = {
53
55
  category: string;
@@ -173,7 +175,9 @@ export type ContextMenuTarget<TData extends RowData = RowData> = {
173
175
  /**
174
176
  * A context-menu entry. Either a built-in action key, the `"separator"`
175
177
  * divider, or a custom item. Built-in keys: `"copy" | "cut" | "paste" |
176
- * "clear" | "row_above" | "row_below" | "remove_row" | "remove_col"`.
178
+ * "clear" | "row_above" | "row_below" | "remove_row" | "remove_col" |
179
+ * "chart"`. The `"chart"` item (chart the selected range) is only shown when
180
+ * `charting` is enabled; it is appended to the default menu automatically.
177
181
  */
178
182
  export type ContextMenuItem<TData extends RowData = RowData> = string | {
179
183
  key: string;
@@ -269,6 +273,54 @@ export type BoardCardMoveEvent<TData extends RowData = RowData> = {
269
273
  * of a table. Dragging a card between lanes fires {@link BoardConfig.onCardMove}
270
274
  * where you reassign the `groupBy` field on your own data.
271
275
  */
276
+ /**
277
+ * Chart view of the grid. Setting the `chart` prop on `<SvGrid>` swaps the table
278
+ * for a chart driven by the grid's FILTERED + SORTED rows - so the search box,
279
+ * column filters and sort all flow through to the chart. Unlike the board and
280
+ * scheduler views, the renderer is free: the grid lazy-loads a built-in
281
+ * `SvChart` view unless a host overrides it via `registerChartView`.
282
+ *
283
+ * The config maps directly onto `rowsToChartSpec` - one row field for the
284
+ * category axis, one or more for the value series (or a `series` field to pivot
285
+ * one series per distinct value).
286
+ *
287
+ * ```svelte
288
+ * <SvGrid {data} {columns}
289
+ * chart={{ type: 'bar', category: 'month', value: 'revenue', reduce: 'sum' }} />
290
+ * ```
291
+ */
292
+ export type ChartViewConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
293
+ /** Chart type. Default `'bar'`. */
294
+ type?: ChartType;
295
+ /** Row field for the category (x) axis. */
296
+ category: keyof TData & string;
297
+ /** Row field(s) for the value (y) series. */
298
+ value: (keyof TData & string) | Array<keyof TData & string>;
299
+ /** Pivot dimension: one series per distinct value of this field. */
300
+ series?: keyof TData & string;
301
+ /** Aggregation when several rows share a category. Default `'sum'`. */
302
+ reduce?: "sum" | "avg" | "count";
303
+ /** Stack bar / area series instead of grouping them. */
304
+ stacked?: boolean;
305
+ /** Stack to 100% (implies `stacked`). */
306
+ stacked100?: boolean;
307
+ /** Order categories. Default: insertion order (value-desc when `topN` is set). */
308
+ sort?: "value-desc" | "value-asc" | "category" | "none";
309
+ /** Keep only the top N categories; bucket the rest into "Other". */
310
+ topN?: number;
311
+ /** Palette for series without an explicit colour. */
312
+ palette?: string[];
313
+ /** Number format for the value axis, tooltips and data labels. */
314
+ valueFormat?: ChartValueFormat;
315
+ /** Show the clickable legend. Default `true`. */
316
+ legend?: boolean;
317
+ /** Draw the value on each bar / point / slice. Default `false`. */
318
+ dataLabels?: boolean;
319
+ /** Show the search box above the chart (filters rows first). Default `true`. */
320
+ searchable?: boolean;
321
+ /** Placeholder for the search box. */
322
+ searchPlaceholder?: string;
323
+ };
272
324
  export type BoardConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
273
325
  /** Field whose value buckets each row into a lane. */
274
326
  groupBy: keyof TData & string;
@@ -543,6 +595,12 @@ export type SchedulerException = {
543
595
  end?: string | number | Date;
544
596
  title?: string;
545
597
  allDay?: boolean;
598
+ /**
599
+ * Per-occurrence overrides for ANY other field (e.g. attendees, calendar,
600
+ * color, resource). Merged over the row for just this occurrence, so "This
601
+ * event" can change fields beyond start / end / title / all-day.
602
+ */
603
+ fields?: Record<string, unknown>;
546
604
  };
547
605
  /** How a change to a recurring event should apply. */
548
606
  export type SchedulerEditScope = "occurrence" | "following" | "series";
@@ -875,6 +933,30 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
875
933
  * {@link SchedulerConfig}.
876
934
  */
877
935
  scheduler?: SchedulerConfig<TFeatures, TData>;
936
+ /**
937
+ * Chart view. When set, the grid renders its FILTERED + SORTED rows as a chart
938
+ * instead of a table (search / filters / sort flow through). Unlike board and
939
+ * scheduler, the renderer is free - the grid lazy-loads a built-in `SvChart`
940
+ * view, overridable via `registerChartView`. See {@link ChartViewConfig}.
941
+ */
942
+ chart?: ChartViewConfig<TFeatures, TData>;
943
+ /**
944
+ * Pivot mode. When set (and `pivotMode` is on), the grid renders its rows as a
945
+ * pivot table in place - the same grid, aggregated across `pivot.rows` /
946
+ * `pivot.cols` with nested column headers - instead of the flat table. The
947
+ * pivot ENGINE ships in `@svgrid/enterprise`; call `enablePivot()` (or
948
+ * `installEnterprise(api)`) to register it, otherwise an upsell note shows.
949
+ * See {@link GridPivotConfig}.
950
+ */
951
+ pivot?: GridPivotConfig<TData>;
952
+ /**
953
+ * Whether pivot mode is currently active. Defaults to `true` when `pivot` is
954
+ * set. Bindable so a toolbar toggle can flip between the pivot and the flat
955
+ * table over the same data.
956
+ */
957
+ pivotMode?: boolean;
958
+ /** Fired when the in-grid Pivot toggle flips `pivotMode`. */
959
+ onPivotModeChange?: (on: boolean) => void;
878
960
  /**
879
961
  * Right-click context menu. `true` shows the default item set (copy, cut,
880
962
  * paste, clear, insert row above/below, remove row, remove column). Pass an
@@ -925,6 +1007,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
925
1007
  loadingSkeletonRows?: number;
926
1008
  error?: string | null;
927
1009
  emptyMessage?: string;
1010
+ /**
1011
+ * The single place to localize the grid. One object with two fields:
1012
+ *
1013
+ * - `locale` - BCP-47 tag(s) for the DATA: accent/case-insensitive filter
1014
+ * matching AND every column's number / currency / percent / date formatting
1015
+ * (when the column's own `format.locales` is unset). The default for
1016
+ * `filterLocale` and per-column format locales.
1017
+ * - `text` - overrides for the grid's own UI STRINGS (empty state, tool panel,
1018
+ * pager, status bar, filter operator labels, context-menu items, upsell
1019
+ * notes). Any subset overrides the English defaults; unset keys stay English.
1020
+ *
1021
+ * ```svelte
1022
+ * <SvGrid localization={{ locale: 'fr-FR', text: { noRows: 'Aucune ligne' } }} />
1023
+ * ```
1024
+ *
1025
+ * Omitting it (or any field) is a no-op. See {@link GridMessages}.
1026
+ */
1027
+ localization?: GridLocalization;
928
1028
  showGlobalFilter?: boolean;
929
1029
  showColumnFilters?: boolean;
930
1030
  /**
@@ -1144,6 +1244,16 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1144
1244
  id: string;
1145
1245
  desc: boolean;
1146
1246
  }>) => void;
1247
+ /**
1248
+ * The sort state to start in - `{ id, desc }` entries. Use with `externalSort`
1249
+ * when the initial ordering is decided server-side (e.g. a URL `?sort=` param
1250
+ * read in a SvelteKit `load`), so the header sort indicators match the already-
1251
+ * sorted data on first render. Applied once at mount; user sorting takes over.
1252
+ */
1253
+ initialSorting?: Array<{
1254
+ id: string;
1255
+ desc: boolean;
1256
+ }>;
1147
1257
  /**
1148
1258
  * When `true`, the grid still records column-filter / global-filter /
1149
1259
  * facet state (so the menu UI works and indicators light up) but does
@@ -1428,6 +1538,17 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1428
1538
  */
1429
1539
  filterLocale?: string | ReadonlyArray<string>;
1430
1540
  };
1541
+ /**
1542
+ * The grid's single localization surface (see {@link Props.localization}):
1543
+ * `locale` handles the data (filter matching + number/date formatting) and
1544
+ * `text` handles the UI strings.
1545
+ */
1546
+ export type GridLocalization = {
1547
+ /** BCP-47 tag(s) for filter matching + number / date formatting. */
1548
+ locale?: string | ReadonlyArray<string>;
1549
+ /** Overrides for the grid's own UI strings. */
1550
+ text?: Partial<GridMessages>;
1551
+ };
1431
1552
  export type SelectionPoint = {
1432
1553
  rowIndex: number;
1433
1554
  colIndex: number;
@@ -0,0 +1,70 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvGridChartView - the built-in renderer for the grid's `chart` view. It is a
4
+ * thin adapter: take the grid's filtered + sorted rows, map the ChartViewConfig
5
+ * onto `rowsToChartSpec`, and render the standalone SvChart (SvGridChart) sized
6
+ * to fill the container. This is the piece that makes "chart" a view of the
7
+ * grid, and it stays a thin wrapper precisely because the chart primitive is
8
+ * reusable on its own (unlike the board / scheduler renderers).
9
+ *
10
+ * The grid lazy-loads this by default; a host can replace it via
11
+ * `registerChartView` when it needs a richer renderer.
12
+ */
13
+ import SvGridChart from "./SvGridChart.svelte";
14
+ import { rowsToChartSpec, type ChartSpec } from "./chart";
15
+ import type { ChartViewConfig } from "./SvGrid.types";
16
+
17
+ let {
18
+ data,
19
+ chart,
20
+ }: {
21
+ data: ReadonlyArray<Record<string, unknown>>;
22
+ /** Present for parity with board/scheduler renderers; unused here. */
23
+ columns?: unknown;
24
+ getRowId?: unknown;
25
+ chart: ChartViewConfig;
26
+ } = $props();
27
+
28
+ // Container size -> chart viewBox, so the chart fills the grid area and
29
+ // re-lays out on resize (the same responsive behaviour a table view has).
30
+ let w = $state(0);
31
+ let h = $state(0);
32
+
33
+ const spec = $derived.by<ChartSpec>(() => {
34
+ const s = rowsToChartSpec((data ?? []) as ReadonlyArray<Record<string, unknown>>, {
35
+ type: chart.type ?? "bar",
36
+ category: chart.category,
37
+ value: chart.value,
38
+ series: chart.series,
39
+ reduce: chart.reduce,
40
+ stacked: chart.stacked,
41
+ stacked100: chart.stacked100,
42
+ sort: chart.sort,
43
+ topN: chart.topN,
44
+ palette: chart.palette,
45
+ });
46
+ if (chart.valueFormat) s.valueFormat = chart.valueFormat;
47
+ return s;
48
+ });
49
+ </script>
50
+
51
+ <div class="sv-grid-chart-view" bind:clientWidth={w} bind:clientHeight={h}>
52
+ {#if w > 0 && h > 0}
53
+ <SvGridChart
54
+ {spec}
55
+ width={w}
56
+ height={h}
57
+ legend={chart.legend ?? true}
58
+ dataLabels={chart.dataLabels ?? false}
59
+ />
60
+ {/if}
61
+ </div>
62
+
63
+ <style>
64
+ .sv-grid-chart-view {
65
+ width: 100%;
66
+ height: 100%;
67
+ min-height: 0;
68
+ box-sizing: border-box;
69
+ }
70
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { ChartViewConfig } from "./SvGrid.types";
2
+ type $$ComponentProps = {
3
+ data: ReadonlyArray<Record<string, unknown>>;
4
+ /** Present for parity with board/scheduler renderers; unused here. */
5
+ columns?: unknown;
6
+ getRowId?: unknown;
7
+ chart: ChartViewConfig;
8
+ };
9
+ declare const SvGridChartView: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type SvGridChartView = ReturnType<typeof SvGridChartView>;
11
+ export default SvGridChartView;
@@ -64,6 +64,13 @@
64
64
  return index >= 0 && index < visibleOptions.length ? `${instanceId}-opt-${index}` : undefined
65
65
  }
66
66
 
67
+ // Options that carry a `color` render as full pills (see the option list
68
+ // below), which are taller than a plain text row. The panel-sizing math must
69
+ // reserve that height, otherwise the panel is capped to the plain-row estimate
70
+ // and clips the last option (e.g. a 3-item coloured list). ~40px per chip row
71
+ // vs ~32px for plain text.
72
+ const optionRowHeight = $derived(options.some((o) => o.color) ? 40 : 32)
73
+
67
74
  let searchQuery = $state('')
68
75
  const visibleOptions = $derived(
69
76
  !searchable || !searchQuery.trim()
@@ -153,7 +160,7 @@
153
160
  // Use the smaller of (option count, 10) for the upward-flip math so
154
161
  // a 3-option list doesn't think it needs 320px of headroom.
155
162
  const visibleCount = Math.min(options.length, 10)
156
- const estimatedHeight = visibleCount * 32 + (multiple ? 40 : 0) + 8
163
+ const estimatedHeight = visibleCount * optionRowHeight + (multiple ? 40 : 0) + 8
157
164
  panelRect = anchoredRect(triggerEl.getBoundingClientRect(), {
158
165
  estimatedHeight,
159
166
  // Preserve the original behavior: anchor to the trigger, no clamping.
@@ -381,7 +388,7 @@
381
388
  <!-- Cap to the comfortable 10-row height AND the room the viewport allows,
382
389
  so a panel near the bottom edge scrolls instead of overflowing. -->
383
390
  {@const panelMax = Math.min(
384
- needsScroll ? 10 * 32 + (multiple ? 40 : 0) + 8 : Number.POSITIVE_INFINITY,
391
+ needsScroll ? 10 * optionRowHeight + (multiple ? 40 : 0) + 8 : Number.POSITIVE_INFINITY,
385
392
  panelRect.maxHeight,
386
393
  )}
387
394
  <div
@@ -21,7 +21,7 @@
21
21
 
22
22
  type Props = Pick<
23
23
  SvEditorProps,
24
- 'disabled' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel'
24
+ 'disabled' | 'readonly' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel' | 'loading'
25
25
  > & {
26
26
  columns: ReadonlyArray<GridSelectColumn>
27
27
  options: ReadonlyArray<Row>
@@ -55,6 +55,7 @@
55
55
  debounceMs = 250,
56
56
  loadingText = 'Loading…',
57
57
  disabled = false,
58
+ readonly = false,
58
59
  label,
59
60
  hint,
60
61
  error,
@@ -65,6 +66,7 @@
65
66
  name,
66
67
  dir,
67
68
  ariaLabel,
69
+ loading: loadingProp = false,
68
70
  }: Props = $props()
69
71
 
70
72
  const autoId = nextEditorId('sv-gs')
@@ -106,6 +108,7 @@
106
108
 
107
109
  const gs = createPopoverSelect({
108
110
  itemCount: () => filtered.length,
111
+ readonly: () => readonly,
109
112
  onSelect: (i) => {
110
113
  const r = filtered[i]
111
114
  if (r) { value = r[idField] as string | number; onChange?.(r[idField] as string | number, r) }
@@ -122,7 +125,7 @@
122
125
  })
123
126
  </script>
124
127
 
125
- <SvField id={uid} {label} {hint} {error} {required} {dir}>
128
+ <SvField id={uid} {label} {hint} {error} {required} {dir} loading={loadingProp || loading}>
126
129
  <div class="sv-gs sv-gs--{size}" class:is-disabled={disabled}>
127
130
  <button
128
131
  bind:this={triggerEl}
@@ -10,7 +10,7 @@ export type { GridSelectColumn } from './ui-app.types';
10
10
  import type { GridSelectColumn } from './ui-app.types';
11
11
  import { type SvEditorProps } from './editor-contract';
12
12
  import { type Row } from './grid-select';
13
- type Props = Pick<SvEditorProps, 'disabled' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel'> & {
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>;
16
16
  idField?: string;
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvGroup - a horizontal flex layout primitive: lays children in a row with a
4
+ * consistent `gap`, alignment, and optional wrapping. The row counterpart to
5
+ * SvStack - toolbars, button clusters, inline label + control.
6
+ *
7
+ * ```svelte
8
+ * <SvGroup gap={8} justify="between"><Title /><Actions /></SvGroup>
9
+ * ```
10
+ */
11
+ import type { Snippet } from 'svelte'
12
+
13
+ type Props = {
14
+ /** Gap between children (px, or any CSS length). Default 8. */
15
+ gap?: number | string
16
+ /** Cross-axis alignment. Default `center`. */
17
+ align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline'
18
+ /** Main-axis distribution. */
19
+ justify?: 'start' | 'center' | 'end' | 'between' | 'around'
20
+ /** Allow wrapping to multiple rows. */
21
+ wrap?: boolean
22
+ /** Give every child `flex: 1` so they share the width evenly. */
23
+ grow?: boolean
24
+ as?: string
25
+ children?: Snippet
26
+ }
27
+
28
+ let { gap = 8, align = 'center', justify = 'start', wrap = false, grow = false, as = 'div', children }: Props = $props()
29
+ const g = $derived(typeof gap === 'number' ? `${gap}px` : gap)
30
+ const alignMap = { start: 'flex-start', center: 'center', end: 'flex-end', stretch: 'stretch', baseline: 'baseline' } as const
31
+ const justifyMap = { start: 'flex-start', center: 'center', end: 'flex-end', between: 'space-between', around: 'space-around' } as const
32
+ </script>
33
+
34
+ <svelte:element this={as} class="sv-group" class:is-grow={grow} style:gap={g} style:flex-wrap={wrap ? 'wrap' : 'nowrap'} style:align-items={alignMap[align]} style:justify-content={justifyMap[justify]}>
35
+ {@render children?.()}
36
+ </svelte:element>
37
+
38
+ <style>
39
+ .sv-group { display: flex; flex-direction: row; min-width: 0; }
40
+ .sv-group.is-grow > :global(*) { flex: 1 1 0; min-width: 0; }
41
+ </style>
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SvGroup - a horizontal flex layout primitive: lays children in a row with a
3
+ * consistent `gap`, alignment, and optional wrapping. The row counterpart to
4
+ * SvStack - toolbars, button clusters, inline label + control.
5
+ *
6
+ * ```svelte
7
+ * <SvGroup gap={8} justify="between"><Title /><Actions /></SvGroup>
8
+ * ```
9
+ */
10
+ import type { Snippet } from 'svelte';
11
+ type Props = {
12
+ /** Gap between children (px, or any CSS length). Default 8. */
13
+ gap?: number | string;
14
+ /** Cross-axis alignment. Default `center`. */
15
+ align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';
16
+ /** Main-axis distribution. */
17
+ justify?: 'start' | 'center' | 'end' | 'between' | 'around';
18
+ /** Allow wrapping to multiple rows. */
19
+ wrap?: boolean;
20
+ /** Give every child `flex: 1` so they share the width evenly. */
21
+ grow?: boolean;
22
+ as?: string;
23
+ children?: Snippet;
24
+ };
25
+ declare const SvGroup: import("svelte").Component<Props, {}, "">;
26
+ type SvGroup = ReturnType<typeof SvGroup>;
27
+ export default SvGroup;
@@ -0,0 +1,70 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvHoverCard - a rich preview card that opens when the pointer rests on its
4
+ * anchor (a user chip, a link) and closes shortly after it leaves. Built on the
5
+ * shared positioning engine via SvPopover, so it takes any `placement`, flips
6
+ * and shifts to stay in view, and the card itself is hoverable (you can move the
7
+ * pointer onto it). For keyboard/touch users, prefer SvPopover with a click
8
+ * trigger - a hover card is a pointer affordance.
9
+ *
10
+ * ```svelte
11
+ * <SvHoverCard>
12
+ * {#snippet anchor()}<a href="/u/ada">@ada</a>{/snippet}
13
+ * <strong>Ada Lovelace</strong>
14
+ * <p>Analyst, first programmer.</p>
15
+ * </SvHoverCard>
16
+ * ```
17
+ */
18
+ import type { Snippet } from 'svelte'
19
+ import SvPopover from './SvPopover.svelte'
20
+ import type { Placement } from './positioning'
21
+
22
+ type Props = {
23
+ /** Controlled open state (bindable). */
24
+ open?: boolean
25
+ onOpenChange?: (open: boolean) => void
26
+ /** Preferred placement; flips when there is no room. Default `bottom-start`. */
27
+ placement?: Placement
28
+ /** Delay (ms) before the card opens on hover. Default 250. */
29
+ openDelay?: number
30
+ /** Delay (ms) before it closes after the pointer leaves. Default 180. */
31
+ closeDelay?: number
32
+ /** Show a pointer arrow. Default false (cards usually read cleaner without). */
33
+ arrow?: boolean
34
+ /** Force a minimum card width. */
35
+ minWidth?: number
36
+ ariaLabel?: string
37
+ /** The element the card previews. */
38
+ anchor?: Snippet
39
+ /** Card content. */
40
+ children?: Snippet
41
+ }
42
+
43
+ let {
44
+ open = $bindable(false),
45
+ onOpenChange,
46
+ placement = 'bottom-start',
47
+ openDelay = 250,
48
+ closeDelay = 180,
49
+ arrow = false,
50
+ minWidth = 240,
51
+ ariaLabel,
52
+ anchor,
53
+ children,
54
+ }: Props = $props()
55
+ </script>
56
+
57
+ <SvPopover
58
+ bind:open
59
+ {onOpenChange}
60
+ trigger="hover"
61
+ {placement}
62
+ {openDelay}
63
+ {closeDelay}
64
+ {arrow}
65
+ {minWidth}
66
+ {ariaLabel}
67
+ {anchor}
68
+ >
69
+ {@render children?.()}
70
+ </SvPopover>
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SvHoverCard - a rich preview card that opens when the pointer rests on its
3
+ * anchor (a user chip, a link) and closes shortly after it leaves. Built on the
4
+ * shared positioning engine via SvPopover, so it takes any `placement`, flips
5
+ * and shifts to stay in view, and the card itself is hoverable (you can move the
6
+ * pointer onto it). For keyboard/touch users, prefer SvPopover with a click
7
+ * trigger - a hover card is a pointer affordance.
8
+ *
9
+ * ```svelte
10
+ * <SvHoverCard>
11
+ * {#snippet anchor()}<a href="/u/ada">@ada</a>{/snippet}
12
+ * <strong>Ada Lovelace</strong>
13
+ * <p>Analyst, first programmer.</p>
14
+ * </SvHoverCard>
15
+ * ```
16
+ */
17
+ import type { Snippet } from 'svelte';
18
+ import type { Placement } from './positioning';
19
+ type Props = {
20
+ /** Controlled open state (bindable). */
21
+ open?: boolean;
22
+ onOpenChange?: (open: boolean) => void;
23
+ /** Preferred placement; flips when there is no room. Default `bottom-start`. */
24
+ placement?: Placement;
25
+ /** Delay (ms) before the card opens on hover. Default 250. */
26
+ openDelay?: number;
27
+ /** Delay (ms) before it closes after the pointer leaves. Default 180. */
28
+ closeDelay?: number;
29
+ /** Show a pointer arrow. Default false (cards usually read cleaner without). */
30
+ arrow?: boolean;
31
+ /** Force a minimum card width. */
32
+ minWidth?: number;
33
+ ariaLabel?: string;
34
+ /** The element the card previews. */
35
+ anchor?: Snippet;
36
+ /** Card content. */
37
+ children?: Snippet;
38
+ };
39
+ declare const SvHoverCard: import("svelte").Component<Props, {}, "open">;
40
+ type SvHoverCard = ReturnType<typeof SvHoverCard>;
41
+ export default SvHoverCard;
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvKbd - a keyboard-key hint. Pass `keys` for a combo (joined with the OS
4
+ * separator), or a single `children` label.
5
+ *
6
+ * <SvKbd keys={['Ctrl', 'K']} /> · <SvKbd>Esc</SvKbd>
7
+ */
8
+ import type { Snippet } from 'svelte'
9
+
10
+ type Props = {
11
+ /** Key sequence, rendered as separate caps. */
12
+ keys?: string[]
13
+ /** Separator between keys. */
14
+ separator?: string
15
+ size?: 'sm' | 'md'
16
+ children?: Snippet
17
+ }
18
+
19
+ let { keys, separator = '+', size = 'md', children }: Props = $props()
20
+ </script>
21
+
22
+ {#if keys}
23
+ <span class="sv-kbd-group sv-kbd--{size}">
24
+ {#each keys as k, i}
25
+ {#if i > 0}<span class="sv-kbd__sep" aria-hidden="true">{separator}</span>{/if}
26
+ <kbd class="sv-kbd">{k}</kbd>
27
+ {/each}
28
+ </span>
29
+ {:else}
30
+ <kbd class="sv-kbd sv-kbd--{size}">{@render children?.()}</kbd>
31
+ {/if}
32
+
33
+ <style>
34
+ .sv-kbd-group { display: inline-flex; align-items: center; gap: 3px; }
35
+ .sv-kbd {
36
+ display: inline-block;
37
+ min-width: 1.4em;
38
+ padding: 1px 6px;
39
+ font-family: var(--sg-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
40
+ font-size: 12px;
41
+ line-height: 1.5;
42
+ text-align: center;
43
+ color: var(--sg-fg, #0f172a);
44
+ background: var(--sg-muted-bg, color-mix(in srgb, var(--sg-fg, #0f172a) 7%, var(--sg-bg, #fff)));
45
+ border: 1px solid var(--sg-border, #e2e8f0);
46
+ border-bottom-width: 2px;
47
+ border-radius: 5px;
48
+ }
49
+ .sv-kbd--sm { font-size: 11px; padding: 0 4px; }
50
+ .sv-kbd__sep { color: var(--sg-muted, #64748b); font-size: 11px; }
51
+ </style>
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SvKbd - a keyboard-key hint. Pass `keys` for a combo (joined with the OS
3
+ * separator), or a single `children` label.
4
+ *
5
+ * <SvKbd keys={['Ctrl', 'K']} /> · <SvKbd>Esc</SvKbd>
6
+ */
7
+ import type { Snippet } from 'svelte';
8
+ type Props = {
9
+ /** Key sequence, rendered as separate caps. */
10
+ keys?: string[];
11
+ /** Separator between keys. */
12
+ separator?: string;
13
+ size?: 'sm' | 'md';
14
+ children?: Snippet;
15
+ };
16
+ declare const SvKbd: import("svelte").Component<Props, {}, "">;
17
+ type SvKbd = ReturnType<typeof SvKbd>;
18
+ export default SvKbd;
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvList - a themed ordered / unordered / unstyled list. Pass `items` for the
4
+ * simple case, or a `children` snippet for full control over each `<li>`.
5
+ *
6
+ * <SvList items={['One', 'Two', 'Three']} />
7
+ * <SvList type="ordered" spacing="lg" items={steps} />
8
+ */
9
+ import type { Snippet } from 'svelte'
10
+
11
+ type Props = {
12
+ /** Marker style. `none` drops markers + indentation. */
13
+ type?: 'unordered' | 'ordered' | 'none'
14
+ /** Simple string items (skip the snippet). */
15
+ items?: string[]
16
+ /** Vertical gap between items. */
17
+ spacing?: 'sm' | 'md' | 'lg'
18
+ /** Font size step. */
19
+ size?: 'sm' | 'md' | 'lg'
20
+ /** Custom list content (`<li>` elements). Overrides `items`. */
21
+ children?: Snippet
22
+ }
23
+
24
+ let { type = 'unordered', items, spacing = 'md', size = 'md', children }: Props = $props()
25
+
26
+ const gapMap = { sm: '2px', md: '6px', lg: '10px' } as const
27
+ const sizeMap = { sm: '13px', md: '14px', lg: '16px' } as const
28
+ const tag = $derived(type === 'ordered' ? 'ol' : 'ul')
29
+ </script>
30
+
31
+ <svelte:element
32
+ this={tag}
33
+ class="sv-list sv-list--{type}"
34
+ style:--sv-list-gap={gapMap[spacing]}
35
+ style:font-size={sizeMap[size]}
36
+ >
37
+ {#if children}
38
+ {@render children()}
39
+ {:else if items}
40
+ {#each items as item}<li>{item}</li>{/each}
41
+ {/if}
42
+ </svelte:element>
43
+
44
+ <style>
45
+ .sv-list {
46
+ margin: 0;
47
+ font-family: var(--sg-font, inherit);
48
+ color: var(--sg-fg, #0f172a);
49
+ line-height: 1.5;
50
+ }
51
+ .sv-list--unordered, .sv-list--ordered { padding-left: 1.4em; }
52
+ .sv-list--none { padding-left: 0; list-style: none; }
53
+ .sv-list :global(li) { margin-top: var(--sv-list-gap, 6px); }
54
+ .sv-list :global(li:first-child) { margin-top: 0; }
55
+ </style>