@svgrid/enterprise 3.0.1 → 3.0.3

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 (445) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +680 -0
  10. package/dist/SvFormulaBar.svelte.d.ts +69 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +263 -54
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvRibbonIcon.svelte +46 -0
  20. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  21. package/dist/SvSchemaChart.svelte +4 -2
  22. package/dist/SvSheet.svelte +7914 -0
  23. package/dist/SvSheet.svelte.d.ts +215 -0
  24. package/dist/SvSheetChartSetup.svelte +151 -0
  25. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  26. package/dist/SvSheetComment.svelte +283 -0
  27. package/dist/SvSheetComment.svelte.d.ts +22 -0
  28. package/dist/SvSheetConditionalFormat.svelte +159 -0
  29. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  30. package/dist/SvSheetDataValidation.svelte +273 -0
  31. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  32. package/dist/SvSheetEditRanges.svelte +217 -0
  33. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  34. package/dist/SvSheetErrors.svelte +125 -0
  35. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  36. package/dist/SvSheetEvaluate.svelte +133 -0
  37. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  38. package/dist/SvSheetFilterMenu.svelte +320 -0
  39. package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
  40. package/dist/SvSheetFindReplace.svelte +132 -0
  41. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  42. package/dist/SvSheetFormatCells.svelte +465 -0
  43. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  44. package/dist/SvSheetGoalSeek.svelte +145 -0
  45. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  46. package/dist/SvSheetInsertFunction.svelte +149 -0
  47. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  48. package/dist/SvSheetIteration.svelte +81 -0
  49. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  50. package/dist/SvSheetLink.svelte +99 -0
  51. package/dist/SvSheetLink.svelte.d.ts +17 -0
  52. package/dist/SvSheetListPicker.svelte +91 -0
  53. package/dist/SvSheetListPicker.svelte.d.ts +10 -0
  54. package/dist/SvSheetManageRules.svelte +187 -0
  55. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  56. package/dist/SvSheetNameManager.svelte +227 -0
  57. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  58. package/dist/SvSheetPageSetup.svelte +159 -0
  59. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  60. package/dist/SvSheetPasteSpecial.svelte +107 -0
  61. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  62. package/dist/SvSheetPivot.svelte +220 -0
  63. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  64. package/dist/SvSheetProtectSheet.svelte +81 -0
  65. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  66. package/dist/SvSheetRemoveDuplicates.svelte +152 -0
  67. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  68. package/dist/SvSheetRibbon.svelte +1254 -0
  69. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  70. package/dist/SvSheetSizeDialog.svelte +60 -0
  71. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  72. package/dist/SvSheetSort.svelte +218 -0
  73. package/dist/SvSheetSort.svelte.d.ts +28 -0
  74. package/dist/SvSheetSparklines.svelte +135 -0
  75. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  76. package/dist/SvSheetTable.svelte +160 -0
  77. package/dist/SvSheetTable.svelte.d.ts +24 -0
  78. package/dist/SvSheetTabs.svelte +571 -0
  79. package/dist/SvSheetTabs.svelte.d.ts +50 -0
  80. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  81. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  82. package/dist/SvSheetTextToColumns.svelte +172 -0
  83. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  84. package/dist/SvSheetValidationAlert.svelte +85 -0
  85. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  86. package/dist/advanced-filter-enable.js +1 -1
  87. package/dist/alerts/alert-engine.d.ts +6 -0
  88. package/dist/alerts/alert-engine.js +21 -4
  89. package/dist/alerts/alert-formats.js +2 -0
  90. package/dist/alerts/alert-types.d.ts +1 -1
  91. package/dist/alerts.d.ts +1 -1
  92. package/dist/alerts.js +2 -2
  93. package/dist/board.js +2 -2
  94. package/dist/bulk-edit.d.ts +3 -1
  95. package/dist/bulk-edit.js +1 -1
  96. package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
  97. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  98. package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
  99. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  100. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  101. package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
  102. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  103. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  104. package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
  109. package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
  110. package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  112. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  113. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  114. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  115. package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
  116. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  117. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  118. package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
  119. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  120. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  121. package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
  122. package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
  123. package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
  124. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  125. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  126. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  127. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  128. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  129. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  130. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  131. package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
  132. package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
  133. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  134. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  135. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  136. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  137. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  138. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  139. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  140. package/dist/designer/index.html +29 -19
  141. package/dist/export-pdf.d.ts +164 -0
  142. package/dist/export-pdf.js +346 -15
  143. package/dist/export.js +25 -10
  144. package/dist/gantt/SvGridGantt.svelte +2890 -0
  145. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  146. package/dist/gantt/gantt-config.d.ts +73 -0
  147. package/dist/gantt/gantt-config.js +1 -0
  148. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  149. package/dist/gantt/gantt-critical-path.js +207 -0
  150. package/dist/gantt/gantt-model.d.ts +257 -0
  151. package/dist/gantt/gantt-model.js +651 -0
  152. package/dist/gantt/gantt-resources.d.ts +59 -0
  153. package/dist/gantt/gantt-resources.js +71 -0
  154. package/dist/gantt/gantt.d.ts +7 -0
  155. package/dist/gantt/gantt.js +36 -0
  156. package/dist/gantt/index.d.ts +15 -0
  157. package/dist/gantt/index.js +22 -0
  158. package/dist/gantt/timeline-arrows.d.ts +102 -0
  159. package/dist/gantt/timeline-arrows.js +181 -0
  160. package/dist/import.d.ts +2 -2
  161. package/dist/import.js +1 -1
  162. package/dist/index.d.ts +93 -3
  163. package/dist/index.js +107 -3
  164. package/dist/install.js +13 -1
  165. package/dist/license-core.d.ts +17 -1
  166. package/dist/license-core.js +16 -5
  167. package/dist/license.d.ts +18 -2
  168. package/dist/license.js +71 -6
  169. package/dist/node/studio.js +203 -9
  170. package/dist/pivot-chart.d.ts +25 -1
  171. package/dist/pivot-chart.js +25 -69
  172. package/dist/pivot-enable.js +2 -2
  173. package/dist/scheduler-dependencies.d.ts +35 -0
  174. package/dist/scheduler-dependencies.js +36 -1
  175. package/dist/scheduler.js +2 -2
  176. package/dist/selection-bar.js +2 -2
  177. package/dist/server/SvGroupCell.svelte +213 -0
  178. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  179. package/dist/server/SvRowGroupPanel.svelte +322 -0
  180. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  181. package/dist/server/enable.d.ts +17 -0
  182. package/dist/server/enable.js +49 -0
  183. package/dist/server/index.d.ts +22 -0
  184. package/dist/server/index.js +24 -0
  185. package/dist/server/messages.d.ts +45 -0
  186. package/dist/server/messages.js +35 -0
  187. package/dist/server/server-group-model.d.ts +104 -0
  188. package/dist/server/server-group-model.js +272 -0
  189. package/dist/server/server-pivot.d.ts +46 -0
  190. package/dist/server/server-pivot.js +57 -0
  191. package/dist/server/server-row-model.d.ts +547 -0
  192. package/dist/server/server-row-model.js +1551 -0
  193. package/dist/server/server-selection.d.ts +99 -0
  194. package/dist/server/server-selection.js +215 -0
  195. package/dist/server/svgrid-adapter.d.ts +155 -0
  196. package/dist/server/svgrid-adapter.js +202 -0
  197. package/dist/sheet/address.d.ts +43 -0
  198. package/dist/sheet/address.js +81 -0
  199. package/dist/sheet/ast.d.ts +138 -0
  200. package/dist/sheet/ast.js +70 -0
  201. package/dist/sheet/auto-filter.d.ts +120 -0
  202. package/dist/sheet/auto-filter.js +295 -0
  203. package/dist/sheet/autocomplete.d.ts +51 -0
  204. package/dist/sheet/autocomplete.js +248 -0
  205. package/dist/sheet/cell-images.d.ts +39 -0
  206. package/dist/sheet/cell-images.js +90 -0
  207. package/dist/sheet/cell-types.d.ts +58 -0
  208. package/dist/sheet/cell-types.js +96 -0
  209. package/dist/sheet/coerce.d.ts +71 -0
  210. package/dist/sheet/coerce.js +289 -0
  211. package/dist/sheet/commands.d.ts +89 -0
  212. package/dist/sheet/commands.js +230 -0
  213. package/dist/sheet/comments.d.ts +63 -0
  214. package/dist/sheet/comments.js +131 -0
  215. package/dist/sheet/conditional-formats.d.ts +167 -0
  216. package/dist/sheet/conditional-formats.js +341 -0
  217. package/dist/sheet/csv.d.ts +32 -0
  218. package/dist/sheet/csv.js +158 -0
  219. package/dist/sheet/culture.d.ts +87 -0
  220. package/dist/sheet/culture.js +247 -0
  221. package/dist/sheet/delta.d.ts +102 -0
  222. package/dist/sheet/delta.js +203 -0
  223. package/dist/sheet/deps.d.ts +104 -0
  224. package/dist/sheet/deps.js +274 -0
  225. package/dist/sheet/document.d.ts +252 -0
  226. package/dist/sheet/document.js +465 -0
  227. package/dist/sheet/edit-keys.d.ts +14 -0
  228. package/dist/sheet/edit-keys.js +40 -0
  229. package/dist/sheet/engine.d.ts +67 -0
  230. package/dist/sheet/engine.js +19 -0
  231. package/dist/sheet/entry.d.ts +35 -0
  232. package/dist/sheet/entry.js +226 -0
  233. package/dist/sheet/error-check.d.ts +49 -0
  234. package/dist/sheet/error-check.js +83 -0
  235. package/dist/sheet/evaluate-steps.d.ts +48 -0
  236. package/dist/sheet/evaluate-steps.js +196 -0
  237. package/dist/sheet/evaluate.d.ts +128 -0
  238. package/dist/sheet/evaluate.js +1049 -0
  239. package/dist/sheet/filter-files.d.ts +37 -0
  240. package/dist/sheet/filter-files.js +465 -0
  241. package/dist/sheet/find-replace.d.ts +62 -0
  242. package/dist/sheet/find-replace.js +152 -0
  243. package/dist/sheet/format-store.d.ts +114 -0
  244. package/dist/sheet/format-store.js +243 -0
  245. package/dist/sheet/freeze.d.ts +54 -0
  246. package/dist/sheet/freeze.js +58 -0
  247. package/dist/sheet/from-rows.d.ts +14 -0
  248. package/dist/sheet/from-rows.js +50 -0
  249. package/dist/sheet/function-catalog.d.ts +10 -0
  250. package/dist/sheet/function-catalog.js +385 -0
  251. package/dist/sheet/functions.d.ts +28 -0
  252. package/dist/sheet/functions.js +634 -0
  253. package/dist/sheet/goal-seek.d.ts +73 -0
  254. package/dist/sheet/goal-seek.js +153 -0
  255. package/dist/sheet/index.d.ts +80 -0
  256. package/dist/sheet/index.js +80 -0
  257. package/dist/sheet/links.d.ts +57 -0
  258. package/dist/sheet/links.js +174 -0
  259. package/dist/sheet/merges.d.ts +71 -0
  260. package/dist/sheet/merges.js +137 -0
  261. package/dist/sheet/messages.d.ts +778 -0
  262. package/dist/sheet/messages.js +806 -0
  263. package/dist/sheet/names.d.ts +31 -0
  264. package/dist/sheet/names.js +87 -0
  265. package/dist/sheet/navigate.d.ts +52 -0
  266. package/dist/sheet/navigate.js +135 -0
  267. package/dist/sheet/number-format.d.ts +110 -0
  268. package/dist/sheet/number-format.js +905 -0
  269. package/dist/sheet/objects.d.ts +106 -0
  270. package/dist/sheet/objects.js +149 -0
  271. package/dist/sheet/ods-document.d.ts +44 -0
  272. package/dist/sheet/ods-document.js +1275 -0
  273. package/dist/sheet/open-file.d.ts +26 -0
  274. package/dist/sheet/open-file.js +56 -0
  275. package/dist/sheet/outline.d.ts +82 -0
  276. package/dist/sheet/outline.js +228 -0
  277. package/dist/sheet/packs/array.d.ts +16 -0
  278. package/dist/sheet/packs/array.js +172 -0
  279. package/dist/sheet/packs/database.d.ts +42 -0
  280. package/dist/sheet/packs/database.js +142 -0
  281. package/dist/sheet/packs/engineering.d.ts +2 -0
  282. package/dist/sheet/packs/engineering.js +296 -0
  283. package/dist/sheet/packs/financial.d.ts +5 -0
  284. package/dist/sheet/packs/financial.js +220 -0
  285. package/dist/sheet/packs/math-stats.d.ts +2 -0
  286. package/dist/sheet/packs/math-stats.js +372 -0
  287. package/dist/sheet/packs/special.d.ts +44 -0
  288. package/dist/sheet/packs/special.js +187 -0
  289. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  290. package/dist/sheet/packs/stats-dist.js +785 -0
  291. package/dist/sheet/packs/text-date.d.ts +2 -0
  292. package/dist/sheet/packs/text-date.js +332 -0
  293. package/dist/sheet/packs/trig.d.ts +2 -0
  294. package/dist/sheet/packs/trig.js +73 -0
  295. package/dist/sheet/page-setup.d.ts +73 -0
  296. package/dist/sheet/page-setup.js +73 -0
  297. package/dist/sheet/palette.d.ts +19 -0
  298. package/dist/sheet/palette.js +84 -0
  299. package/dist/sheet/parse.d.ts +13 -0
  300. package/dist/sheet/parse.js +140 -0
  301. package/dist/sheet/paste-special.d.ts +186 -0
  302. package/dist/sheet/paste-special.js +601 -0
  303. package/dist/sheet/pivot-range.d.ts +160 -0
  304. package/dist/sheet/pivot-range.js +333 -0
  305. package/dist/sheet/presence.d.ts +73 -0
  306. package/dist/sheet/presence.js +79 -0
  307. package/dist/sheet/print.d.ts +104 -0
  308. package/dist/sheet/print.js +169 -0
  309. package/dist/sheet/protection.d.ts +75 -0
  310. package/dist/sheet/protection.js +101 -0
  311. package/dist/sheet/rects.d.ts +45 -0
  312. package/dist/sheet/rects.js +112 -0
  313. package/dist/sheet/refs.d.ts +130 -0
  314. package/dist/sheet/refs.js +413 -0
  315. package/dist/sheet/ribbon-icons.d.ts +31 -0
  316. package/dist/sheet/ribbon-icons.js +536 -0
  317. package/dist/sheet/ribbon.d.ts +173 -0
  318. package/dist/sheet/ribbon.js +1054 -0
  319. package/dist/sheet/sheet-kinds.d.ts +74 -0
  320. package/dist/sheet/sheet-kinds.js +91 -0
  321. package/dist/sheet/shortcuts.d.ts +174 -0
  322. package/dist/sheet/shortcuts.js +674 -0
  323. package/dist/sheet/sort.d.ts +51 -0
  324. package/dist/sheet/sort.js +107 -0
  325. package/dist/sheet/sparklines.d.ts +111 -0
  326. package/dist/sheet/sparklines.js +204 -0
  327. package/dist/sheet/structure.d.ts +87 -0
  328. package/dist/sheet/structure.js +166 -0
  329. package/dist/sheet/table-styles.d.ts +74 -0
  330. package/dist/sheet/table-styles.js +152 -0
  331. package/dist/sheet/tables.d.ts +89 -0
  332. package/dist/sheet/tables.js +178 -0
  333. package/dist/sheet/tokenize.d.ts +71 -0
  334. package/dist/sheet/tokenize.js +355 -0
  335. package/dist/sheet/transforms.d.ts +76 -0
  336. package/dist/sheet/transforms.js +154 -0
  337. package/dist/sheet/validation.d.ts +108 -0
  338. package/dist/sheet/validation.js +278 -0
  339. package/dist/sheet/workbook.d.ts +217 -0
  340. package/dist/sheet/workbook.js +1120 -0
  341. package/dist/sheet/xls-cfb.d.ts +32 -0
  342. package/dist/sheet/xls-cfb.js +290 -0
  343. package/dist/sheet/xls-document.d.ts +10 -0
  344. package/dist/sheet/xls-document.js +1243 -0
  345. package/dist/sheet/xls-formula.d.ts +40 -0
  346. package/dist/sheet/xls-formula.js +569 -0
  347. package/dist/sheet/xlsx-document.d.ts +108 -0
  348. package/dist/sheet/xlsx-document.js +1849 -0
  349. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  350. package/dist/sheet/xlsx-drawing.js +420 -0
  351. package/dist/sheet-enable.d.ts +6 -0
  352. package/dist/sheet-enable.js +45 -0
  353. package/dist/sheet-text.d.ts +7 -0
  354. package/dist/sheet-text.js +29 -0
  355. package/dist/sources/auth-supabase.js +2 -2
  356. package/dist/sources/realtime-supabase.js +2 -2
  357. package/dist/sources/rest.d.ts +6 -2
  358. package/dist/sources/rest.js +42 -7
  359. package/dist/sources/supabase.d.ts +10 -1
  360. package/dist/sources/supabase.js +73 -40
  361. package/dist/studio/emit-project.js +14 -1
  362. package/dist/studio/index.js +1 -1
  363. package/dist/studio/project.d.ts +11 -2
  364. package/dist/studio/project.js +5 -2
  365. package/dist/studio/ui-components.generated.js +170 -3
  366. package/dist/sveltekit/in-memory.d.ts +2 -2
  367. package/dist/sveltekit/in-memory.js +125 -4
  368. package/dist/sveltekit/index.d.ts +1 -1
  369. package/dist/sveltekit/index.js +1 -1
  370. package/dist/sveltekit/query-plan.d.ts +50 -4
  371. package/dist/sveltekit/query-plan.js +25 -3
  372. package/dist/sveltekit/sql-source.d.ts +6 -0
  373. package/dist/sveltekit/sql-source.js +34 -6
  374. package/dist/sveltekit/sql.d.ts +31 -0
  375. package/dist/sveltekit/sql.js +135 -25
  376. package/dist/sveltekit/transport.d.ts +10 -2
  377. package/dist/sveltekit/transport.js +30 -6
  378. package/dist/upgrade-prompt.d.ts +1 -1
  379. package/dist/version.d.ts +1 -1
  380. package/dist/version.js +1 -1
  381. package/dist/watermark.js +35 -2
  382. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  383. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  384. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  385. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  386. package/dist/wc/SvField-B_kurx_P.js +149 -0
  387. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  388. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  389. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  390. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  391. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  392. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  393. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  394. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  395. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  396. package/dist/wc/chart-6OXlybVT.js +4341 -0
  397. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  398. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  399. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  400. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  401. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  402. package/dist/wc/client-DQIzjDBG.js +3064 -0
  403. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  404. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  405. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  406. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  407. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  408. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  409. package/dist/wc/list-option-DrRyivWp.js +82 -0
  410. package/dist/wc/popover-WsGlvtQv.js +69 -0
  411. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  412. package/dist/wc/react.d.ts +41 -0
  413. package/dist/wc/react.js +90 -0
  414. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  415. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  416. package/dist/wc/row-resize-limG_N1z.js +111 -0
  417. package/dist/wc/sv-sheet-element.d.ts +97 -0
  418. package/dist/wc/sv-sheet-element.js +44213 -0
  419. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  420. package/dist/wc/validate-BqDthkNr.js +88 -0
  421. package/dist/wc/vue.d.ts +31 -0
  422. package/dist/wc/vue.js +75 -0
  423. package/package.json +36 -6
  424. package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
  425. package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
  426. package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
  427. package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
  428. package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
  429. package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
  430. package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
  431. package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
  432. package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
  433. package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
  434. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  435. package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
  436. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  437. package/dist/designer/assets/chart-DXFganU8.js +0 -1
  438. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  439. package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
  440. package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
  441. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  442. package/dist/designer/assets/index-k2stW6L8.css +0 -1
  443. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  444. package/dist/designer/assets/src-D9p27OGC.js +0 -58
  445. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,15 @@
