@svgrid/enterprise 3.1.7 → 3.1.9

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 (270) hide show
  1. package/README.md +1 -0
  2. package/dist/SvAlertRuleEditor.svelte +16 -5
  3. package/dist/SvGridAlerts.svelte +8 -0
  4. package/dist/SvGridAlerts.svelte.d.ts +4 -0
  5. package/dist/SvGridBoard.svelte +69 -10
  6. package/dist/SvGridBulkEditDrawer.svelte +13 -5
  7. package/dist/SvGridGallery.svelte +286 -0
  8. package/dist/SvGridGallery.svelte.d.ts +30 -0
  9. package/dist/SvGridScheduler.svelte +33 -11
  10. package/dist/SvGridSelectionBar.svelte +47 -0
  11. package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -0
  12. package/dist/advanced-filter/expr-columns-from-grid.js +11 -7
  13. package/dist/advanced-filter-enable.d.ts +6 -0
  14. package/dist/advanced-filter-enable.js +8 -0
  15. package/dist/alerts/alert-engine.d.ts +7 -0
  16. package/dist/alerts/alert-engine.js +5 -2
  17. package/dist/alerts/condition-editor.d.ts +26 -0
  18. package/dist/alerts/condition-editor.js +17 -0
  19. package/dist/base/index.d.ts +20 -0
  20. package/dist/base/index.js +20 -0
  21. package/dist/bulk-edit.d.ts +11 -0
  22. package/dist/bulk-edit.js +18 -1
  23. package/dist/cdn/svgrid-enterprise.svelte-external.js +11375 -10805
  24. package/dist/designer/assets/GridFooter-Cu8_yBlQ.js +2 -0
  25. package/dist/designer/assets/GridMenus-BUjkkAU2.js +6 -0
  26. package/dist/designer/assets/PinSplitter-BgTpgh1d.css +1 -0
  27. package/dist/designer/assets/PinSplitter-C5AwA1xV.js +1 -0
  28. package/dist/designer/assets/SvGrid.helpers-CIrmIo9U.js +1 -0
  29. package/dist/designer/assets/SvGridCellEditor-CJxThKL_.js +4 -0
  30. package/dist/designer/assets/SvListBox-CS7oUAiX.js +2 -0
  31. package/dist/designer/assets/conditional-formatting-MDWbF8_Y.js +1 -0
  32. package/dist/designer/assets/grid-extension.svelte-BZ7AqyJI.js +1 -0
  33. package/dist/designer/assets/{index-DtBIaQno.js → index-BPU2KNc5.js} +396 -395
  34. package/dist/designer/assets/index-BmvG99kR.css +1 -0
  35. package/dist/designer/assets/sparkline-C-NcnB2i.js +1 -0
  36. package/dist/designer/assets/src-C_U1NKOY.js +58 -0
  37. package/dist/designer/assets/sv-grid-scrollbar-B9N6Wuj0.js +109 -0
  38. package/dist/designer/assets/validate-H5u2HEQh.js +1 -0
  39. package/dist/designer/index.html +11 -7
  40. package/dist/expressions/compile.js +10 -0
  41. package/dist/expressions/evaluate.js +18 -0
  42. package/dist/expressions/expression-types.d.ts +10 -0
  43. package/dist/expressions/kinds.d.ts +28 -0
  44. package/dist/expressions/kinds.js +19 -0
  45. package/dist/expressions/parse.js +9 -1
  46. package/dist/fields/AttachmentCell.svelte +242 -0
  47. package/dist/fields/AttachmentCell.svelte.d.ts +5 -0
  48. package/dist/fields/AttachmentDialog.svelte +357 -0
  49. package/dist/fields/AttachmentDialog.svelte.d.ts +13 -0
  50. package/dist/fields/AttachmentEditor.svelte +41 -0
  51. package/dist/fields/AttachmentEditor.svelte.d.ts +11 -0
  52. package/dist/fields/AttachmentPreview.svelte +72 -0
  53. package/dist/fields/AttachmentPreview.svelte.d.ts +8 -0
  54. package/dist/fields/BarcodeCell.svelte +20 -0
  55. package/dist/fields/BarcodeCell.svelte.d.ts +5 -0
  56. package/dist/fields/BaseAutomations.svelte +558 -0
  57. package/dist/fields/BaseAutomations.svelte.d.ts +18 -0
  58. package/dist/fields/BaseChartView.svelte +47 -0
  59. package/dist/fields/BaseChartView.svelte.d.ts +8 -0
  60. package/dist/fields/BaseTableView.svelte +185 -0
  61. package/dist/fields/BaseTableView.svelte.d.ts +37 -0
  62. package/dist/fields/BaseTabs.svelte +308 -0
  63. package/dist/fields/BaseTabs.svelte.d.ts +21 -0
  64. package/dist/fields/ButtonCell.svelte +47 -0
  65. package/dist/fields/ButtonCell.svelte.d.ts +20 -0
  66. package/dist/fields/CheckboxCell.svelte +46 -0
  67. package/dist/fields/CheckboxCell.svelte.d.ts +14 -0
  68. package/dist/fields/DeleteFieldConfirm.svelte +80 -0
  69. package/dist/fields/DeleteFieldConfirm.svelte.d.ts +8 -0
  70. package/dist/fields/DeleteRecordConfirm.svelte +48 -0
  71. package/dist/fields/DeleteRecordConfirm.svelte.d.ts +9 -0
  72. package/dist/fields/FieldCell.svelte +80 -0
  73. package/dist/fields/FieldCell.svelte.d.ts +9 -0
  74. package/dist/fields/FieldEditor.svelte +321 -0
  75. package/dist/fields/FieldEditor.svelte.d.ts +10 -0
  76. package/dist/fields/FieldInput.svelte +188 -0
  77. package/dist/fields/FieldInput.svelte.d.ts +29 -0
  78. package/dist/fields/FieldsHeaderEnd.svelte +146 -0
  79. package/dist/fields/FieldsHeaderEnd.svelte.d.ts +6 -0
  80. package/dist/fields/FootRowAdder.svelte +8 -0
  81. package/dist/fields/FootRowAdder.svelte.d.ts +6 -0
  82. package/dist/fields/GroupHeader.svelte +127 -0
  83. package/dist/fields/GroupHeader.svelte.d.ts +24 -0
  84. package/dist/fields/LinkCell.svelte +46 -0
  85. package/dist/fields/LinkCell.svelte.d.ts +9 -0
  86. package/dist/fields/LinkPickerEditor.svelte +172 -0
  87. package/dist/fields/LinkPickerEditor.svelte.d.ts +9 -0
  88. package/dist/fields/LinkPreview.svelte +60 -0
  89. package/dist/fields/LinkPreview.svelte.d.ts +7 -0
  90. package/dist/fields/LinkedRecordView.svelte +94 -0
  91. package/dist/fields/LinkedRecordView.svelte.d.ts +9 -0
  92. package/dist/fields/LinkedRecordsCell.svelte +59 -0
  93. package/dist/fields/LinkedRecordsCell.svelte.d.ts +11 -0
  94. package/dist/fields/LongTextEditor.svelte +157 -0
  95. package/dist/fields/LongTextEditor.svelte.d.ts +11 -0
  96. package/dist/fields/NumberEditor.svelte +309 -0
  97. package/dist/fields/NumberEditor.svelte.d.ts +12 -0
  98. package/dist/fields/OptionsEditor.svelte +117 -0
  99. package/dist/fields/OptionsEditor.svelte.d.ts +11 -0
  100. package/dist/fields/PercentCell.svelte +21 -0
  101. package/dist/fields/PercentCell.svelte.d.ts +8 -0
  102. package/dist/fields/PropertyInput.svelte +204 -0
  103. package/dist/fields/PropertyInput.svelte.d.ts +11 -0
  104. package/dist/fields/RatingCell.svelte +75 -0
  105. package/dist/fields/RatingCell.svelte.d.ts +16 -0
  106. package/dist/fields/RatingEditor.svelte +82 -0
  107. package/dist/fields/RatingEditor.svelte.d.ts +9 -0
  108. package/dist/fields/RecordView.svelte +310 -0
  109. package/dist/fields/RecordView.svelte.d.ts +11 -0
  110. package/dist/fields/RichTextCell.svelte +30 -0
  111. package/dist/fields/RichTextCell.svelte.d.ts +5 -0
  112. package/dist/fields/RowAdder.svelte +93 -0
  113. package/dist/fields/RowAdder.svelte.d.ts +7 -0
  114. package/dist/fields/RowHeader.svelte +99 -0
  115. package/dist/fields/RowHeader.svelte.d.ts +11 -0
  116. package/dist/fields/SelectCell.svelte +35 -0
  117. package/dist/fields/SelectCell.svelte.d.ts +15 -0
  118. package/dist/fields/SelectEditor.svelte +350 -0
  119. package/dist/fields/SelectEditor.svelte.d.ts +17 -0
  120. package/dist/fields/SummaryCell.svelte +160 -0
  121. package/dist/fields/SummaryCell.svelte.d.ts +11 -0
  122. package/dist/fields/SvBase.svelte +545 -0
  123. package/dist/fields/SvBase.svelte.d.ts +30 -0
  124. package/dist/fields/SvBaseForm.svelte +295 -0
  125. package/dist/fields/SvBaseForm.svelte.d.ts +22 -0
  126. package/dist/fields/SvBaseViewBar.svelte +644 -0
  127. package/dist/fields/SvBaseViewBar.svelte.d.ts +26 -0
  128. package/dist/fields/UserCell.svelte +39 -0
  129. package/dist/fields/UserCell.svelte.d.ts +9 -0
  130. package/dist/fields/UserFace.svelte +30 -0
  131. package/dist/fields/UserFace.svelte.d.ts +12 -0
  132. package/dist/fields/activity.svelte.d.ts +50 -0
  133. package/dist/fields/activity.svelte.js +110 -0
  134. package/dist/fields/attachments.d.ts +95 -0
  135. package/dist/fields/attachments.js +145 -0
  136. package/dist/fields/automation-outbound.d.ts +46 -0
  137. package/dist/fields/automation-outbound.js +61 -0
  138. package/dist/fields/automation-server.d.ts +53 -0
  139. package/dist/fields/automation-server.js +333 -0
  140. package/dist/fields/automations.svelte.d.ts +208 -0
  141. package/dist/fields/automations.svelte.js +437 -0
  142. package/dist/fields/bar-request.svelte.d.ts +16 -0
  143. package/dist/fields/bar-request.svelte.js +15 -0
  144. package/dist/fields/base-alerts.d.ts +24 -0
  145. package/dist/fields/base-alerts.js +64 -0
  146. package/dist/fields/base-connect.d.ts +82 -0
  147. package/dist/fields/base-connect.js +271 -0
  148. package/dist/fields/base-schema.d.ts +104 -0
  149. package/dist/fields/base-schema.js +266 -0
  150. package/dist/fields/base-sql.d.ts +62 -0
  151. package/dist/fields/base-sql.js +251 -0
  152. package/dist/fields/base-sync.d.ts +142 -0
  153. package/dist/fields/base-sync.js +499 -0
  154. package/dist/fields/base-tables.d.ts +89 -0
  155. package/dist/fields/base-tables.js +349 -0
  156. package/dist/fields/builtin-types.d.ts +13 -0
  157. package/dist/fields/builtin-types.js +773 -0
  158. package/dist/fields/button.d.ts +2 -0
  159. package/dist/fields/button.js +17 -0
  160. package/dist/fields/chart-view.d.ts +35 -0
  161. package/dist/fields/chart-view.js +154 -0
  162. package/dist/fields/column-order.d.ts +6 -0
  163. package/dist/fields/column-order.js +12 -0
  164. package/dist/fields/convert.d.ts +16 -0
  165. package/dist/fields/convert.js +176 -0
  166. package/dist/fields/copy-text.d.ts +13 -0
  167. package/dist/fields/copy-text.js +45 -0
  168. package/dist/fields/editor-request.svelte.d.ts +71 -0
  169. package/dist/fields/editor-request.svelte.js +52 -0
  170. package/dist/fields/field-ops.d.ts +72 -0
  171. package/dist/fields/field-ops.js +334 -0
  172. package/dist/fields/filter-model.d.ts +84 -0
  173. package/dist/fields/filter-model.js +446 -0
  174. package/dist/fields/format.d.ts +109 -0
  175. package/dist/fields/format.js +288 -0
  176. package/dist/fields/formula.d.ts +50 -0
  177. package/dist/fields/formula.js +530 -0
  178. package/dist/fields/grid-access.d.ts +60 -0
  179. package/dist/fields/grid-access.js +120 -0
  180. package/dist/fields/index.d.ts +34 -0
  181. package/dist/fields/index.js +312 -0
  182. package/dist/fields/linked-fields.d.ts +8 -0
  183. package/dist/fields/linked-fields.js +40 -0
  184. package/dist/fields/links.d.ts +10 -0
  185. package/dist/fields/links.js +46 -0
  186. package/dist/fields/name-list.d.ts +16 -0
  187. package/dist/fields/name-list.js +49 -0
  188. package/dist/fields/palette.d.ts +47 -0
  189. package/dist/fields/palette.js +69 -0
  190. package/dist/fields/record-delete.svelte.d.ts +12 -0
  191. package/dist/fields/record-delete.svelte.js +5 -0
  192. package/dist/fields/record-menu.d.ts +9 -0
  193. package/dist/fields/record-menu.js +78 -0
  194. package/dist/fields/registry.svelte.d.ts +176 -0
  195. package/dist/fields/registry.svelte.js +51 -0
  196. package/dist/fields/rich-text.d.ts +23 -0
  197. package/dist/fields/rich-text.js +48 -0
  198. package/dist/fields/row-color-choice.svelte.d.ts +31 -0
  199. package/dist/fields/row-color-choice.svelte.js +25 -0
  200. package/dist/fields/row-colors.d.ts +36 -0
  201. package/dist/fields/row-colors.js +90 -0
  202. package/dist/fields/row-height.d.ts +28 -0
  203. package/dist/fields/row-height.js +50 -0
  204. package/dist/fields/sources.svelte.d.ts +80 -0
  205. package/dist/fields/sources.svelte.js +131 -0
  206. package/dist/fields/summaries.d.ts +18 -0
  207. package/dist/fields/summaries.js +138 -0
  208. package/dist/fields/view-model.d.ts +129 -0
  209. package/dist/fields/view-model.js +492 -0
  210. package/dist/fields/viewbar/ChartPanel.svelte +61 -0
  211. package/dist/fields/viewbar/ChartPanel.svelte.d.ts +9 -0
  212. package/dist/fields/viewbar/ColorPanel.svelte +112 -0
  213. package/dist/fields/viewbar/ColorPanel.svelte.d.ts +9 -0
  214. package/dist/fields/viewbar/ConditionValue.svelte +153 -0
  215. package/dist/fields/viewbar/ConditionValue.svelte.d.ts +15 -0
  216. package/dist/fields/viewbar/FieldIcon.svelte +18 -0
  217. package/dist/fields/viewbar/FieldIcon.svelte.d.ts +9 -0
  218. package/dist/fields/viewbar/FilterPanel.svelte +192 -0
  219. package/dist/fields/viewbar/FilterPanel.svelte.d.ts +13 -0
  220. package/dist/fields/viewbar/GanttPanel.svelte +60 -0
  221. package/dist/fields/viewbar/GanttPanel.svelte.d.ts +10 -0
  222. package/dist/fields/viewbar/HideFieldsPanel.svelte +104 -0
  223. package/dist/fields/viewbar/HideFieldsPanel.svelte.d.ts +7 -0
  224. package/dist/fields/viewbar/SortPanel.svelte +85 -0
  225. package/dist/fields/viewbar/SortPanel.svelte.d.ts +8 -0
  226. package/dist/fields/viewbar/ViewsMenu.svelte +250 -0
  227. package/dist/fields/viewbar/ViewsMenu.svelte.d.ts +15 -0
  228. package/dist/fields/viewbar/panel-focus.d.ts +3 -0
  229. package/dist/fields/viewbar/panel-focus.js +22 -0
  230. package/dist/fields/viewbar/sort-state.d.ts +20 -0
  231. package/dist/fields/viewbar/sort-state.js +24 -0
  232. package/dist/gallery.d.ts +7 -0
  233. package/dist/gallery.js +36 -0
  234. package/dist/gantt/SvGridGantt.svelte +88 -16
  235. package/dist/gantt/gantt-config.d.ts +28 -0
  236. package/dist/index.d.ts +3 -0
  237. package/dist/index.js +6 -0
  238. package/dist/install.js +3 -0
  239. package/dist/license-core.d.ts +3 -3
  240. package/dist/license.js +1 -0
  241. package/dist/node/studio.js +141 -20
  242. package/dist/scheduler-config.d.ts +11 -0
  243. package/dist/sources/introspect-supabase.js +4 -1
  244. package/dist/sources/rest.js +6 -2
  245. package/dist/studio/emit-project.js +25 -6
  246. package/dist/studio/sveltekit3.js +13 -7
  247. package/dist/studio/ui-components.generated.js +94 -2
  248. package/dist/upgrade-prompt.d.ts +1 -1
  249. package/dist/version.d.ts +2 -2
  250. package/dist/version.js +2 -2
  251. package/dist/wc/GridFooter-f5K0aLe_.js +145 -0
  252. package/dist/wc/GridMenus-FtSN_8t9.js +1369 -0
  253. package/dist/wc/PinSplitter-D-qtDhSM.js +132 -0
  254. package/dist/wc/{SvGrid.helpers-zBkDTryR.js → SvGrid.helpers-B2GEKrxS.js} +84 -36
  255. package/dist/wc/{SvGridCellEditor-CzUKEbkI.js → SvGridCellEditor-B_cLJrsp.js} +20 -9
  256. package/dist/wc/conditional-formatting-BXis_oP1.js +189 -0
  257. package/dist/wc/grid-extension.svelte-Bufq4B4C.js +20 -0
  258. package/dist/wc/sv-sheet-element.js +7561 -7618
  259. package/dist/wc/svelte-virtualizer.svelte-ehwOupl-.js +360 -0
  260. package/dist/wc/{validate-43C03DLP.js → validate-BaMO8UPE.js} +1 -1
  261. package/package.json +14 -3
  262. package/dist/designer/assets/GridMenus-CvcASlKv.js +0 -8
  263. package/dist/designer/assets/SvGrid.helpers-DE5mmORW.js +0 -1
  264. package/dist/designer/assets/SvGridCellEditor-C7NWcnNC.js +0 -4
  265. package/dist/designer/assets/SvListBox-BlmmzYcU.js +0 -110
  266. package/dist/designer/assets/index-KmSEY7Lb.css +0 -1
  267. package/dist/designer/assets/src-DqHCqori.js +0 -58
  268. package/dist/designer/assets/validate-B71dE1Cs.js +0 -1
  269. package/dist/wc/GridMenus-fWbBUiRH.js +0 -1088
  270. package/dist/wc/svelte-virtualizer.svelte-Dntdh8Ms.js +0 -581
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The `rowColor` prop: a color per row from a select field's option colors,
3
+ * or from the first matching rule. The grid asks for rendered rows only
4
+ * (registerGridExtension's rowMarkColor / rowMarkLabel), so this never walks
5
+ * the data. Where the color is painted is CSS keyed on the root class.
6
+ */
7
+ import { chosenRowColor } from './row-color-choice.svelte.js';
8
+ import { recordHeightOf } from './row-height.js';
9
+ // value -> color for each field, per column set (a new columns array rebuilds it).
10
+ const optionColors = new WeakMap();
11
+ function colorsFor(ctrl, field) {
12
+ const cols = ctrl.allColumns ?? [];
13
+ let byField = optionColors.get(cols);
14
+ if (!byField) {
15
+ byField = new Map();
16
+ optionColors.set(cols, byField);
17
+ }
18
+ let map = byField.get(field);
19
+ if (!map) {
20
+ map = new Map();
21
+ const def = cols.find((c) => c.columnDef.field === field)?.columnDef;
22
+ const fromProps = def?.fieldProps?.options;
23
+ const options = Array.isArray(fromProps) ? fromProps : Array.isArray(def?.editorOptions) ? def.editorOptions : [];
24
+ for (const o of options) {
25
+ if (o && typeof o === 'object' && o.color)
26
+ map.set(String(o.value), o.color);
27
+ }
28
+ byField.set(field, map);
29
+ }
30
+ return map;
31
+ }
32
+ function fieldValue(row, field) {
33
+ const v = row?.[field];
34
+ // A multiple select colors the row by its first value.
35
+ return Array.isArray(v) ? v[0] : v;
36
+ }
37
+ function matchRule(config, row) {
38
+ return config.rules?.find((r) => {
39
+ try {
40
+ return r.when(row);
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ });
46
+ }
47
+ /** The colors in force: one picked from the column menu, else the `rowColor` prop. */
48
+ export function rowColorOf(ctrl) {
49
+ const chosen = chosenRowColor(ctrl);
50
+ return chosen !== undefined ? chosen : ctrl.props.rowColor;
51
+ }
52
+ export function rowMarkColor(ctrl, row) {
53
+ const config = rowColorOf(ctrl);
54
+ if (!config || row == null)
55
+ return null;
56
+ if (config.field) {
57
+ const v = fieldValue(row, config.field);
58
+ return v == null ? null : (colorsFor(ctrl, config.field).get(String(v)) ?? null);
59
+ }
60
+ return matchRule(config, row)?.color ?? null;
61
+ }
62
+ export function rowMarkLabel(ctrl, row) {
63
+ const config = rowColorOf(ctrl);
64
+ if (!config || row == null)
65
+ return null;
66
+ if (config.field) {
67
+ const v = fieldValue(row, config.field);
68
+ return v == null || v === '' ? null : String(v);
69
+ }
70
+ return matchRule(config, row)?.label ?? null;
71
+ }
72
+ export function rowColorRootClass(ctrl) {
73
+ const config = rowColorOf(ctrl);
74
+ if (!config)
75
+ return null;
76
+ const target = config.target === 'bar' || config.target === 'row' ? config.target : 'header';
77
+ return `sv-fields-rowcolor sv-fields-rowcolor-${target}`;
78
+ }
79
+ /**
80
+ * Taller rows show more, as a table database does: from a 48px row height
81
+ * the root class names how many lines of text fit (2 to 6), and the fields
82
+ * styles wrap text and select pills to that and grow attachment thumbnails.
83
+ */
84
+ export function tallRowClass(ctrl) {
85
+ const h = recordHeightOf(ctrl.props.rowHeight) || 0;
86
+ if (h < 48)
87
+ return null;
88
+ const lines = Math.max(2, Math.min(6, Math.floor((h - 12) / 20)));
89
+ return `sv-fields-tall sv-fields-lines-${lines}`;
90
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Group rows taller than records. A grouped view's header holds the field's
3
+ * name over its value (a select pill, a linked record's chip), which a 40px
4
+ * record row has no room for. The grid takes `rowHeight` as a function of
5
+ * the row index, so while a view is grouped the base sets one that draws
6
+ * group rows at GROUP_ROW_HEIGHT and records at the height picked for them.
7
+ * Everything that reads the row height (the menu, a view saved, tall-row
8
+ * wrapping) reads the record height through `recordHeightOf`.
9
+ */
10
+ export declare const GROUP_ROW_HEIGHT = 52;
11
+ type RowLike = {
12
+ depth?: number;
13
+ getCanExpand?: () => boolean;
14
+ __treeRow?: boolean;
15
+ };
16
+ /** A record row's height, whether the option is a number or the grouped function. */
17
+ export declare function recordHeightOf(value: unknown): number | undefined;
18
+ /**
19
+ * Keep the row height in step with grouping: the function while grouped, the
20
+ * plain record height otherwise. Call it when grouping or the height changes.
21
+ */
22
+ export declare function syncGroupRowHeight(ctrl: {
23
+ allRows?: RowLike[];
24
+ } | undefined, api: {
25
+ getOption: (k: string) => unknown;
26
+ setOption: (k: string, v: unknown) => void;
27
+ } | undefined, grouped: boolean): void;
28
+ export {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Group rows taller than records. A grouped view's header holds the field's
3
+ * name over its value (a select pill, a linked record's chip), which a 40px
4
+ * record row has no room for. The grid takes `rowHeight` as a function of
5
+ * the row index, so while a view is grouped the base sets one that draws
6
+ * group rows at GROUP_ROW_HEIGHT and records at the height picked for them.
7
+ * Everything that reads the row height (the menu, a view saved, tall-row
8
+ * wrapping) reads the record height through `recordHeightOf`.
9
+ */
10
+ export const GROUP_ROW_HEIGHT = 52;
11
+ /** The grid's own record height when none is set (`rowHeight` unset). */
12
+ const GRID_DEFAULT = 30;
13
+ const MARK = Symbol('groupedRowHeight');
14
+ const isGrouped = (v) => typeof v === 'function' && v[MARK] === true;
15
+ /** A record row's height, whether the option is a number or the grouped function. */
16
+ export function recordHeightOf(value) {
17
+ if (typeof value === 'number')
18
+ return value;
19
+ return isGrouped(value) ? value.recordHeight : undefined;
20
+ }
21
+ /** A group row of client grouping (not a tree row, which is a record). */
22
+ function isGroupRow(row) {
23
+ return !!row && !row.__treeRow && typeof row.getCanExpand === 'function' && row.getCanExpand();
24
+ }
25
+ /**
26
+ * Keep the row height in step with grouping: the function while grouped, the
27
+ * plain record height otherwise. Call it when grouping or the height changes.
28
+ */
29
+ export function syncGroupRowHeight(ctrl, api, grouped) {
30
+ if (!ctrl || !api)
31
+ return;
32
+ const now = api.getOption('rowHeight');
33
+ // Another function of the app's own: leave it be.
34
+ if (typeof now === 'function' && !isGrouped(now))
35
+ return;
36
+ const h = recordHeightOf(now);
37
+ if (!grouped) {
38
+ // Back to what it was; unset stays unset.
39
+ if (isGrouped(now))
40
+ api.setOption('rowHeight', h);
41
+ return;
42
+ }
43
+ if (isGrouped(now))
44
+ return;
45
+ const record = h ?? GRID_DEFAULT;
46
+ const fn = ((i) => (isGroupRow(ctrl.allRows?.[i]) ? Math.max(record, GROUP_ROW_HEIGHT) : record));
47
+ fn.recordHeight = h;
48
+ fn[MARK] = true;
49
+ api.setOption('rowHeight', fn);
50
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * What fields need from the app that no column holds: the people a user
3
+ * field can name, who is signed in (created by / last modified by), and the
4
+ * rows of other tables a link field can point at.
5
+ */
6
+ export type FieldUser = {
7
+ id: string;
8
+ name: string;
9
+ email?: string;
10
+ avatarUrl?: string;
11
+ };
12
+ /** The people user fields can choose from. */
13
+ export declare function setFieldUsers(list: ReadonlyArray<FieldUser>): void;
14
+ export declare const getFieldUsers: () => ReadonlyArray<FieldUser>;
15
+ export declare const findFieldUser: (id: unknown) => FieldUser | undefined;
16
+ /** Who is signed in: what "created by" and "last modified by" write. */
17
+ export declare function setCurrentUser(user: FieldUser | null): void;
18
+ export declare const getCurrentUser: () => FieldUser | null;
19
+ /** Another table a link field can point at. */
20
+ export type LinkedTable = {
21
+ id: string;
22
+ name: string;
23
+ /** Its rows. A function is read each time, so the table can change. */
24
+ rows: ReadonlyArray<Record<string, unknown>> | (() => ReadonlyArray<Record<string, unknown>>);
25
+ /** A row's id. Default: its `id` property. */
26
+ getRowId?: (row: Record<string, unknown>) => string;
27
+ /** The field shown for a linked row (its name). */
28
+ primaryField: string;
29
+ /**
30
+ * The fields a lookup or rollup can read: `{ field, header }`, and the
31
+ * field's type when it has one (`fieldType`, `fieldProps`), so a lookup
32
+ * shows a date as a date, an amount with its symbol.
33
+ */
34
+ fields?: ReadonlyArray<{
35
+ field: string;
36
+ header: string;
37
+ fieldType?: string;
38
+ fieldProps?: Record<string, unknown>;
39
+ }>;
40
+ /**
41
+ * Add a record named `name` to this table (the link picker's "+ Create");
42
+ * return the new row, with its id. Without it the picker only links
43
+ * existing records.
44
+ */
45
+ create?: (name: string) => Record<string, unknown> | Promise<Record<string, unknown>>;
46
+ /**
47
+ * Show a record of this table where it lives (another tab of a base): the
48
+ * linked record view then offers "Open in {name}".
49
+ */
50
+ open?: (rowId: string) => void;
51
+ };
52
+ /** A linked table's fields as filled columns (formatter, cell), for showing one of its records. */
53
+ export type LinkedField = {
54
+ id: string;
55
+ header: string;
56
+ def: Record<string, any>;
57
+ };
58
+ /**
59
+ * Add or replace a table that link fields can point at. Registering again
60
+ * with the same id and owner replaces that registration. With the same id
61
+ * and another owner (two bases, or a base and the app), the newest one is
62
+ * shown until it is unregistered. Returns a function that unregisters this
63
+ * registration only.
64
+ */
65
+ export declare function registerLinkedTable(table: LinkedTable, owner?: object): () => void;
66
+ /** Forget a table: the app's registration of `id`, or `owner`'s. */
67
+ export declare function unregisterLinkedTable(id: string, owner?: object): void;
68
+ export declare const getLinkedTable: (id: unknown) => LinkedTable | undefined;
69
+ export declare const listLinkedTables: () => LinkedTable[];
70
+ export declare const rowsOf: (t: LinkedTable) => ReadonlyArray<Record<string, unknown>>;
71
+ export declare const idOf: (t: LinkedTable, row: Record<string, unknown>) => string;
72
+ /** The linked rows a link cell's value names, in its order; unknown ids are skipped. */
73
+ export declare function linkedRows(table: LinkedTable | undefined, value: unknown): Record<string, unknown>[];
74
+ /**
75
+ * The id of the record of `table` a pasted or typed part names: its id, else
76
+ * its name (the primary field), both ignoring case. Undefined when no record has it.
77
+ */
78
+ export declare function resolveLinkId(table: LinkedTable, part: unknown): string | undefined;
79
+ /** The records `parts` name (see resolveLinkId), in order, each once; a part no record has is dropped. */
80
+ export declare function resolveLinkIds(table: LinkedTable, parts: ReadonlyArray<unknown>): string[];
@@ -0,0 +1,131 @@
1
+ /**
2
+ * What fields need from the app that no column holds: the people a user
3
+ * field can name, who is signed in (created by / last modified by), and the
4
+ * rows of other tables a link field can point at.
5
+ */
6
+ let users = $state.raw([]);
7
+ let currentUser = $state.raw(null);
8
+ /** The people user fields can choose from. */
9
+ export function setFieldUsers(list) {
10
+ users = [...list];
11
+ }
12
+ export const getFieldUsers = () => users;
13
+ export const findFieldUser = (id) => id == null ? undefined : users.find((u) => u.id === String(id)) ?? (currentUser?.id === String(id) ? currentUser : undefined);
14
+ /** Who is signed in: what "created by" and "last modified by" write. */
15
+ export function setCurrentUser(user) {
16
+ currentUser = user;
17
+ }
18
+ export const getCurrentUser = () => currentUser;
19
+ let tables = $state.raw({});
20
+ const entries = new Map();
21
+ function publish(id) {
22
+ const top = entries.get(id)?.at(-1)?.table;
23
+ if (top)
24
+ tables = { ...tables, [id]: top };
25
+ else if (id in tables) {
26
+ const { [id]: _gone, ...rest } = tables;
27
+ tables = rest;
28
+ }
29
+ }
30
+ /**
31
+ * Add or replace a table that link fields can point at. Registering again
32
+ * with the same id and owner replaces that registration. With the same id
33
+ * and another owner (two bases, or a base and the app), the newest one is
34
+ * shown until it is unregistered. Returns a function that unregisters this
35
+ * registration only.
36
+ */
37
+ export function registerLinkedTable(table, owner) {
38
+ const list = (entries.get(table.id) ?? []).filter((e) => e.owner !== owner);
39
+ const entry = { table, owner };
40
+ list.push(entry);
41
+ entries.set(table.id, list);
42
+ publish(table.id);
43
+ return () => {
44
+ const now = entries.get(table.id);
45
+ if (!now?.includes(entry))
46
+ return;
47
+ entries.set(table.id, now.filter((e) => e !== entry));
48
+ publish(table.id);
49
+ };
50
+ }
51
+ /** Forget a table: the app's registration of `id`, or `owner`'s. */
52
+ export function unregisterLinkedTable(id, owner) {
53
+ const list = entries.get(id);
54
+ if (!list?.some((e) => e.owner === owner))
55
+ return;
56
+ entries.set(id, list.filter((e) => e.owner !== owner));
57
+ publish(id);
58
+ }
59
+ export const getLinkedTable = (id) => (typeof id === 'string' ? tables[id] : undefined);
60
+ export const listLinkedTables = () => Object.values(tables);
61
+ export const rowsOf = (t) => (typeof t.rows === 'function' ? t.rows() : t.rows);
62
+ export const idOf = (t, row) => (t.getRowId ? t.getRowId(row) : String(row.id ?? ''));
63
+ /** The linked rows a link cell's value names, in its order; unknown ids are skipped. */
64
+ export function linkedRows(table, value) {
65
+ if (!table)
66
+ return [];
67
+ const ids = Array.isArray(value) ? value.map(String) : value == null || value === '' ? [] : [String(value)];
68
+ if (!ids.length)
69
+ return [];
70
+ const byId = indexOf(table);
71
+ return ids.map((id) => byId.get(id)).filter((r) => !!r);
72
+ }
73
+ /**
74
+ * The id of the record of `table` a pasted or typed part names: its id, else
75
+ * its name (the primary field), both ignoring case. Undefined when no record has it.
76
+ */
77
+ export function resolveLinkId(table, part) {
78
+ const q = String(part ?? '').trim().toLowerCase();
79
+ if (!q)
80
+ return undefined;
81
+ const { byId, byName } = lookupOf(table);
82
+ return byId.get(q) ?? byName.get(q);
83
+ }
84
+ /** The records `parts` name (see resolveLinkId), in order, each once; a part no record has is dropped. */
85
+ export function resolveLinkIds(table, parts) {
86
+ const ids = [];
87
+ for (const p of parts) {
88
+ const id = resolveLinkId(table, p);
89
+ if (id != null && !ids.includes(id))
90
+ ids.push(id);
91
+ }
92
+ return ids;
93
+ }
94
+ let lookups = new WeakMap();
95
+ let dropQueued = false;
96
+ function lookupOf(table) {
97
+ const rows = rowsOf(table);
98
+ let l = lookups.get(rows);
99
+ if (!l) {
100
+ l = { byId: new Map(), byName: new Map() };
101
+ for (const r of rows) {
102
+ const id = idOf(table, r);
103
+ const lowId = id.toLowerCase();
104
+ const name = String(r[table.primaryField] ?? '').trim().toLowerCase();
105
+ if (!l.byId.has(lowId))
106
+ l.byId.set(lowId, id);
107
+ if (name && !l.byName.has(name))
108
+ l.byName.set(name, id);
109
+ }
110
+ lookups.set(rows, l);
111
+ if (!dropQueued) {
112
+ dropQueued = true;
113
+ queueMicrotask(() => {
114
+ lookups = new WeakMap();
115
+ dropQueued = false;
116
+ });
117
+ }
118
+ }
119
+ return l;
120
+ }
121
+ // id -> row per rows array: a cell asks for its linked rows on every draw.
122
+ const indexes = new WeakMap();
123
+ function indexOf(table) {
124
+ const rows = rowsOf(table);
125
+ let map = indexes.get(rows);
126
+ if (!map) {
127
+ map = new Map(rows.map((r) => [idOf(table, r), r]));
128
+ indexes.set(rows, map);
129
+ }
130
+ return map;
131
+ }
@@ -0,0 +1,18 @@
1
+ export type SummaryKind = 'none' | 'empty' | 'filled' | 'unique' | 'percentEmpty' | 'percentFilled' | 'sum' | 'avg' | 'median' | 'min' | 'max' | 'range' | 'checked' | 'unchecked' | 'percentChecked' | 'earliest' | 'latest' | 'dateRange';
2
+ type Def = Record<string, any>;
3
+ type Choice = {
4
+ value: SummaryKind;
5
+ label: string;
6
+ };
7
+ /** The footer picker's choices for a field, `none` first. */
8
+ export declare function summaryChoices(def: Def): Choice[];
9
+ export declare const summaryLabel: (kind: SummaryKind) => string;
10
+ /**
11
+ * The footer function for a field (the grid's column `summary`): it gets the
12
+ * rows and returns the text to show, the value formatted as the field
13
+ * formats it ("$4,320", "75%", "October 31, 2026").
14
+ */
15
+ export declare function makeSummary(kind: SummaryKind, def: Def): ((values: number[], rows: unknown[]) => string) | false;
16
+ /** The filled column with its footer summary: the app's own `summary` wins. */
17
+ export declare function withSummary<T extends Def>(filled: T, props: Record<string, unknown>): T;
18
+ export {};
@@ -0,0 +1,138 @@
1
+ /**
2
+ * The summary a field shows in the grid's footer row (the `summary` prop):
3
+ * what the footer's picker offers for each kind of field, and the function
4
+ * that computes it. A field keeps its choice in `fieldProps.summary`; without
5
+ * one it shows nothing until someone picks.
6
+ */
7
+ import { toDate } from './format.js';
8
+ const COMMON = [
9
+ { value: 'empty', label: 'Empty' },
10
+ { value: 'filled', label: 'Filled' },
11
+ { value: 'unique', label: 'Unique' },
12
+ { value: 'percentEmpty', label: 'Percent empty' },
13
+ { value: 'percentFilled', label: 'Percent filled' },
14
+ ];
15
+ const NUMERIC = [
16
+ { value: 'sum', label: 'Sum' },
17
+ { value: 'avg', label: 'Average' },
18
+ { value: 'median', label: 'Median' },
19
+ { value: 'min', label: 'Min' },
20
+ { value: 'max', label: 'Max' },
21
+ { value: 'range', label: 'Range' },
22
+ ];
23
+ const CHECKBOX = [
24
+ { value: 'checked', label: 'Checked' },
25
+ { value: 'unchecked', label: 'Unchecked' },
26
+ { value: 'percentChecked', label: 'Percent checked' },
27
+ ];
28
+ const DATES = [
29
+ { value: 'earliest', label: 'Earliest date' },
30
+ { value: 'latest', label: 'Latest date' },
31
+ { value: 'dateRange', label: 'Date range (days)' },
32
+ ];
33
+ /** What a field's data is, for the summaries it can have. */
34
+ function shapeOf(def) {
35
+ // A registered type that stores true / false says so with cellDataType.
36
+ if (def.fieldType === 'checkbox' || def.cellDataType === 'boolean')
37
+ return 'checkbox';
38
+ // A formula is what it computes.
39
+ const result = def.fieldType === 'formula' ? def.fieldProps?.result : undefined;
40
+ if (result === 'number' || result === 'currency' || result === 'percent')
41
+ return 'number';
42
+ if (result === 'date')
43
+ return 'date';
44
+ if (def.cellDataType === 'number' || def.fieldType === 'currency' || def.fieldType === 'percent')
45
+ return 'number';
46
+ if (def.cellDataType === 'date' || def.cellDataType === 'dateString' || ['createdTime', 'lastModifiedTime'].includes(def.fieldType))
47
+ return 'date';
48
+ return 'other';
49
+ }
50
+ /** The footer picker's choices for a field, `none` first. */
51
+ export function summaryChoices(def) {
52
+ const shape = shapeOf(def);
53
+ return [
54
+ { value: 'none', label: 'None' },
55
+ ...(shape === 'number' ? NUMERIC : shape === 'checkbox' ? CHECKBOX : shape === 'date' ? DATES : []),
56
+ ...COMMON,
57
+ ];
58
+ }
59
+ export const summaryLabel = (kind) => [...NUMERIC, ...CHECKBOX, ...DATES, ...COMMON].find((c) => c.value === kind)?.label ?? '';
60
+ const isEmpty = (v) => v == null || v === '' || (Array.isArray(v) && v.length === 0);
61
+ const pct = (n, of) => (of ? `${Math.round((n / of) * 100)}%` : '0%');
62
+ /**
63
+ * The footer function for a field (the grid's column `summary`): it gets the
64
+ * rows and returns the text to show, the value formatted as the field
65
+ * formats it ("$4,320", "75%", "October 31, 2026").
66
+ */
67
+ export function makeSummary(kind, def) {
68
+ if (kind === 'none')
69
+ return false;
70
+ const read = (row) => typeof def.fieldFn === 'function' ? def.fieldFn(row) : def.field != null ? row?.[def.field] : undefined;
71
+ const format = (v) => {
72
+ const f = def.formatter;
73
+ return f ? String(f({ value: v }) ?? '') : String(v);
74
+ };
75
+ return (_values, rows) => {
76
+ const all = rows.map(read);
77
+ const total = all.length;
78
+ switch (kind) {
79
+ case 'empty':
80
+ return String(all.filter(isEmpty).length);
81
+ case 'filled':
82
+ return String(all.filter((v) => !isEmpty(v)).length);
83
+ case 'percentEmpty':
84
+ return pct(all.filter(isEmpty).length, total);
85
+ case 'percentFilled':
86
+ return pct(all.filter((v) => !isEmpty(v)).length, total);
87
+ case 'unique':
88
+ return String(new Set(all.filter((v) => !isEmpty(v)).map((v) => JSON.stringify(v))).size);
89
+ case 'checked':
90
+ return String(all.filter((v) => v === true).length);
91
+ case 'unchecked':
92
+ return String(all.filter((v) => v !== true).length);
93
+ case 'percentChecked':
94
+ return pct(all.filter((v) => v === true).length, total);
95
+ case 'earliest':
96
+ case 'latest':
97
+ case 'dateRange': {
98
+ const times = all.map((v) => toDate(v)?.getTime()).filter((t) => t != null && Number.isFinite(t));
99
+ if (!times.length)
100
+ return '';
101
+ const lo = Math.min(...times);
102
+ const hi = Math.max(...times);
103
+ if (kind === 'dateRange')
104
+ return `${Math.round((hi - lo) / 86400000)} days`;
105
+ // Back to the field's own value shape: a date-only field holds 'YYYY-MM-DD'.
106
+ const pick = all[all.findIndex((v) => toDate(v)?.getTime() === (kind === 'earliest' ? lo : hi))];
107
+ return format(pick);
108
+ }
109
+ default: {
110
+ const nums = all.map((v) => (typeof v === 'number' ? v : v === '' || v == null ? NaN : Number(v))).filter((n) => Number.isFinite(n));
111
+ if (!nums.length)
112
+ return '';
113
+ const sum = nums.reduce((a, b) => a + b, 0);
114
+ if (kind === 'sum')
115
+ return format(sum);
116
+ if (kind === 'avg')
117
+ return format(sum / nums.length);
118
+ if (kind === 'min')
119
+ return format(Math.min(...nums));
120
+ if (kind === 'max')
121
+ return format(Math.max(...nums));
122
+ if (kind === 'range')
123
+ return format(Math.max(...nums) - Math.min(...nums));
124
+ const sorted = [...nums].sort((a, b) => a - b);
125
+ const mid = sorted.length >> 1;
126
+ return format(sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2);
127
+ }
128
+ }
129
+ };
130
+ }
131
+ /** The filled column with its footer summary: the app's own `summary` wins. */
132
+ export function withSummary(filled, props) {
133
+ if (filled.summary !== undefined)
134
+ return filled;
135
+ const kind = props.summary ?? 'none';
136
+ const known = summaryChoices(filled).some((c) => c.value === kind);
137
+ return { ...filled, summary: known ? makeSummary(kind, filled) : false };
138
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Saved views: a name, a type (grid, Kanban, calendar, Gantt, gallery,
3
+ * form) and what the grid looked like the last time the view was left -
4
+ * sorts, groups, the filter, hidden fields and their order, widths, pinned
5
+ * columns, row height and row colors. Switching views saves the one being
6
+ * left and applies the other through the grid's own state and options.
7
+ */
8
+ import type { RowColorConfig } from '@svgrid/grid';
9
+ import { type FieldCondition, type LinkNames } from './filter-model.js';
10
+ import { type FieldColumn } from './grid-access.js';
11
+ import type { ChartSetting } from './chart-view.js';
12
+ export type FieldViewType = 'grid' | 'kanban' | 'calendar' | 'gantt' | 'gallery' | 'chart' | 'form';
13
+ /** How rows are colored: not, by a single select's option colors, or by conditions in order. */
14
+ export type ColorSetting = {
15
+ mode: 'none';
16
+ } | {
17
+ mode: 'field';
18
+ field: string;
19
+ } | {
20
+ mode: 'conditions';
21
+ rules: Array<{
22
+ color: string;
23
+ condition: FieldCondition;
24
+ }>;
25
+ };
26
+ export type FieldView = {
27
+ id: string;
28
+ name: string;
29
+ type: FieldViewType;
30
+ /** The grid's state when the view was last left (`api.getState()`). */
31
+ state?: Record<string, unknown>;
32
+ rowHeight?: number;
33
+ color?: ColorSetting;
34
+ /** Kanban: the single select or user field the cards stack by. */
35
+ stackBy?: string;
36
+ /** Calendar and Gantt: the date field a record starts on, and the one it ends on. */
37
+ dateField?: string;
38
+ endField?: string;
39
+ /** Gantt: a percent field drawn as each bar's fill, and dragged with its grip. */
40
+ progressField?: string;
41
+ /** Gantt: a link field to the same table naming the records each one depends on. */
42
+ dependencyField?: string;
43
+ /** Gantt: the zoom it was left at. */
44
+ zoom?: string;
45
+ /** Gallery: the attachment field whose first image is the card's cover. */
46
+ coverField?: string;
47
+ /** Chart: its kind, the field it groups by and what it counts or adds up. */
48
+ chart?: ChartSetting;
49
+ /** Form: the fields it asks for, in order (default: every editable field). */
50
+ formFields?: string[];
51
+ /** Form: its title and the line under it. */
52
+ formTitle?: string;
53
+ formDescription?: string;
54
+ /** Form: the fields that must be filled in before it sends. */
55
+ formRequired?: string[];
56
+ /** Form: the submit button's text (default 'Submit'). */
57
+ formSubmitLabel?: string;
58
+ };
59
+ export declare const VIEW_TYPES: ReadonlyArray<{
60
+ type: FieldViewType;
61
+ label: string;
62
+ icon: string;
63
+ }>;
64
+ export declare const viewTypeInfo: (t: FieldViewType) => {
65
+ type: FieldViewType;
66
+ label: string;
67
+ icon: string;
68
+ };
69
+ export declare const newViewId: () => string;
70
+ /** Sort direction labels that fit the field ("1 → 9" for a number, "A → Z" for text). */
71
+ export declare function sortLabels(def: Record<string, any> | undefined): [string, string];
72
+ /** The rows-colored setting as the grid now has it. */
73
+ export declare function colorSettingOf(ctrl: any, saved?: ColorSetting): ColorSetting;
74
+ /**
75
+ * The grid's `rowColor` for a setting, painted where the `rowColor` prop says
76
+ * (`target`). Conditions are tested as the filter tests them: on the value the
77
+ * cell shows (computed for a formula, lookup, rollup or count), and one still
78
+ * missing its value is left out.
79
+ */
80
+ export declare function rowColorFor(ctrl: any, setting: ColorSetting, linkNames?: LinkNames): RowColorConfig | null;
81
+ export declare function applyColor(ctrl: any, setting: ColorSetting, linkNames?: LinkNames): void;
82
+ /** Lanes for a Kanban stacked by a field: an "Uncategorized" lane, then one per option or person. */
83
+ export declare function lanesFor(column: FieldColumn): Array<{
84
+ id: string;
85
+ title: string;
86
+ color?: string;
87
+ hideWhenEmpty?: boolean;
88
+ }>;
89
+ /** Fields a Kanban can stack by. */
90
+ export declare const stackableColumns: (ctrl: any) => FieldColumn[];
91
+ /** Fields a calendar or Gantt can place records by. */
92
+ export declare const dateColumns: (ctrl: any) => FieldColumn[];
93
+ /** Fields a Gantt can draw as progress: a number shown as a percent. */
94
+ export declare const progressColumns: (ctrl: any) => FieldColumn[];
95
+ /** Link fields to the same table: what a record depends on, for a Gantt's arrows. */
96
+ export declare const dependencyColumns: (ctrl: any) => FieldColumn[];
97
+ /**
98
+ * Re-apply a calendar or Gantt view after its settings changed (its fields,
99
+ * progress, links or colors), keeping the grid's state.
100
+ */
101
+ export declare function applyGanttSettings(ctrl: any, api: any, view: FieldView, primaryField?: string): void;
102
+ /** Fields a gallery can take a cover from. */
103
+ export declare const coverColumns: (ctrl: any) => FieldColumn[];
104
+ export declare function boardConfig(ctrl: any, api: any, view: FieldView): Record<string, unknown> | undefined;
105
+ /**
106
+ * The grid's `gallery` for a gallery view: the cover field, the primary field
107
+ * as the title, then the fields the grid shows, in its order. A card opens
108
+ * its record. Built again when fields are hidden or moved.
109
+ */
110
+ export declare function galleryConfig(ctrl: any, api: any, view: FieldView): Record<string, unknown>;
111
+ /**
112
+ * The grid as a field cell on a card sees it: every method and prop of the
113
+ * grid, with the card's width as the column's. A custom field type's cell
114
+ * can open its record or read the grid's props from a card as from a row,
115
+ * and a button runs its automation. A card is read, not edited (the record
116
+ * it opens is), so the grid says editing is off: no stars to click, no drop.
117
+ */
118
+ export declare function cardGrid(ctrl: any): (width: number) => unknown;
119
+ /** Remove a record a view handed over (a copy, perhaps), and report it as the grid's delete does. */
120
+ export declare function deleteRecord(ctrl: any, api: any, row: unknown): void;
121
+ /** A new view: no filter, sorts, groups or hidden fields. */
122
+ export declare const PLAIN_STATE: Record<string, unknown>;
123
+ /** The view as the grid now shows it, to keep when the view is left. */
124
+ export declare function captureView(ctrl: any, api: any, view: FieldView): FieldView;
125
+ /** Show a view: its grid state, row height, colors, and the grid's mode for its type. */
126
+ export declare function applyView(ctrl: any, api: any, view: FieldView, opts?: {
127
+ primaryField?: string;
128
+ linkNames?: LinkNames;
129
+ }): void;