@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
@@ -2054,7 +2054,7 @@ var SOURCE = /\.(ts|js|svelte)$/;
2054
2054
  function toSvelteKit3(files) {
2055
2055
  const paths = new Set(files.map((f) => f.path));
2056
2056
  const adapter = adapterOf(files);
2057
- const envNames = /* @__PURE__ */ new Set();
2057
+ const envNames = /* @__PURE__ */ new Map();
2058
2058
  const out = [];
2059
2059
  for (const file of files) {
2060
2060
  if (file.path === "svelte.config.js") continue;
@@ -2090,7 +2090,7 @@ function toSvelteKit3(files) {
2090
2090
  }
2091
2091
  out.push(file);
2092
2092
  }
2093
- if (envNames.size) out.push(envModule([...envNames].sort()));
2093
+ if (envNames.size) out.push(envModule([...envNames].sort(([a], [b]) => a.localeCompare(b))));
2094
2094
  return out;
2095
2095
  }
2096
2096
  function adapterOf(files) {
@@ -2159,18 +2159,22 @@ function rewriteLibImports(src, paths) {
2159
2159
  /**
2160
2160
  * `import { env } from '$env/dynamic/private'` + `env.X`
2161
2161
  * -> `import { X } from '$app/env/private'` + `X`
2162
- * Every name read is collected so src/env.ts can declare it, which v3 requires.
2162
+ * and the same for `$env/dynamic/public` -> `$app/env/public` (the Supabase
2163
+ * client reads PUBLIC_SUPABASE_* this way). Every name read is collected so
2164
+ * src/env.ts can declare it, which v3 requires; public ones are declared
2165
+ * `public: true`, or `$app/env/public` would not export them.
2163
2166
  */
2164
2167
  function rewriteEnv(src, envNames) {
2165
- if (!/from\s+['"]\$env\/dynamic\/private['"]/.test(src)) return src;
2168
+ const kind = /from\s+['"]\$env\/dynamic\/private['"]/.test(src) ? "private" : /from\s+['"]\$env\/dynamic\/public['"]/.test(src) ? "public" : null;
2169
+ if (!kind) return src;
2166
2170
  const used = /* @__PURE__ */ new Set();
2167
2171
  const body = src.replace(/(?<![.\w])env\.([A-Z_][A-Z0-9_]*)/g, (_m, name) => {
2168
2172
  used.add(name);
2169
2173
  return name;
2170
2174
  });
2171
- for (const n of used) envNames.add(n);
2175
+ for (const n of used) envNames.set(n, kind === "public" || envNames.get(n) === true);
2172
2176
  const names = [...used].sort();
2173
- return body.replace(/import\s*\{\s*env\s*\}\s*from\s*(['"])\$env\/dynamic\/private\1/, names.length ? `import { ${names.join(", ")} } from '$app/env/private'` : "");
2177
+ return body.replace(new RegExp(`import\\s*\\{\\s*env\\s*\\}\\s*from\\s*(['"])\\$env\\/dynamic\\/${kind}\\1`), names.length ? `import { ${names.join(", ")} } from '$app/env/${kind}'` : "");
2174
2178
  }
2175
2179
  /**
2176
2180
  * Types that moved out of `@sveltejs/kit`, and the deprecated `json` helper.
@@ -2198,10 +2202,16 @@ function envModule(names) {
2198
2202
  // SvelteKit 3 reads only the variables declared here. A missing one comes
2199
2203
  // through as '' - every read in this app already falls back on that
2200
2204
  // (a dev default, '?? ""', or an if), so that is the intended behaviour.
2201
- export const variables = defineEnvVars({\n${names.map((n) => ` ${n}: { schema: (input) => input ?? '' },`).join("\n")}\n})\n`
2205
+ export const variables = defineEnvVars({\n${names.map(([n, pub]) => ` ${n}: { ${pub ? "public: true, " : ""}schema: (input) => input ?? '' },`).join("\n")}\n})\n`
2202
2206
  };
2203
2207
  }
2204
2208
  //#endregion
2209
+ //#region src/expressions/kinds.ts
2210
+ var kinds = /* @__PURE__ */ new Map();
2211
+ function getPredicateKind(type) {
2212
+ return kinds.get(type);
2213
+ }
2214
+ //#endregion
2205
2215
  //#region src/expressions/parse.ts
2206
2216
  /** Every column id referenced anywhere in a predicate (deduped, in order). */
2207
2217
  function collectColumnRefs(expr) {
@@ -2225,6 +2235,9 @@ function walkPredicate(expr, out) {
2225
2235
  walkScalar(expr.left, out);
2226
2236
  walkScalar(expr.right, out);
2227
2237
  return;
2238
+ case "ext":
2239
+ for (const c of getPredicateKind(expr.type)?.columns?.(expr.payload) ?? []) out.add(c);
2240
+ return;
2228
2241
  case "const": return;
2229
2242
  }
2230
2243
  }
@@ -8719,6 +8732,13 @@ var GENERATED_UI_SURFACE = {
8719
8732
  "description": "Kanban board mode. When set, the grid renders its rows as cards in horizontal lanes (bucketed by `board.groupBy`) instead of a table. See .",
8720
8733
  "group": "common"
8721
8734
  },
8735
+ {
8736
+ "key": "gallery",
8737
+ "label": "Gallery",
8738
+ "type": "json",
8739
+ "description": "Gallery mode. When set, the grid renders its rows as cards (a cover image, a title, a few fields) instead of a table. See .",
8740
+ "group": "common"
8741
+ },
8722
8742
  {
8723
8743
  "key": "scheduler",
8724
8744
  "label": "Scheduler",
@@ -8768,6 +8788,55 @@ var GENERATED_UI_SURFACE = {
8768
8788
  "description": "Floating bar that appears over the grid while rows are selected, showing the count and the actions that apply to the whole selection - the pattern an issue tracker uses for bulk edit. `true` gives the count and a Clear button. An array is the shorthand for `{ actions }`. Pass to also set `position` (`'bottom'` default, or `'top'`), `maxVisible` and `hideClear`. Omitted / `false` is off. Default **off**. This is chrome that floats over your content, not a gesture: it overlaps a row, and what belongs on it is specific to the app. **The prop and its types are free; the bar itself is an Enterprise feature.** Install `@svgrid/enterprise` and call `enableSelectionBar()` (or `installEnterprise`, which does it for you) to render it - without that the grid shows a short upsell note in its place, the same way the scheduler and board views do.",
8769
8789
  "group": "common"
8770
8790
  },
8791
+ {
8792
+ "key": "rowAdder",
8793
+ "label": "Row Adder",
8794
+ "type": "boolean",
8795
+ "description": "A \"+ Add row\" line under the last row. Clicking it (or Enter on it) appends a row, scrolls to it and starts editing its first editable cell. `true` uses the defaults; pass for the label and the new row's values. **The prop and its types are free; the row adder is drawn by the Enterprise `@svgrid/enterprise/fields` module** (`enableFields()`). Without it the prop does nothing.",
8796
+ "group": "common"
8797
+ },
8798
+ {
8799
+ "key": "rowColor",
8800
+ "label": "Row Color",
8801
+ "type": "json",
8802
+ "description": "Color rows by a status: by a select field (each row takes its option's `color`) or by rules (first match wins). The color shows on the row header by default (a 3px stripe at the start of the row-number cell); `target` moves it to a stripe in the first cell or a tint across the row. The row header also gets the status as its title, so the color is never the only signal. Computed for rendered rows only. **The prop and its types are free; the colors are drawn by the Enterprise `@svgrid/enterprise/fields` module** (`enableFields()`).",
8803
+ "group": "common"
8804
+ },
8805
+ {
8806
+ "key": "columnAdder",
8807
+ "label": "Column Adder",
8808
+ "type": "boolean",
8809
+ "description": "A \"+\" header cell after the last column that opens the field editor: a name, a field type and that type's properties. Creating adds the column and fires `onColumnAdd`; the grid never stores a schema, the app does. `{ types }` limits the types offered. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
8810
+ "group": "common"
8811
+ },
8812
+ {
8813
+ "key": "fieldMenu",
8814
+ "label": "Field Menu",
8815
+ "type": "boolean",
8816
+ "description": "Field actions in each column's menu: Edit field, Insert left / right, Duplicate, Delete, Hide. Edit can change the type; values are converted where they can be and the editor says how many cells would be cleared. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
8817
+ "group": "common"
8818
+ },
8819
+ {
8820
+ "key": "expandRows",
8821
+ "label": "Expand Rows",
8822
+ "type": "boolean",
8823
+ "description": "The row-number cell becomes the row's handle: on hover it shows a checkbox that selects the row and an expand button that opens the row as a record, every field with its label and its editor. With `showRowNumbers`. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
8824
+ "group": "common"
8825
+ },
8826
+ {
8827
+ "key": "pinSplitter",
8828
+ "label": "Pin Splitter",
8829
+ "type": "boolean",
8830
+ "description": "A divider at the edge of the left-pinned columns: drag it right to pin the columns it passes, left to unpin them. It snaps to column edges and keeps the columns where they are on screen; with the keyboard, focus it and use the arrow keys. Its words come from `localization.text` (`pinSplitterLabel`, `pinSplitterHint`, `pinSplitterNone`, `pinSplitterOne`, `pinSplitterMany`). Loaded only when set.",
8831
+ "group": "common"
8832
+ },
8833
+ {
8834
+ "key": "primaryField",
8835
+ "label": "Primary Field",
8836
+ "type": "string",
8837
+ "description": "The table's primary field (a column id or field): always the first column and pinned, never hidden or deleted, and the name of a record (the expanded record's title, a gallery card's title). **Kept by the Enterprise `@svgrid/enterprise/fields` module.**",
8838
+ "group": "common"
8839
+ },
8771
8840
  {
8772
8841
  "key": "features",
8773
8842
  "label": "Features",
@@ -9297,7 +9366,7 @@ var GENERATED_UI_SURFACE = {
9297
9366
  "key": "rowNumberWidth",
9298
9367
  "label": "Row Number Width",
9299
9368
  "type": "number",
9300
- "description": "Width (px) of the row-number column. Defaults to 56, which fits up to \"99,999\"; bump this when the dataset crosses six digits so the largest row number stays fully visible at the bottom of a scroll.",
9369
+ "description": "Width (px) of the row-number column. By default it fits the largest row number: 56px up to four digits, then 9px wider per digit (from `data.length`, or `rowCount` on a server-paged grid). Set it to pin a width, for example when a theme uses a much larger font.",
9301
9370
  "group": "common"
9302
9371
  },
9303
9372
  {
@@ -9526,7 +9595,7 @@ var GENERATED_UI_SURFACE = {
9526
9595
  "key": "rowDragManaged",
9527
9596
  "label": "Row Drag Managed",
9528
9597
  "type": "boolean",
9529
- "description": "Enables managed row dragging. When `true`, every row becomes a drag source (grab cursor + a grip in the row-number cell) and a drop indicator paints between rows during a drag. On drop the grid mutates its own internal data - reordering within the grid, or moving the row across grids that share the same . Defaults to `false`.",
9598
+ "description": "Enables managed row dragging. When `true`, a row is dragged by its row-number cell (a grip shows while it is hovered), or by any cell when row numbers are off, and a drop indicator paints between rows during a drag. On drop the grid mutates its own internal data - reordering within the grid, or moving the row across grids that share the same . Defaults to `false`.",
9530
9599
  "group": "common"
9531
9600
  },
9532
9601
  {
@@ -9558,6 +9627,42 @@ var GENERATED_UI_SURFACE = {
9558
9627
  "prop": "onPivotModeChange",
9559
9628
  "description": "Fired when the in-grid Pivot toggle flips `pivotMode`."
9560
9629
  },
9630
+ {
9631
+ "key": "rowAdd",
9632
+ "label": "Row Add",
9633
+ "prop": "onRowAdd",
9634
+ "description": "Fires after the row adder appended a row, with that row. Persist it here."
9635
+ },
9636
+ {
9637
+ "key": "columnAdd",
9638
+ "label": "Column Add",
9639
+ "prop": "onColumnAdd",
9640
+ "description": "A field was added (column adder, Insert, Duplicate). `columns` is the whole column list after the change, as declared (store it as your `columns`); `data` is set when values were written too."
9641
+ },
9642
+ {
9643
+ "key": "columnChange",
9644
+ "label": "Column Change",
9645
+ "prop": "onColumnChange",
9646
+ "description": "A field was edited. `columns` as in `onColumnAdd`; `data` is set when a type change converted its values."
9647
+ },
9648
+ {
9649
+ "key": "columnRemove",
9650
+ "label": "Column Remove",
9651
+ "prop": "onColumnRemove",
9652
+ "description": "A field was deleted from the column menu (its values stay in the rows). `columns` as in `onColumnAdd`."
9653
+ },
9654
+ {
9655
+ "key": "rowsDelete",
9656
+ "label": "Rows Delete",
9657
+ "prop": "onRowsDelete",
9658
+ "description": "Rows were deleted from the selection bar's Delete (`deleteRows`): the rows and their ids, and the data without them, to store."
9659
+ },
9660
+ {
9661
+ "key": "rowColorChange",
9662
+ "label": "Row Color Change",
9663
+ "prop": "onRowColorChange",
9664
+ "description": "The rows were set to be colored by another field, or no longer colored, from a single select's column menu (\"Color rows by this field\" with `fieldMenu`). Store it and pass it back as `rowColor`."
9665
+ },
9561
9666
  {
9562
9667
  "key": "expandedChange",
9563
9668
  "label": "Expanded Change",
@@ -16341,7 +16446,7 @@ function hasFieldConditions(schema) {
16341
16446
  *
16342
16447
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
16343
16448
  */
16344
- var SVGRID_VERSION = "3.1.7";
16449
+ var SVGRID_VERSION = "3.1.9";
16345
16450
  /**
16346
16451
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16347
16452
  * on 3.1.x while the grid is on 3.0.x.
@@ -16354,7 +16459,7 @@ var SVGRID_VERSION = "3.1.7";
16354
16459
  *
16355
16460
  * `version.test.ts` asserts this matches packages/grid/package.json.
16356
16461
  */
16357
- var GRID_VERSION = "3.0.10";
16462
+ var GRID_VERSION = "3.0.12";
16358
16463
  //#endregion
16359
16464
  //#region src/studio/emit-project.ts
16360
16465
  var has = (blocks, kind) => blocks.some((b) => b.config.kind === kind);
@@ -18441,6 +18546,7 @@ function emitSsrGridScreen(schema, screen, routed, accessEnabled, screenIds, byN
18441
18546
  const facetPanel = screen.blocks.find((b) => b.config.kind === "filter")?.config;
18442
18547
  const pageSize = grid.pageSize && grid.pageSize > 0 ? grid.pageSize : 25;
18443
18548
  const wantsFilter = grid.filterable !== false;
18549
+ const wantsSort = grid.sortable !== false;
18444
18550
  const idField = schema.idField ?? schema.fields.find((f) => f.primaryKey)?.field ?? "id";
18445
18551
  const isFormHidden = (f) => f.hidden === true || typeof f.hidden === "object" && !!f.hidden.form;
18446
18552
  const editable = schema.fields.filter((f) => f.field !== idField && !f.primaryKey && !f.readonly && !f.computed && !f.formula && !isFormHidden(f));
@@ -18738,7 +18844,7 @@ ${wantsFilter ? `
18738
18844
  ${facetForm}
18739
18845
  <SvGrid
18740
18846
  data={data.rows}
18741
- {columns}
18847
+ {columns}${wantsSort ? "\n sortable" : ""}
18742
18848
  externalSort
18743
18849
  initialSorting={data.sort}
18744
18850
  showPagination
@@ -21156,13 +21262,28 @@ function randomSecret(bytes = 32) {
21156
21262
  globalThis.crypto.getRandomValues(buf);
21157
21263
  return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
21158
21264
  }
21265
+ /** The Supabase project the app connects to, when the model holds one: the
21266
+ * project-wide connection, else the first Supabase-bound entity's. */
21267
+ function supabaseConnOf(project) {
21268
+ const hit = [project.supabase, ...Object.values(project.dataSources ?? {}).filter((s) => s.kind === "supabase")].find((c) => c?.url && c?.key);
21269
+ return hit ? {
21270
+ url: hit.url,
21271
+ key: hit.key
21272
+ } : null;
21273
+ }
21159
21274
  /** A ready-to-run, git-ignored `.env`: the `.env.example` template with a real
21160
21275
  * random `SESSION_SECRET` filled in, so the app is secure out of the box (no
21161
- * hardcoded dev secret). Only emitted when the app actually signs sessions. */
21162
- function envDotFile(allSource) {
21276
+ * hardcoded dev secret), and the Supabase URL + anon key the model already
21277
+ * holds, so a Supabase app runs as generated instead of failing on an empty
21278
+ * URL. Only emitted when there is something to fill in. */
21279
+ function envDotFile(allSource, project) {
21163
21280
  const example = envExample(allSource);
21164
- if (!example || !allSource.includes("SESSION_SECRET")) return null;
21165
- return example.replace("SESSION_SECRET=change-me-to-a-long-random-string", `SESSION_SECRET=${randomSecret()}`);
21281
+ if (!example) return null;
21282
+ const supa = allSource.includes("PUBLIC_SUPABASE_URL") ? supabaseConnOf(project) : null;
21283
+ if (!allSource.includes("SESSION_SECRET") && !supa) return null;
21284
+ let env = example.replace("SESSION_SECRET=change-me-to-a-long-random-string", `SESSION_SECRET=${randomSecret()}`);
21285
+ if (supa) env = env.replace(/^PUBLIC_SUPABASE_URL=$/m, `PUBLIC_SUPABASE_URL=${supa.url}`).replace(/^PUBLIC_SUPABASE_ANON_KEY=$/m, `PUBLIC_SUPABASE_ANON_KEY=${supa.key}`);
21286
+ return env;
21166
21287
  }
21167
21288
  /** A `.env.example` listing the env vars the generated code reads, when any. */
21168
21289
  function envExample(allSource) {
@@ -21448,10 +21569,10 @@ function emitStudioAppBundle(project) {
21448
21569
  description: "Environment variables the app reads (copy to .env and fill in).",
21449
21570
  contents: envExample(allSource)
21450
21571
  }] : [],
21451
- ...envDotFile(allSource) ? [{
21572
+ ...envDotFile(allSource, project) ? [{
21452
21573
  path: ".env",
21453
- description: "Local env (git-ignored): a real random SESSION_SECRET is pre-filled so sessions are secure out of the box; fill in the rest.",
21454
- contents: envDotFile(allSource)
21574
+ description: "Local env (git-ignored): a real random SESSION_SECRET and the Supabase connection the design holds are pre-filled, so the app runs as generated; fill in the rest.",
21575
+ contents: envDotFile(allSource, project)
21455
21576
  }] : [],
21456
21577
  {
21457
21578
  path: "src/app.css",
@@ -41317,7 +41438,7 @@ async function listSupabaseTables(url, key, fetchFn = globalThis.fetch) {
41317
41438
  /** Introspect a Supabase/PostgREST table into an EntitySchema, or null. */
41318
41439
  async function introspectSupabaseTable(options) {
41319
41440
  const o = {
41320
- fetch: globalThis.fetch,
41441
+ fetch: (...args) => globalThis.fetch(...args),
41321
41442
  ...options
41322
41443
  };
41323
41444
  const base = o.url.replace(/\/+$/, "");
@@ -108,6 +108,17 @@ export type SchedulerProConfig<TFeatures extends TableFeatures = TableFeatures,
108
108
  hidden?: boolean;
109
109
  }>;
110
110
  calendarField?: keyof TData & string;
111
+ /**
112
+ * Open an event where the app keeps it (a record view) instead of the
113
+ * built-in drawer: a click on the event calls it.
114
+ */
115
+ onEventOpen?: (row: TData) => void;
116
+ /**
117
+ * `false`: events move but keep their length - no edge grips. For records
118
+ * with one date (a start or a due date) there is no end to change.
119
+ * Default `true`.
120
+ */
121
+ resizable?: boolean;
111
122
  /**
112
123
  * External busy intervals to shade on a resource's timeline row - times it is
113
124
  * unavailable that aren't events in this scheduler (its own calendar). Combine
@@ -125,7 +125,10 @@ export async function listSupabaseTables(url, key, fetchFn = globalThis.fetch) {
125
125
  }
126
126
  /** Introspect a Supabase/PostgREST table into an EntitySchema, or null. */
127
127
  export async function introspectSupabaseTable(options) {
128
- const o = { fetch: globalThis.fetch, ...options };
128
+ // A wrapper, not `globalThis.fetch` itself: called as `o.fetch(...)` the
129
+ // browser's fetch gets `o` as its receiver and throws "Illegal invocation",
130
+ // which the paths below catch as "no answer", so no table was ever found.
131
+ const o = { fetch: (...args) => globalThis.fetch(...args), ...options };
129
132
  const base = o.url.replace(/\/+$/, '');
130
133
  const columns = (await viaOpenApi(o, base)) ?? (await viaSample(o, base)) ?? (await viaCsv(o, base));
131
134
  if (!columns || !columns.length)
@@ -110,8 +110,12 @@ export function createRestDataSource(config) {
110
110
  };
111
111
  const send = async (url, init) => {
112
112
  const res = await doFetch(url, init);
113
- if (!res.ok)
114
- throw new Error(`REST ${init?.method ?? 'GET'} ${url} -> ${res.status} ${res.statusText}`);
113
+ if (!res.ok) {
114
+ // The endpoint's own words, when it sent any (`{ error }` or `{ message }`): a
115
+ // validation message reads better to the user than the status line.
116
+ const said = await res.json().then((b) => b?.error ?? b?.message, () => undefined);
117
+ throw new Error(`REST ${init?.method ?? 'GET'} ${url} -> ${res.status} ${res.statusText}${typeof said === 'string' && said ? `: ${said}` : ''}`);
118
+ }
115
119
  const parsed = res.status === 204 ? undefined : await res.json().catch(() => undefined);
116
120
  return { body: parsed, res };
117
121
  };
@@ -2540,6 +2540,9 @@ function emitSsrGridScreen(schema, screen, routed, accessEnabled, screenIds, byN
2540
2540
  const facetPanel = screen.blocks.find((b) => b.config.kind === 'filter')?.config;
2541
2541
  const pageSize = grid.pageSize && grid.pageSize > 0 ? grid.pageSize : 25;
2542
2542
  const wantsFilter = grid.filterable !== false;
2543
+ // externalSort alone only renders the indicator; without `sortable` a header
2544
+ // click never reaches onSortingChange, so the URL (and the load) never sorts.
2545
+ const wantsSort = grid.sortable !== false;
2543
2546
  const idField = schema.idField ?? schema.fields.find((f) => f.primaryKey)?.field ?? 'id';
2544
2547
  const isFormHidden = (f) => f.hidden === true || (typeof f.hidden === 'object' && !!f.hidden.form);
2545
2548
  const editable = schema.fields.filter((f) => f.field !== idField && !f.primaryKey && !f.readonly && !f.computed && !f.formula && !isFormHidden(f));
@@ -2901,7 +2904,7 @@ ${wantsFilter ? `
2901
2904
  ${facetForm}
2902
2905
  <SvGrid
2903
2906
  data={data.rows}
2904
- {columns}
2907
+ {columns}${wantsSort ? '\n sortable' : ''}
2905
2908
  externalSort
2906
2909
  initialSorting={data.sort}
2907
2910
  showPagination
@@ -5171,14 +5174,30 @@ function randomSecret(bytes = 32) {
5171
5174
  globalThis.crypto.getRandomValues(buf);
5172
5175
  return Array.from(buf, (b) => b.toString(16).padStart(2, '0')).join('');
5173
5176
  }
5177
+ /** The Supabase project the app connects to, when the model holds one: the
5178
+ * project-wide connection, else the first Supabase-bound entity's. */
5179
+ function supabaseConnOf(project) {
5180
+ const candidates = [project.supabase, ...Object.values(project.dataSources ?? {}).filter((s) => s.kind === 'supabase')];
5181
+ const hit = candidates.find((c) => c?.url && c?.key);
5182
+ return hit ? { url: hit.url, key: hit.key } : null;
5183
+ }
5174
5184
  /** A ready-to-run, git-ignored `.env`: the `.env.example` template with a real
5175
5185
  * random `SESSION_SECRET` filled in, so the app is secure out of the box (no
5176
- * hardcoded dev secret). Only emitted when the app actually signs sessions. */
5177
- function envDotFile(allSource) {
5186
+ * hardcoded dev secret), and the Supabase URL + anon key the model already
5187
+ * holds, so a Supabase app runs as generated instead of failing on an empty
5188
+ * URL. Only emitted when there is something to fill in. */
5189
+ function envDotFile(allSource, project) {
5178
5190
  const example = envExample(allSource);
5179
- if (!example || !allSource.includes('SESSION_SECRET'))
5191
+ if (!example)
5192
+ return null;
5193
+ const supa = allSource.includes('PUBLIC_SUPABASE_URL') ? supabaseConnOf(project) : null;
5194
+ if (!allSource.includes('SESSION_SECRET') && !supa)
5180
5195
  return null;
5181
- return example.replace('SESSION_SECRET=change-me-to-a-long-random-string', `SESSION_SECRET=${randomSecret()}`);
5196
+ let env = example.replace('SESSION_SECRET=change-me-to-a-long-random-string', `SESSION_SECRET=${randomSecret()}`);
5197
+ // The anon key is public / browser-safe; access is governed by RLS.
5198
+ if (supa)
5199
+ env = env.replace(/^PUBLIC_SUPABASE_URL=$/m, `PUBLIC_SUPABASE_URL=${supa.url}`).replace(/^PUBLIC_SUPABASE_ANON_KEY=$/m, `PUBLIC_SUPABASE_ANON_KEY=${supa.key}`);
5200
+ return env;
5182
5201
  }
5183
5202
  /** A `.env.example` listing the env vars the generated code reads, when any. */
5184
5203
  function envExample(allSource) {
@@ -5480,7 +5499,7 @@ export function emitStudioAppBundle(project) {
5480
5499
  rootLayoutModule(project),
5481
5500
  ...SCAFFOLD_STATIC,
5482
5501
  ...(envExample(allSource) ? [{ path: '.env.example', description: 'Environment variables the app reads (copy to .env and fill in).', contents: envExample(allSource) }] : []),
5483
- ...(envDotFile(allSource) ? [{ path: '.env', description: 'Local env (git-ignored): a real random SESSION_SECRET is pre-filled so sessions are secure out of the box; fill in the rest.', contents: envDotFile(allSource) }] : []),
5502
+ ...(envDotFile(allSource, project) ? [{ path: '.env', description: 'Local env (git-ignored): a real random SESSION_SECRET and the Supabase connection the design holds are pre-filled, so the app runs as generated; fill in the rest.', contents: envDotFile(allSource, project) }] : []),
5484
5503
  { path: 'src/app.css', description: 'App theme tokens + page styles.', contents: appCss(project) },
5485
5504
  // Your styles: a dedicated CSS file the layout imports AFTER app.css, so its rules
5486
5505
  // win. Edited in the designer's Styles panel; regenerated from the model.
@@ -24,7 +24,8 @@ const SOURCE = /\.(ts|js|svelte)$/;
24
24
  export function toSvelteKit3(files) {
25
25
  const paths = new Set(files.map((f) => f.path));
26
26
  const adapter = adapterOf(files);
27
- const envNames = new Set();
27
+ // Every env var a source reads, and whether it is public (client-side).
28
+ const envNames = new Map();
28
29
  const out = [];
29
30
  for (const file of files) {
30
31
  // svelte.config.js is gone: its adapter and preprocess move into vite.config.ts.
@@ -50,7 +51,7 @@ export function toSvelteKit3(files) {
50
51
  out.push(file);
51
52
  }
52
53
  if (envNames.size)
53
- out.push(envModule([...envNames].sort()));
54
+ out.push(envModule([...envNames].sort(([a], [b]) => a.localeCompare(b))));
54
55
  return out;
55
56
  }
56
57
  /* ---------------------------------------------------------------- config */
@@ -143,10 +144,15 @@ function rewriteLibImports(src, paths) {
143
144
  /**
144
145
  * `import { env } from '$env/dynamic/private'` + `env.X`
145
146
  * -> `import { X } from '$app/env/private'` + `X`
146
- * Every name read is collected so src/env.ts can declare it, which v3 requires.
147
+ * and the same for `$env/dynamic/public` -> `$app/env/public` (the Supabase
148
+ * client reads PUBLIC_SUPABASE_* this way). Every name read is collected so
149
+ * src/env.ts can declare it, which v3 requires; public ones are declared
150
+ * `public: true`, or `$app/env/public` would not export them.
147
151
  */
148
152
  function rewriteEnv(src, envNames) {
149
- if (!/from\s+['"]\$env\/dynamic\/private['"]/.test(src))
153
+ const kind = /from\s+['"]\$env\/dynamic\/private['"]/.test(src) ? 'private'
154
+ : /from\s+['"]\$env\/dynamic\/public['"]/.test(src) ? 'public' : null;
155
+ if (!kind)
150
156
  return src;
151
157
  const used = new Set();
152
158
  // `(?<![.\w])` keeps `process.env.X` untouched; only the imported `env` changes.
@@ -155,9 +161,9 @@ function rewriteEnv(src, envNames) {
155
161
  return name;
156
162
  });
157
163
  for (const n of used)
158
- envNames.add(n);
164
+ envNames.set(n, kind === 'public' || envNames.get(n) === true);
159
165
  const names = [...used].sort();
160
- return body.replace(/import\s*\{\s*env\s*\}\s*from\s*(['"])\$env\/dynamic\/private\1/, names.length ? `import { ${names.join(', ')} } from '$app/env/private'` : '');
166
+ return body.replace(new RegExp(`import\\s*\\{\\s*env\\s*\\}\\s*from\\s*(['"])\\$env\\/dynamic\\/${kind}\\1`), names.length ? `import { ${names.join(', ')} } from '$app/env/${kind}'` : '');
161
167
  }
162
168
  /**
163
169
  * Types that moved out of `@sveltejs/kit`, and the deprecated `json` helper.
@@ -181,7 +187,7 @@ function rewriteKitImports(src) {
181
187
  }
182
188
  /* ------------------------------------------------------------------- env */
183
189
  function envModule(names) {
184
- const decls = names.map((n) => ` ${n}: { schema: (input) => input ?? '' },`).join('\n');
190
+ const decls = names.map(([n, pub]) => ` ${n}: { ${pub ? 'public: true, ' : ''}schema: (input) => input ?? '' },`).join('\n');
185
191
  return {
186
192
  path: 'src/env.ts',
187
193
  description: 'Environment variables the app reads (SvelteKit 3 requires declaring them).',
@@ -6599,6 +6599,13 @@ export const GENERATED_UI_SURFACE = {
6599
6599
  "description": "Kanban board mode. When set, the grid renders its rows as cards in horizontal lanes (bucketed by `board.groupBy`) instead of a table. See .",
6600
6600
  "group": "common"
6601
6601
  },
6602
+ {
6603
+ "key": "gallery",
6604
+ "label": "Gallery",
6605
+ "type": "json",
6606
+ "description": "Gallery mode. When set, the grid renders its rows as cards (a cover image, a title, a few fields) instead of a table. See .",
6607
+ "group": "common"
6608
+ },
6602
6609
  {
6603
6610
  "key": "scheduler",
6604
6611
  "label": "Scheduler",
@@ -6648,6 +6655,55 @@ export const GENERATED_UI_SURFACE = {
6648
6655
  "description": "Floating bar that appears over the grid while rows are selected, showing the count and the actions that apply to the whole selection - the pattern an issue tracker uses for bulk edit. `true` gives the count and a Clear button. An array is the shorthand for `{ actions }`. Pass to also set `position` (`'bottom'` default, or `'top'`), `maxVisible` and `hideClear`. Omitted / `false` is off. Default **off**. This is chrome that floats over your content, not a gesture: it overlaps a row, and what belongs on it is specific to the app. **The prop and its types are free; the bar itself is an Enterprise feature.** Install `@svgrid/enterprise` and call `enableSelectionBar()` (or `installEnterprise`, which does it for you) to render it - without that the grid shows a short upsell note in its place, the same way the scheduler and board views do.",
6649
6656
  "group": "common"
6650
6657
  },
6658
+ {
6659
+ "key": "rowAdder",
6660
+ "label": "Row Adder",
6661
+ "type": "boolean",
6662
+ "description": "A \"+ Add row\" line under the last row. Clicking it (or Enter on it) appends a row, scrolls to it and starts editing its first editable cell. `true` uses the defaults; pass for the label and the new row's values. **The prop and its types are free; the row adder is drawn by the Enterprise `@svgrid/enterprise/fields` module** (`enableFields()`). Without it the prop does nothing.",
6663
+ "group": "common"
6664
+ },
6665
+ {
6666
+ "key": "rowColor",
6667
+ "label": "Row Color",
6668
+ "type": "json",
6669
+ "description": "Color rows by a status: by a select field (each row takes its option's `color`) or by rules (first match wins). The color shows on the row header by default (a 3px stripe at the start of the row-number cell); `target` moves it to a stripe in the first cell or a tint across the row. The row header also gets the status as its title, so the color is never the only signal. Computed for rendered rows only. **The prop and its types are free; the colors are drawn by the Enterprise `@svgrid/enterprise/fields` module** (`enableFields()`).",
6670
+ "group": "common"
6671
+ },
6672
+ {
6673
+ "key": "columnAdder",
6674
+ "label": "Column Adder",
6675
+ "type": "boolean",
6676
+ "description": "A \"+\" header cell after the last column that opens the field editor: a name, a field type and that type's properties. Creating adds the column and fires `onColumnAdd`; the grid never stores a schema, the app does. `{ types }` limits the types offered. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
6677
+ "group": "common"
6678
+ },
6679
+ {
6680
+ "key": "fieldMenu",
6681
+ "label": "Field Menu",
6682
+ "type": "boolean",
6683
+ "description": "Field actions in each column's menu: Edit field, Insert left / right, Duplicate, Delete, Hide. Edit can change the type; values are converted where they can be and the editor says how many cells would be cleared. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
6684
+ "group": "common"
6685
+ },
6686
+ {
6687
+ "key": "expandRows",
6688
+ "label": "Expand Rows",
6689
+ "type": "boolean",
6690
+ "description": "The row-number cell becomes the row's handle: on hover it shows a checkbox that selects the row and an expand button that opens the row as a record, every field with its label and its editor. With `showRowNumbers`. **Drawn by the Enterprise `@svgrid/enterprise/fields` module.**",
6691
+ "group": "common"
6692
+ },
6693
+ {
6694
+ "key": "pinSplitter",
6695
+ "label": "Pin Splitter",
6696
+ "type": "boolean",
6697
+ "description": "A divider at the edge of the left-pinned columns: drag it right to pin the columns it passes, left to unpin them. It snaps to column edges and keeps the columns where they are on screen; with the keyboard, focus it and use the arrow keys. Its words come from `localization.text` (`pinSplitterLabel`, `pinSplitterHint`, `pinSplitterNone`, `pinSplitterOne`, `pinSplitterMany`). Loaded only when set.",
6698
+ "group": "common"
6699
+ },
6700
+ {
6701
+ "key": "primaryField",
6702
+ "label": "Primary Field",
6703
+ "type": "string",
6704
+ "description": "The table's primary field (a column id or field): always the first column and pinned, never hidden or deleted, and the name of a record (the expanded record's title, a gallery card's title). **Kept by the Enterprise `@svgrid/enterprise/fields` module.**",
6705
+ "group": "common"
6706
+ },
6651
6707
  {
6652
6708
  "key": "features",
6653
6709
  "label": "Features",
@@ -7180,7 +7236,7 @@ export const GENERATED_UI_SURFACE = {
7180
7236
  "key": "rowNumberWidth",
7181
7237
  "label": "Row Number Width",
7182
7238
  "type": "number",
7183
- "description": "Width (px) of the row-number column. Defaults to 56, which fits up to \"99,999\"; bump this when the dataset crosses six digits so the largest row number stays fully visible at the bottom of a scroll.",
7239
+ "description": "Width (px) of the row-number column. By default it fits the largest row number: 56px up to four digits, then 9px wider per digit (from `data.length`, or `rowCount` on a server-paged grid). Set it to pin a width, for example when a theme uses a much larger font.",
7184
7240
  "group": "common"
7185
7241
  },
7186
7242
  {
@@ -7412,7 +7468,7 @@ export const GENERATED_UI_SURFACE = {
7412
7468
  "key": "rowDragManaged",
7413
7469
  "label": "Row Drag Managed",
7414
7470
  "type": "boolean",
7415
- "description": "Enables managed row dragging. When `true`, every row becomes a drag source (grab cursor + a grip in the row-number cell) and a drop indicator paints between rows during a drag. On drop the grid mutates its own internal data - reordering within the grid, or moving the row across grids that share the same . Defaults to `false`.",
7471
+ "description": "Enables managed row dragging. When `true`, a row is dragged by its row-number cell (a grip shows while it is hovered), or by any cell when row numbers are off, and a drop indicator paints between rows during a drag. On drop the grid mutates its own internal data - reordering within the grid, or moving the row across grids that share the same . Defaults to `false`.",
7416
7472
  "group": "common"
7417
7473
  },
7418
7474
  {
@@ -7444,6 +7500,42 @@ export const GENERATED_UI_SURFACE = {
7444
7500
  "prop": "onPivotModeChange",
7445
7501
  "description": "Fired when the in-grid Pivot toggle flips `pivotMode`."
7446
7502
  },
7503
+ {
7504
+ "key": "rowAdd",
7505
+ "label": "Row Add",
7506
+ "prop": "onRowAdd",
7507
+ "description": "Fires after the row adder appended a row, with that row. Persist it here."
7508
+ },
7509
+ {
7510
+ "key": "columnAdd",
7511
+ "label": "Column Add",
7512
+ "prop": "onColumnAdd",
7513
+ "description": "A field was added (column adder, Insert, Duplicate). `columns` is the whole column list after the change, as declared (store it as your `columns`); `data` is set when values were written too."
7514
+ },
7515
+ {
7516
+ "key": "columnChange",
7517
+ "label": "Column Change",
7518
+ "prop": "onColumnChange",
7519
+ "description": "A field was edited. `columns` as in `onColumnAdd`; `data` is set when a type change converted its values."
7520
+ },
7521
+ {
7522
+ "key": "columnRemove",
7523
+ "label": "Column Remove",
7524
+ "prop": "onColumnRemove",
7525
+ "description": "A field was deleted from the column menu (its values stay in the rows). `columns` as in `onColumnAdd`."
7526
+ },
7527
+ {
7528
+ "key": "rowsDelete",
7529
+ "label": "Rows Delete",
7530
+ "prop": "onRowsDelete",
7531
+ "description": "Rows were deleted from the selection bar's Delete (`deleteRows`): the rows and their ids, and the data without them, to store."
7532
+ },
7533
+ {
7534
+ "key": "rowColorChange",
7535
+ "label": "Row Color Change",
7536
+ "prop": "onRowColorChange",
7537
+ "description": "The rows were set to be colored by another field, or no longer colored, from a single select's column menu (\"Color rows by this field\" with `fieldMenu`). Store it and pass it back as `rowColor`."
7538
+ },
7447
7539
  {
7448
7540
  "key": "expandedChange",
7449
7541
  "label": "Expanded Change",
@@ -1,5 +1,5 @@
1
1
  /** Human-readable labels for the Enterprise surfaces that gate behind a license. */
2
- export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Server-side row model' | 'Spreadsheet' | 'Studio';
2
+ export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Server-side row model' | 'Spreadsheet' | 'SvGrid Base' | 'Studio';
3
3
  /**
4
4
  * Show the contextual upgrade prompt for `feature`. No-ops if one has already
5
5
  * been shown this session, a card is already up, or we're on the server. Safe
package/dist/version.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export declare const SVGRID_VERSION = "3.1.7";
13
+ export declare const SVGRID_VERSION = "3.1.9";
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
@@ -23,4 +23,4 @@ export declare const SVGRID_VERSION = "3.1.7";
23
23
  *
24
24
  * `version.test.ts` asserts this matches packages/grid/package.json.
25
25
  */
26
- export declare const GRID_VERSION = "3.0.10";
26
+ export declare const GRID_VERSION = "3.0.12";