1
+ import { type EditRange } from './sheet/protection.js';
2
+ type Props = {
3
+ open?: boolean;
4
+ /** The sheet's ranges as they stand. */
5
+ ranges: ReadonlyArray<EditRange>;
6
+ /** The selection as A1 text, what a new range's cells open on. */
7
+ selection: string;
8
+ onApply: (ranges: EditRange[]) => void;
9
+ /** The Protect Sheet... button: the shell opens that dialog. */
10
+ onProtect: () => void;
11
+ onClose?: () => void;
12
+ };
13
+ declare const SvSheetEditRanges: import("svelte").Component<Props, {}, "open">;
14
+ type SvSheetEditRanges = ReturnType<typeof SvSheetEditRanges>;
15
+ export default SvSheetEditRanges;
@@ -0,0 +1,125 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Excel's Error Checking: the cells on this sheet worth a second look,
4
+ * walked one at a time. Each one says what the error means rather than
5
+ * leaving the code to be looked up, and Show Calculation Steps hands the
6
+ * cell to Evaluate Formula, which is where the answer usually is.
7
+ *
8
+ * The selection follows the walk, so the cell being talked about is the
9
+ * cell on screen.
10
+ */
11
+ import { untrack } from 'svelte'
12
+ import { SvModal } from '@svgrid/grid'
13
+ import { useSheetText } from './sheet-text'
14
+ import { colToLetters } from './sheet/address'
15
+ import { checkSheet, describeFinding, type ErrorFinding } from './sheet/error-check'
16
+ import type { Workbook } from './sheet/workbook'
17
+
18
+ type Props = {
19
+ open?: boolean
20
+ workbook: Workbook
21
+ sheet: string
22
+ /** Put the selection on a cell being looked at. */
23
+ onGoTo: (cell: { row: number; col: number }) => void
24
+ /** Open Evaluate Formula on the cell being looked at. */
25
+ onSteps: (cell: { row: number; col: number }) => void
26
+ onClose?: () => void
27
+ }
28
+
29
+ let { open = $bindable(false), workbook, sheet, onGoTo, onSteps, onClose }: Props = $props()
30
+ const t = useSheetText()
31
+
32
+ let findings = $state<ErrorFinding[]>([])
33
+ let at = $state(0)
34
+ let nextButton = $state<HTMLButtonElement | null>(null)
35
+
36
+ const current = $derived(findings[at] ?? null)
37
+ const address = $derived(current ? `${colToLetters(current.col)}${current.row + 1}` : '')
38
+
39
+ // Opening is the only thing this effect follows. Reading the workbook
40
+ // through it would tie it to every repaint, and moving the selection
41
+ // repaints, so the walk would restart itself forever.
42
+ $effect(() => {
43
+ if (!open) return
44
+ untrack(load)
45
+ })
46
+
47
+ function load() {
48
+ const found = checkSheet(sheet, {
49
+ rowCount: () => workbook.rowCount(sheet),
50
+ colCount: () => workbook.colCount(sheet),
51
+ getRaw: (row, col) => workbook.getRaw(sheet, row, col),
52
+ getValue: (row, col) => workbook.getValue(sheet, row, col),
53
+ })
54
+ findings = found
55
+ at = 0
56
+ show(found[0])
57
+ queueMicrotask(() => nextButton?.focus())
58
+ }
59
+
60
+ function show(finding: ErrorFinding | undefined) {
61
+ if (finding) onGoTo({ row: finding.row, col: finding.col })
62
+ }
63
+
64
+ function move(by: number) {
65
+ const list = findings
66
+ if (list.length === 0) return
67
+ at = (at + by + list.length) % list.length
68
+ show(list[at])
69
+ }
70
+
71
+ function close() {
72
+ open = false
73
+ onClose?.()
74
+ }
75
+ </script>
76
+
77
+ <SvModal bind:open onClose={onClose} title={t('errors.title')} size="sm">
78
+ <div class="sv-sheet-dialog">
79
+ {#if current}
80
+ <p class="position">{t('errors.position', { index: at + 1, count: findings.length })}</p>
81
+ <p class="headline">
82
+ <code>{address}</code>
83
+ <strong>{current.kind === 'error' ? current.error : t('errors.inconsistent')}</strong>
84
+ </p>
85
+ <pre class="formula">{current.text}</pre>
86
+ <p class="meaning">{describeFinding(current)}</p>
87
+ {:else}
88
+ <p class="none">{t('errors.none')}</p>
89
+ {/if}
90
+ <p class="hint">{t('errors.hint')}</p>
91
+ </div>
92
+ {#snippet footer()}
93
+ <div class="sv-sheet-dialog-buttons">
94
+ <button type="button" class="btn" onclick={() => move(-1)} disabled={findings.length < 2}>{t('errors.previous')}</button>
95
+ <button type="button" class="btn" bind:this={nextButton} onclick={() => move(1)} disabled={findings.length < 2}>{t('errors.next')}</button>
96
+ <span class="spacer"></span>
97
+ <button
98
+ type="button"
99
+ class="btn primary"
100
+ disabled={!current}
101
+ onclick={() => { if (current) { open = false; onSteps({ row: current.row, col: current.col }) } }}
102
+ >{t('errors.steps')}</button>
103
+ <button type="button" class="btn" onclick={close}>{t('close')}</button>
104
+ </div>
105
+ {/snippet}
106
+ </SvModal>
107
+
108
+ <style>
109
+ .spacer { flex: 1; }
110
+ .position { margin: 0 0 6px; color: var(--sg-muted, #64748b); font-size: 12px; }
111
+ .headline { margin: 0 0 8px; display: flex; align-items: baseline; gap: 8px; }
112
+ .formula {
113
+ margin: 0 0 8px;
114
+ padding: 8px 10px;
115
+ border: 1px solid var(--sg-border, #d4d4d8);
116
+ border-radius: 4px;
117
+ background: var(--sg-surface-2, #f8fafc);
118
+ font-family: var(--sg-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
119
+ font-size: 13px;
120
+ white-space: pre-wrap;
121
+ overflow-wrap: anywhere;
122
+ }
123
+ .meaning { margin: 0; }
124
+ .none { margin: 0 0 8px; }
125
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { Workbook } from './sheet/workbook.js';
2
+ type Props = {
3
+ open?: boolean;
4
+ workbook: Workbook;
5
+ sheet: string;
6
+ /** Put the selection on a cell being looked at. */
7
+ onGoTo: (cell: {
8
+ row: number;
9
+ col: number;
10
+ }) => void;
11
+ /** Open Evaluate Formula on the cell being looked at. */
12
+ onSteps: (cell: {
13
+ row: number;
14
+ col: number;
15
+ }) => void;
16
+ onClose?: () => void;
17
+ };
18
+ declare const SvSheetErrors: import("svelte").Component<Props, {}, "open">;
19
+ type SvSheetErrors = ReturnType<typeof SvSheetErrors>;
20
+ export default SvSheetErrors;
@@ -0,0 +1,133 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Excel's Evaluate Formula: the active cell's formula with one part
4
+ * underlined, and a button that replaces that part with what it is worth.
5
+ * Keep clicking and the formula collapses into the cell's answer, which is
6
+ * the quickest way to see which half of a long formula is the wrong half.
7
+ *
8
+ * The walk itself is `evaluationSteps`; this shows it and lets the reader
9
+ * move back and forth through it.
10
+ */
11
+ import { untrack } from 'svelte'
12
+ import { SvModal } from '@svgrid/grid'
13
+ import { useSheetText } from './sheet-text'
14
+ import { colToLetters } from './sheet/address'
15
+ import { parseFormula } from './sheet/parse'
16
+ import { evaluationSteps, printValue, type EvaluationStep } from './sheet/evaluate-steps'
17
+ import type { Workbook } from './sheet/workbook'
18
+
19
+ type Props = {
20
+ open?: boolean
21
+ workbook: Workbook
22
+ sheet: string
23
+ /** The cell to walk, which is the active one when the dialog opens. */
24
+ cell: { row: number; col: number }
25
+ onClose?: () => void
26
+ }
27
+
28
+ let { open = $bindable(false), workbook, sheet, cell, onClose }: Props = $props()
29
+ const t = useSheetText()
30
+
31
+ let steps = $state<EvaluationStep[]>([])
32
+ let at = $state(0)
33
+ let problem = $state('')
34
+ let evaluateButton = $state<HTMLButtonElement | null>(null)
35
+
36
+ const address = $derived(`${sheet}!${colToLetters(cell.col)}${cell.row + 1}`)
37
+ /** The line on screen: the formula as it stands before the next step, or
38
+ * the final value once every part has been worked out. */
39
+ const current = $derived(steps[at] ?? null)
40
+ const finished = $derived(steps.length > 0 && at >= steps.length)
41
+ const answer = $derived(steps.length > 0 ? steps[steps.length - 1]!.value : null)
42
+
43
+ // The cell is followed, because Error Checking hands this dialog a new
44
+ // one while it is open; the workbook is not, or every repaint would
45
+ // restart the walk.
46
+ $effect(() => {
47
+ if (!open) return
48
+ const target = cell
49
+ untrack(() => walk(target))
50
+ })
51
+
52
+ function walk(target: { row: number; col: number }) {
53
+ at = 0
54
+ problem = ''
55
+ steps = []
56
+ const text = workbook.getRaw(sheet, target.row, target.col).trim()
57
+ if (!text.startsWith('=')) {
58
+ problem = t('evaluate.noFormula')
59
+ return
60
+ }
61
+ try {
62
+ steps = evaluationSteps(
63
+ parseFormula(text),
64
+ (formula) => workbook.evaluateText(sheet, formula, undefined, { row: target.row, col: target.col }),
65
+ )
66
+ } catch {
67
+ problem = t('evaluate.noFormula')
68
+ }
69
+ queueMicrotask(() => evaluateButton?.focus())
70
+ }
71
+
72
+ function close() {
73
+ open = false
74
+ onClose?.()
75
+ }
76
+ </script>
77
+
78
+ <SvModal bind:open onClose={onClose} title={t('evaluate.title')} size="md">
79
+ <div class="sv-sheet-dialog">
80
+ <p class="reference"><span class="label">{t('evaluate.reference')}</span> <code>{address}</code></p>
81
+ {#if problem}
82
+ <p class="error">{problem}</p>
83
+ {:else}
84
+ <p class="label">{t('evaluate.evaluation')}</p>
85
+ <pre class="evaluation" data-testid="sv-sheet-evaluation">{#if current}{current.formula.slice(0, current.from)}<mark>{current.formula.slice(current.from, current.to)}</mark>{current.formula.slice(current.to)}{:else}{printValue(answer ?? '')}{/if}</pre>
86
+ {#if finished}
87
+ <p class="done">{t('evaluate.done')} <strong>{printValue(answer ?? '')}</strong></p>
88
+ {/if}
89
+ <p class="hint">{t('evaluate.hint')}</p>
90
+ {/if}
91
+ </div>
92
+ {#snippet footer()}
93
+ <div class="sv-sheet-dialog-buttons">
94
+ <button type="button" class="btn" onclick={() => { at = Math.max(0, at - 1) }} disabled={at === 0 || !!problem}>{t('evaluate.stepBack')}</button>
95
+ <button type="button" class="btn" onclick={() => { at = 0 }} disabled={at === 0 || !!problem}>{t('evaluate.restart')}</button>
96
+ <span class="spacer"></span>
97
+ <button
98
+ type="button"
99
+ class="btn primary"
100
+ bind:this={evaluateButton}
101
+ onclick={() => { at = Math.min(steps.length, at + 1) }}
102
+ disabled={finished || !!problem}
103
+ >{t('evaluate.evaluate')}</button>
104
+ <button type="button" class="btn" onclick={close}>{t('close')}</button>
105
+ </div>
106
+ {/snippet}
107
+ </SvModal>
108
+
109
+ <style>
110
+ .spacer { flex: 1; }
111
+ .reference { margin: 0 0 8px; }
112
+ .label { color: var(--sg-muted, #64748b); font-size: 12px; }
113
+ .evaluation {
114
+ margin: 0;
115
+ padding: 10px 12px;
116
+ border: 1px solid var(--sg-border, #d4d4d8);
117
+ border-radius: 4px;
118
+ background: var(--sg-surface-2, #f8fafc);
119
+ font-family: var(--sg-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
120
+ font-size: 13px;
121
+ line-height: 1.6;
122
+ white-space: pre-wrap;
123
+ overflow-wrap: anywhere;
124
+ }
125
+ .evaluation mark {
126
+ background: var(--sg-accent-soft, #dbeafe);
127
+ color: inherit;
128
+ text-decoration: underline;
129
+ text-underline-offset: 3px;
130
+ }
131
+ .done { margin: 8px 0 0; }
132
+ .error { margin: 4px 0 0; color: var(--sg-danger, #c42b1c); font-size: 12px; }
133
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { Workbook } from './sheet/workbook.js';
2
+ type Props = {
3
+ open?: boolean;
4
+ workbook: Workbook;
5
+ sheet: string;
6
+ /** The cell to walk, which is the active one when the dialog opens. */
7
+ cell: {
8
+ row: number;
9
+ col: number;
10
+ };
11
+ onClose?: () => void;
12
+ };
13
+ declare const SvSheetEvaluate: import("svelte").Component<Props, {}, "open">;
14
+ type SvSheetEvaluate = ReturnType<typeof SvSheetEvaluate>;
15
+ export default SvSheetEvaluate;
@@ -0,0 +1,320 @@
1
+ <script lang="ts">
2
+ /**
3
+ * The menu an AutoFilter arrow drops: Excel's, in its order. Sort A to Z
4
+ * and Z to A, Clear Filter From the column, a condition (Text Filters or
5
+ * Number Filters: equals, greater than, contains, between and the rest,
6
+ * two of them joined with And / Or), a search box, (Select All) and the
7
+ * column's values to tick, OK and Cancel. The shell mounts it inside the
8
+ * popover anchored to the header cell.
9
+ */
10
+ import { useSheetText } from './sheet-text'
11
+ import type { ExcelFilterOperator } from '@svgrid/grid/filtering'
12
+ import { valuesFilter, type ColumnFilter, type FilterValue, type FilterCondition, type DatePeriod } from './sheet/auto-filter'
13
+
14
+ type Props = {
15
+ /** The header text, for Clear Filter From "X". */
16
+ header: string
17
+ /** The column's values with their counts. */
18
+ values: ReadonlyArray<FilterValue>
19
+ /** The filter on the column now, if any. */
20
+ filter: ColumnFilter | null
21
+ /** Whether the column holds numbers, for Number Filters over Text Filters. */
22
+ numeric: boolean
23
+ /** Whether the column holds dates, for Date Filters. */
24
+ dates?: boolean
25
+ /** The fills the column's cells carry (null for none), for Filter by
26
+ * Color; the entry is left off with fewer than two. */
27
+ fills?: ReadonlyArray<string | null>
28
+ onSort: (direction: 'asc' | 'desc') => void
29
+ onApply: (filter: ColumnFilter | null) => void
30
+ onCancel: () => void
31
+ }
32
+
33
+ let { header, values, filter, numeric, dates = false, fills = [], onSort, onApply, onCancel }: Props = $props()
34
+ const t = useSheetText()
35
+
36
+ const PERIODS: ReadonlyArray<DatePeriod> = [
37
+ 'equals', 'before', 'after', 'between', 'tomorrow', 'today', 'yesterday',
38
+ 'nextWeek', 'thisWeek', 'lastWeek', 'nextMonth', 'thisMonth', 'lastMonth',
39
+ 'nextQuarter', 'thisQuarter', 'lastQuarter', 'nextYear', 'thisYear', 'lastYear', 'yearToDate',
40
+ ]
41
+ const typedPeriod = (p: DatePeriod) => p === 'equals' || p === 'before' || p === 'after' || p === 'between'
42
+
43
+ const TEXT_OPS: ReadonlyArray<ExcelFilterOperator> = [
44
+ 'equals', 'notEquals', 'startsWith', 'endsWith', 'contains', 'notContains', 'isBlank', 'isNotBlank',
45
+ ]
46
+ const NUMBER_OPS: ReadonlyArray<ExcelFilterOperator> = [
47
+ 'equals', 'notEquals', 'greaterThan', 'lessThan', 'between', 'isBlank', 'isNotBlank',
48
+ ]
49
+ const ops = $derived(numeric ? NUMBER_OPS : TEXT_OPS)
50
+
51
+ let search = $state('')
52
+ let ticked = $state<Set<string>>(new Set())
53
+ let mode = $state<'values' | 'condition' | 'date' | 'top'>('values')
54
+ let period = $state<DatePeriod>('today')
55
+ let d1 = $state('')
56
+ let d2 = $state('')
57
+ let topSide = $state<'top' | 'bottom'>('top')
58
+ let topCount = $state(10)
59
+ let topUnit = $state<'items' | 'percent'>('items')
60
+ let op1 = $state<ExcelFilterOperator>('equals')
61
+ let v1 = $state('')
62
+ let v1to = $state('')
63
+ let join = $state<'and' | 'or'>('and')
64
+ let op2 = $state<ExcelFilterOperator | ''>('')
65
+ let v2 = $state('')
66
+ let v2to = $state('')
67
+ let searchBox = $state<HTMLInputElement | null>(null)
68
+
69
+ $effect(() => {
70
+ // Open on the column's state: the ticks it has, or the condition it has.
71
+ const f = filter
72
+ const all = values.map((v) => v.text)
73
+ if (f?.kind === 'values') ticked = new Set(f.included ? all.filter((t) => f.included!.includes(t)) : all.filter((t) => !f.excluded.includes(t)))
74
+ else ticked = new Set(all)
75
+ mode = f?.kind === 'condition' ? 'condition' : f?.kind === 'date' ? 'date' : f?.kind === 'top' ? 'top' : 'values'
76
+ period = f?.kind === 'date' ? f.period : 'today'
77
+ d1 = f?.kind === 'date' ? f.value ?? '' : ''
78
+ d2 = f?.kind === 'date' ? f.valueTo ?? '' : ''
79
+ topSide = f?.kind === 'top' && !f.top ? 'bottom' : 'top'
80
+ topCount = f?.kind === 'top' ? f.count : 10
81
+ topUnit = f?.kind === 'top' && f.percent ? 'percent' : 'items'
82
+ if (f?.kind === 'condition') {
83
+ op1 = f.first.op; v1 = f.first.value ?? ''; v1to = f.first.valueTo ?? ''
84
+ join = f.join ?? 'and'
85
+ op2 = f.second?.op ?? ''; v2 = f.second?.value ?? ''; v2to = f.second?.valueTo ?? ''
86
+ } else {
87
+ op1 = 'equals'; v1 = ''; v1to = ''; join = 'and'; op2 = ''; v2 = ''; v2to = ''
88
+ }
89
+ search = ''
90
+ queueMicrotask(() => searchBox?.focus())
91
+ })
92
+
93
+ const shown = $derived.by(() => {
94
+ const needle = search.trim().toLowerCase()
95
+ return needle ? values.filter((v) => v.text.toLowerCase().includes(needle)) : values
96
+ })
97
+ const allShownTicked = $derived(shown.length > 0 && shown.every((v) => ticked.has(v.text)))
98
+ const noneShownTicked = $derived(shown.every((v) => !ticked.has(v.text)))
99
+
100
+ function toggle(text: string) {
101
+ const next = new Set(ticked)
102
+ if (next.has(text)) next.delete(text)
103
+ else next.add(text)
104
+ ticked = next
105
+ mode = 'values'
106
+ }
107
+ function toggleAll() {
108
+ const next = new Set(ticked)
109
+ if (allShownTicked) for (const v of shown) next.delete(v.text)
110
+ else for (const v of shown) next.add(v.text)
111
+ ticked = next
112
+ mode = 'values'
113
+ }
114
+ const needsValue = (op: ExcelFilterOperator | '') => op !== '' && op !== 'isBlank' && op !== 'isNotBlank'
115
+ const conditionValid = $derived(
116
+ (!needsValue(op1) || v1.trim() !== '') && (op1 !== 'between' || v1to.trim() !== '')
117
+ && (op2 === '' || !needsValue(op2) || v2.trim() !== '') && (op2 !== 'between' || v2to.trim() !== ''),
118
+ )
119
+
120
+ const dateValid = $derived(
121
+ !typedPeriod(period) || (d1.trim() !== '' && (period !== 'between' || d2.trim() !== '')),
122
+ )
123
+ const topValid = $derived(Number.isFinite(topCount) && topCount > 0)
124
+
125
+ function ok() {
126
+ if (mode === 'date') {
127
+ if (!dateValid) return
128
+ onApply({ kind: 'date', period, ...(typedPeriod(period) ? { value: d1.trim() } : {}), ...(period === 'between' ? { valueTo: d2.trim() } : {}) })
129
+ return
130
+ }
131
+ if (mode === 'top') {
132
+ if (!topValid) return
133
+ onApply({ kind: 'top', top: topSide === 'top', count: Math.trunc(topCount), ...(topUnit === 'percent' ? { percent: true } : {}) })
134
+ return
135
+ }
136
+ if (mode === 'condition') {
137
+ if (!conditionValid) return
138
+ const first: FilterCondition = { op: op1, ...(needsValue(op1) ? { value: v1.trim() } : {}), ...(op1 === 'between' ? { valueTo: v1to.trim() } : {}) }
139
+ const second: FilterCondition | undefined = op2 === ''
140
+ ? undefined
141
+ : { op: op2, ...(needsValue(op2) ? { value: v2.trim() } : {}), ...(op2 === 'between' ? { valueTo: v2to.trim() } : {}) }
142
+ onApply({ kind: 'condition', first, ...(second ? { join, second } : {}) })
143
+ return
144
+ }
145
+ // A search applies its results, as Excel's does: the values it hides
146
+ // are out, whatever their ticks, and the ticked matches stay.
147
+ const keep = search.trim() ? new Set(shown.filter((v) => ticked.has(v.text)).map((v) => v.text)) : ticked
148
+ onApply(valuesFilter(values.map((v) => v.text), keep))
149
+ }
150
+
151
+ function onKeyDown(event: KeyboardEvent) {
152
+ if (event.key === 'Enter' && !(event.target instanceof HTMLButtonElement)) { event.preventDefault(); ok() }
153
+ }
154
+ </script>
155
+
156
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
157
+ <div class="sv-sheet-filter-menu" role="dialog" tabindex="-1" aria-label={t('filter.label', { header })} onkeydown={onKeyDown}>
158
+ <button type="button" class="row" onclick={() => onSort('asc')}>{t(numeric ? 'filter.sortSmallest' : 'filter.sortAsc')}</button>
159
+ <button type="button" class="row" onclick={() => onSort('desc')}>{t(numeric ? 'filter.sortLargest' : 'filter.sortDesc')}</button>
160
+ <hr />
161
+ <button type="button" class="row" disabled={!filter} onclick={() => onApply(null)}>{t('filter.clear', { header })}</button>
162
+ {#if fills.length > 1}
163
+ <!-- Excel's Filter by Color: the fills the column carries, as swatches. -->
164
+ <details class="conditions colours" open={filter?.kind === 'color'}>
165
+ <summary>{t('filter.byColor')}</summary>
166
+ <div class="swatches" role="group" aria-label={t('filter.byColorGroup')}>
167
+ {#each fills as fill (fill ?? '')}
168
+ <button
169
+ type="button"
170
+ class="swatch"
171
+ class:none={fill === null}
172
+ class:on={filter?.kind === 'color' && (filter.fill ?? '') === (fill ?? '')}
173
+ style:background={fill ?? undefined}
174
+ title={fill ?? t('filter.noFill')}
175
+ aria-label={fill ? t('filter.byFill', { fill }) : t('filter.byNoFill')}
176
+ onclick={() => onApply({ kind: 'color', fill })}
177
+ >{#if fill === null}{t('filter.noFill')}{/if}</button>
178
+ {/each}
179
+ </div>
180
+ </details>
181
+ {/if}
182
+ {#if dates}
183
+ <details class="conditions" open={mode === 'date'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'date' }}>
184
+ <summary>{t('filter.dateFilters')}</summary>
185
+ <div class="condition">
186
+ <select bind:value={period} aria-label={t('filter.datePeriod')} onchange={() => (mode = 'date')}>
187
+ {#each PERIODS as id (id)}<option value={id}>{t(`filter.period.${id}`)}</option>{/each}
188
+ </select>
189
+ {#if typedPeriod(period)}<input type="date" bind:value={d1} aria-label={t('filter.date')} oninput={() => (mode = 'date')} />{/if}
190
+ {#if period === 'between'}<span>{t('filter.and')}</span><input type="date" bind:value={d2} aria-label={t('filter.secondDate')} />{/if}
191
+ </div>
192
+ </details>
193
+ {/if}
194
+ <details class="conditions" open={mode === 'condition'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'condition' }}>
195
+ <summary>{t(numeric ? 'filter.numberFilters' : 'filter.textFilters')}</summary>
196
+ <div class="condition">
197
+ <select bind:value={op1} aria-label={t('filter.firstCondition')} onchange={() => (mode = 'condition')}>
198
+ {#each ops as op (op)}<option value={op}>{t(`filter.op.${op}`)}</option>{/each}
199
+ </select>
200
+ {#if needsValue(op1)}<input type="text" bind:value={v1} aria-label={t('filter.firstValue')} oninput={() => (mode = 'condition')} />{/if}
201
+ {#if op1 === 'between'}<span>{t('filter.and')}</span><input type="text" bind:value={v1to} aria-label={t('filter.firstUpperValue')} />{/if}
202
+ </div>
203
+ <div class="join">
204
+ <label class="check"><input type="radio" name="sv-sheet-filter-join" value="and" bind:group={join} /> {t('filter.joinAnd')}</label>
205
+ <label class="check"><input type="radio" name="sv-sheet-filter-join" value="or" bind:group={join} /> {t('filter.joinOr')}</label>
206
+ </div>
207
+ <div class="condition">
208
+ <select bind:value={op2} aria-label={t('filter.secondCondition')}>
209
+ <option value="">{t('filter.none')}</option>
210
+ {#each ops as op (op)}<option value={op}>{t(`filter.op.${op}`)}</option>{/each}
211
+ </select>
212
+ {#if needsValue(op2)}<input type="text" bind:value={v2} aria-label={t('filter.secondValue')} />{/if}
213
+ {#if op2 === 'between'}<span>{t('filter.and')}</span><input type="text" bind:value={v2to} aria-label={t('filter.secondUpperValue')} />{/if}
214
+ </div>
215
+ </details>
216
+ {#if numeric}
217
+ <details class="conditions" open={mode === 'top'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'top' }}>
218
+ <summary>{t('filter.top10')}</summary>
219
+ <div class="condition top">
220
+ <select bind:value={topSide} aria-label={t('filter.topOrBottom')} onchange={() => (mode = 'top')}>
221
+ <option value="top">{t('filter.top')}</option>
222
+ <option value="bottom">{t('filter.bottom')}</option>
223
+ </select>
224
+ <input type="number" min="1" bind:value={topCount} aria-label={t('filter.howMany')} oninput={() => (mode = 'top')} />
225
+ <select bind:value={topUnit} aria-label={t('filter.itemsOrPercent')}>
226
+ <option value="items">{t('filter.items')}</option>
227
+ <option value="percent">{t('filter.percent')}</option>
228
+ </select>
229
+ </div>
230
+ </details>
231
+ {/if}
232
+ <hr />
233
+ <input bind:this={searchBox} type="search" class="search" placeholder={t('filter.search')} aria-label={t('filter.searchValues')} bind:value={search} />
234
+ <div class="values" role="group" aria-label={t('filter.values')}>
235
+ <label class="check all">
236
+ <input type="checkbox" checked={allShownTicked} indeterminate={!allShownTicked && !noneShownTicked} onchange={toggleAll} />
237
+ {t(search.trim() ? 'filter.selectAllResults' : 'filter.selectAll')}
238
+ </label>
239
+ {#each shown as v (v.text)}
240
+ <label class="check">
241
+ <input type="checkbox" checked={ticked.has(v.text)} onchange={() => toggle(v.text)} />
242
+ <span class="text">{v.text === '' ? t('filter.blanks') : v.text}</span>
243
+ <span class="count">{v.count}</span>
244
+ </label>
245
+ {/each}
246
+ {#if shown.length === 0}<div class="none">{t('filter.noMatches')}</div>{/if}
247
+ </div>
248
+ <div class="sv-sheet-dialog-buttons">
249
+ <button type="button" class="btn primary" onclick={ok} disabled={mode === 'condition' ? !conditionValid : mode === 'date' ? !dateValid : mode === 'top' ? !topValid : noneShownTicked && !search.trim()}>{t('ok')}</button>
250
+ <button type="button" class="btn" onclick={onCancel}>{t('cancel')}</button>
251
+ </div>
252
+ </div>
253
+
254
+ <style>
255
+ .sv-sheet-filter-menu {
256
+ display: flex;
257
+ flex-direction: column;
258
+ gap: 4px;
259
+ width: 260px;
260
+ padding: 6px;
261
+ font-size: 12px;
262
+ color: var(--sg-fg, #242424);
263
+ }
264
+ hr { width: 100%; margin: 2px 0; border: 0; border-top: 1px solid var(--sg-border, #d1d1d1); }
265
+ .row {
266
+ padding: 5px 8px;
267
+ font: inherit;
268
+ text-align: left;
269
+ color: inherit;
270
+ background: transparent;
271
+ border: 0;
272
+ border-radius: 3px;
273
+ cursor: pointer;
274
+ }
275
+ .row:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f0f0f0); }
276
+ .row:disabled { opacity: 0.5; cursor: default; }
277
+ .conditions summary { padding: 5px 8px; cursor: pointer; border-radius: 3px; }
278
+ .conditions summary:hover { background: var(--sg-row-hover-bg, #f0f0f0); }
279
+ .condition, .join { display: flex; align-items: center; gap: 6px; padding: 3px 8px; }
280
+ .condition select { flex: 0 0 120px; }
281
+ .condition input { flex: 1 1 60px; min-width: 40px; }
282
+ .condition.top select { flex: 0 0 80px; }
283
+ .condition.top input { flex: 0 0 56px; }
284
+ .swatches { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 8px; }
285
+ .swatch {
286
+ width: 22px;
287
+ height: 22px;
288
+ padding: 0;
289
+ font: inherit;
290
+ font-size: 10px;
291
+ color: inherit;
292
+ border: 1px solid var(--sg-border, #d1d1d1);
293
+ border-radius: 3px;
294
+ cursor: pointer;
295
+ }
296
+ .swatch.none { width: auto; padding: 0 6px; background: var(--sg-bg, #fff); }
297
+ .swatch.on { outline: 2px solid var(--sg-accent, #217346); outline-offset: 1px; }
298
+ select, input[type="text"], .search {
299
+ height: 24px;
300
+ padding: 0 6px;
301
+ font: inherit;
302
+ color: inherit;
303
+ background: var(--sg-bg, #fff);
304
+ border: 1px solid var(--sg-border, #d1d1d1);
305
+ border-radius: 3px;
306
+ }
307
+ .search { width: 100%; box-sizing: border-box; }
308
+ .values {
309
+ max-height: 180px;
310
+ overflow-y: auto;
311
+ padding: 2px 4px;
312
+ border: 1px solid var(--sg-border, #d1d1d1);
313
+ border-radius: 3px;
314
+ }
315
+ .check { display: flex; align-items: center; gap: 6px; padding: 2px 4px; cursor: default; }
316
+ .check.all { font-weight: 600; }
317
+ .check .text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
318
+ .check .count { color: var(--sg-muted, #616161); }
319
+ .none { padding: 4px; color: var(--sg-muted, #616161); }
320
+ </style>
@@ -0,0 +1,22 @@
1
+ import { type ColumnFilter, type FilterValue } from './sheet/auto-filter.js';
2
+ type Props = {
3
+ /** The header text, for Clear Filter From "X". */
4
+ header: string;
5
+ /** The column's values with their counts. */
6
+ values: ReadonlyArray<FilterValue>;
7
+ /** The filter on the column now, if any. */
8
+ filter: ColumnFilter | null;
9
+ /** Whether the column holds numbers, for Number Filters over Text Filters. */
10
+ numeric: boolean;
11
+ /** Whether the column holds dates, for Date Filters. */
12
+ dates?: boolean;
13
+ /** The fills the column's cells carry (null for none), for Filter by
14
+ * Color; the entry is left off with fewer than two. */
15
+ fills?: ReadonlyArray<string | null>;
16
+ onSort: (direction: 'asc' | 'desc') => void;
17
+ onApply: (filter: ColumnFilter | null) => void;
18
+ onCancel: () => void;
19
+ };
20
+ declare const SvSheetFilterMenu: import("svelte").Component<Props, {}, "">;
21
+ type SvSheetFilterMenu = ReturnType<typeof SvSheetFilterMenu>;
22
+ export default SvSheetFilterMenu;