@svgrid/grid 2.6.1 → 2.6.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 (374) hide show
  1. package/README.md +199 -199
  2. package/dist/FlexRender.svelte +96 -96
  3. package/dist/GridFooter.svelte +178 -178
  4. package/dist/GridMenus.svelte +705 -705
  5. package/dist/SvAutoComplete.svelte +165 -165
  6. package/dist/SvAvatar.svelte +75 -75
  7. package/dist/SvCalendar.svelte +503 -503
  8. package/dist/SvCarousel.svelte +141 -141
  9. package/dist/SvCheckBox.svelte +102 -102
  10. package/dist/SvCircularProgress.svelte +109 -109
  11. package/dist/SvColorInput.svelte +181 -181
  12. package/dist/SvComboBox.svelte +275 -275
  13. package/dist/SvContextMenu.svelte +116 -116
  14. package/dist/SvCountryInput.svelte +162 -162
  15. package/dist/SvDrawer.svelte +254 -254
  16. package/dist/SvDropDownList.svelte +374 -374
  17. package/dist/SvDurationInput.svelte +126 -126
  18. package/dist/SvField.svelte +293 -293
  19. package/dist/SvForm.svelte +437 -437
  20. package/dist/SvGrid.controller.svelte.js +22 -10
  21. package/dist/SvGrid.css +2814 -2814
  22. package/dist/SvGrid.svelte +3490 -3490
  23. package/dist/SvGridChart.svelte +1716 -1716
  24. package/dist/SvGridChartPanel.svelte +485 -485
  25. package/dist/SvGridChartView.svelte +70 -70
  26. package/dist/SvGridDropdown.svelte +728 -728
  27. package/dist/SvGridSelect.svelte +266 -266
  28. package/dist/SvGroupCell.svelte +116 -116
  29. package/dist/SvListBox.svelte +326 -326
  30. package/dist/SvMaskedInput.svelte +122 -122
  31. package/dist/SvMenu.svelte +124 -124
  32. package/dist/SvMenuList.svelte +146 -146
  33. package/dist/SvMultiSelect.svelte +289 -289
  34. package/dist/SvNumberInput.svelte +168 -168
  35. package/dist/SvOtpInput.svelte +158 -158
  36. package/dist/SvPasswordInput.svelte +151 -151
  37. package/dist/SvPhoneInput.svelte +133 -133
  38. package/dist/SvPopover.svelte +197 -197
  39. package/dist/SvProgress.svelte +116 -116
  40. package/dist/SvRadioGroup.svelte +107 -107
  41. package/dist/SvRating.svelte +112 -112
  42. package/dist/SvResult.svelte +73 -73
  43. package/dist/SvRichText.svelte +211 -211
  44. package/dist/SvRowGroupPanel.svelte +170 -170
  45. package/dist/SvScrollArea.svelte +61 -61
  46. package/dist/SvSlider.svelte +202 -202
  47. package/dist/SvSwitchButton.svelte +108 -108
  48. package/dist/SvTagsInput.svelte +114 -114
  49. package/dist/SvTextInput.svelte +147 -147
  50. package/dist/SvTimePicker.svelte +245 -245
  51. package/dist/SvToaster.svelte +159 -159
  52. package/dist/SvToggleButton.svelte +85 -85
  53. package/dist/SvTooltip.svelte +161 -161
  54. package/dist/SvTour.svelte +208 -208
  55. package/dist/SvTree.svelte +444 -444
  56. package/dist/SvTreeSelect.svelte +235 -235
  57. package/dist/cdn/{GridMenus-DfmxE2Tb.js → GridMenus-BoVKgAv8.js} +9 -9
  58. package/dist/cdn/{GridMenus-CaaYtSpU.js → GridMenus-DL1zrDwf.js} +9 -9
  59. package/dist/cdn/{SvDateTimePicker-DSUhIta8.js → SvDateTimePicker-CHnUkWcH.js} +2 -2
  60. package/dist/cdn/{SvDateTimePicker-h9kPyszT.js → SvDateTimePicker-CRQH_U7E.js} +2 -2
  61. package/dist/cdn/{SvGridChart-CwhFz7GV.js → SvGridChart-BEJmNNx9.js} +1 -1
  62. package/dist/cdn/{SvGridChart-Bs2GIR2Q.js → SvGridChart-BwVos976.js} +1 -1
  63. package/dist/cdn/{SvGridChartPanel-1WXuStzM.js → SvGridChartPanel-BOknOkrP.js} +1 -1
  64. package/dist/cdn/{SvGridChartPanel-e5_nqNP9.js → SvGridChartPanel-D2PjII4O.js} +1 -1
  65. package/dist/cdn/{SvGridChartView-SmPW10dI.js → SvGridChartView-00LPUHL1.js} +1 -1
  66. package/dist/cdn/{SvGridChartView-eSPuJE6g.js → SvGridChartView-BhUEJ5ki.js} +1 -1
  67. package/dist/cdn/{SvGridDropdown-B1ZcLpgs.js → SvGridDropdown-D0VdjeR8.js} +1 -1
  68. package/dist/cdn/{SvGridDropdown-CtdbHcIS.js → SvGridDropdown-D13MtJ2j.js} +1 -1
  69. package/dist/cdn/{src-BIIhU1uh.js → src-CEpw6Ato.js} +2885 -2863
  70. package/dist/cdn/{src-DisUdSk9.js → src-M2NfKnjX.js} +2106 -2084
  71. package/dist/cdn/svgrid.js +8 -8
  72. package/dist/cdn/svgrid.svelte-external.js +8 -8
  73. package/dist/chart-export.js +8 -8
  74. package/dist/filtering/excel-filters.d.ts +14 -0
  75. package/dist/filtering/excel-filters.js +67 -32
  76. package/dist/index.d.ts +1 -1
  77. package/dist/index.js +1 -1
  78. package/package.json +11 -11
  79. package/src/FlexRender.svelte +96 -96
  80. package/src/GridFooter.svelte +178 -178
  81. package/src/GridMenus.svelte +705 -705
  82. package/src/SvAutoComplete.svelte +165 -165
  83. package/src/SvAvatar.svelte +75 -75
  84. package/src/SvCalendar.svelte +503 -503
  85. package/src/SvCalendar.test.ts +226 -226
  86. package/src/SvCarousel.svelte +141 -141
  87. package/src/SvCheckBox.svelte +102 -102
  88. package/src/SvCircularProgress.svelte +109 -109
  89. package/src/SvColorInput.svelte +181 -181
  90. package/src/SvComboBox.svelte +275 -275
  91. package/src/SvContextMenu.svelte +116 -116
  92. package/src/SvCountryInput.svelte +162 -162
  93. package/src/SvDrawer.svelte +254 -254
  94. package/src/SvDropDownList.svelte +374 -374
  95. package/src/SvDurationInput.svelte +126 -126
  96. package/src/SvField.svelte +293 -293
  97. package/src/SvForm.svelte +437 -437
  98. package/src/SvForm.test.ts +411 -411
  99. package/src/SvGrid.controller.svelte.ts +3691 -3680
  100. package/src/SvGrid.css +2814 -2814
  101. package/src/SvGrid.svelte +3490 -3490
  102. package/src/SvGrid.types.ts +1708 -1708
  103. package/src/SvGridChart.svelte +1716 -1716
  104. package/src/SvGridChartPanel.svelte +485 -485
  105. package/src/SvGridChartView.svelte +70 -70
  106. package/src/SvGridDropdown.svelte +728 -728
  107. package/src/SvGridSelect.svelte +266 -266
  108. package/src/SvGroupCell.svelte +116 -116
  109. package/src/SvListBox.svelte +326 -326
  110. package/src/SvMaskedInput.svelte +122 -122
  111. package/src/SvMenu.svelte +124 -124
  112. package/src/SvMenu.test.ts +97 -97
  113. package/src/SvMenuList.svelte +146 -146
  114. package/src/SvMultiSelect.svelte +289 -289
  115. package/src/SvNumberInput.svelte +168 -168
  116. package/src/SvOtpInput.svelte +158 -158
  117. package/src/SvPasswordInput.svelte +151 -151
  118. package/src/SvPhoneInput.svelte +133 -133
  119. package/src/SvPopover.svelte +197 -197
  120. package/src/SvProgress.svelte +116 -116
  121. package/src/SvRadioGroup.svelte +107 -107
  122. package/src/SvRating.svelte +112 -112
  123. package/src/SvResult.svelte +73 -73
  124. package/src/SvRichText.svelte +211 -211
  125. package/src/SvRowGroupPanel.svelte +170 -170
  126. package/src/SvScrollArea.svelte +61 -61
  127. package/src/SvSlider.svelte +202 -202
  128. package/src/SvSwitchButton.svelte +108 -108
  129. package/src/SvTagsInput.svelte +114 -114
  130. package/src/SvTextInput.svelte +147 -147
  131. package/src/SvTimePicker.svelte +245 -245
  132. package/src/SvToaster.svelte +159 -159
  133. package/src/SvToaster.test.ts +95 -95
  134. package/src/SvToggleButton.svelte +85 -85
  135. package/src/SvTooltip.svelte +161 -161
  136. package/src/SvTour.svelte +208 -208
  137. package/src/SvTree.svelte +444 -444
  138. package/src/SvTreeSelect.svelte +235 -235
  139. package/src/a11y/dismissable.test.ts +119 -119
  140. package/src/a11y/dismissable.ts +114 -114
  141. package/src/a11y.contract.test.ts +49 -49
  142. package/src/a11y.test.ts +59 -59
  143. package/src/a11y.ts +61 -61
  144. package/src/ai.test.ts +502 -502
  145. package/src/ai.ts +1391 -1391
  146. package/src/build-api.coverage.test.ts +633 -633
  147. package/src/build-api.ts +805 -805
  148. package/src/builtin-editors.grid.test.ts +85 -85
  149. package/src/cell-formatting.ts +169 -169
  150. package/src/cell-render.test.ts +513 -513
  151. package/src/cell-render.ts +496 -496
  152. package/src/cell-values.ts +118 -118
  153. package/src/chart-export.ts +201 -201
  154. package/src/chart-view.svelte.ts +36 -36
  155. package/src/chart.ts +2295 -2295
  156. package/src/collaboration.test.ts +104 -104
  157. package/src/collaboration.ts +167 -167
  158. package/src/core.performance.test.ts +30 -30
  159. package/src/core.ts +1261 -1261
  160. package/src/createAutocomplete.svelte.ts +132 -132
  161. package/src/createCombobox.svelte.ts +191 -191
  162. package/src/createCountryInput.svelte.ts +157 -157
  163. package/src/createDropdownList.svelte.ts +168 -168
  164. package/src/createForm.svelte.ts +386 -386
  165. package/src/createGrid.svelte.ts +42 -42
  166. package/src/createGrid.test.ts +10 -10
  167. package/src/createGridState.svelte.ts +17 -17
  168. package/src/createListbox.svelte.ts +250 -250
  169. package/src/createMenu.svelte.ts +224 -224
  170. package/src/createPopoverSelect.svelte.ts +213 -213
  171. package/src/createSlider.svelte.ts +191 -191
  172. package/src/createTooltip.svelte.ts +144 -144
  173. package/src/createTree.svelte.ts +319 -319
  174. package/src/editing.test.ts +949 -949
  175. package/src/editing.ts +606 -606
  176. package/src/editor-contract.ts +170 -170
  177. package/src/editor-registry.grid.test.ts +144 -144
  178. package/src/editor-registry.ts +122 -122
  179. package/src/export-data-api.test.ts +126 -126
  180. package/src/export-format.test.ts +107 -107
  181. package/src/export-format.ts +601 -601
  182. package/src/filter-operators.ts +157 -157
  183. package/src/filtering/excel-filters.ts +71 -34
  184. package/src/flex-render.ts +3 -3
  185. package/src/form-field.ts +127 -127
  186. package/src/group-display.test.ts +167 -167
  187. package/src/group-display.ts +200 -200
  188. package/src/index.ts +726 -724
  189. package/src/js-scroller.svelte.ts +173 -173
  190. package/src/keyboard-handlers.ts +270 -270
  191. package/src/keyboard.test.ts +59 -59
  192. package/src/keyboard.ts +97 -97
  193. package/src/list-nav.test.ts +49 -49
  194. package/src/list-nav.ts +29 -29
  195. package/src/list-option.test.ts +56 -56
  196. package/src/list-option.ts +172 -172
  197. package/src/menus.ts +567 -567
  198. package/src/merge-objects.ts +48 -48
  199. package/src/overlays.test.ts +90 -90
  200. package/src/render-component.ts +28 -28
  201. package/src/row-resize.ts +210 -210
  202. package/src/scheduler-model.test.ts +562 -562
  203. package/src/scheduler-model.ts +872 -872
  204. package/src/selection.test.ts +754 -754
  205. package/src/selection.ts +491 -491
  206. package/src/server-data-source.test.ts +289 -289
  207. package/src/server-data-source.ts +413 -413
  208. package/src/sparkline.test.ts +68 -68
  209. package/src/sparkline.ts +169 -169
  210. package/src/spreadsheet.test.ts +488 -488
  211. package/src/spreadsheet.ts +312 -312
  212. package/src/static-functions.ts +11 -11
  213. package/src/subscribe.ts +38 -38
  214. package/src/svgrid-wrapper.types.ts +526 -526
  215. package/src/svgrid.async-editor-options.test.ts +271 -271
  216. package/src/svgrid.auto-row-height.test.ts +204 -204
  217. package/src/svgrid.behavior.test.ts +705 -705
  218. package/src/svgrid.charting.test.ts +534 -534
  219. package/src/svgrid.comments-autocomplete.test.ts +123 -123
  220. package/src/svgrid.context-menu.test.ts +147 -147
  221. package/src/svgrid.features.test.ts +157 -157
  222. package/src/svgrid.filter-depth.test.ts +163 -163
  223. package/src/svgrid.filter-menu-listbox.svelte.test.ts +331 -331
  224. package/src/svgrid.filter-menu-scroll.test.ts +112 -112
  225. package/src/svgrid.grand-total.test.ts +188 -188
  226. package/src/svgrid.group-display-mode.test.ts +171 -171
  227. package/src/svgrid.group-footers.test.ts +121 -121
  228. package/src/svgrid.group-pagination.test.ts +153 -153
  229. package/src/svgrid.new-features.wrapper.test.ts +251 -251
  230. package/src/svgrid.tree-data.test.ts +186 -186
  231. package/src/svgrid.wrapper.test.ts +42 -40
  232. package/src/svgriddropdown.async-panel.svelte.test.ts +195 -195
  233. package/src/test-setup.ts +62 -62
  234. package/src/themes/index.ts +278 -278
  235. package/src/toast-store.svelte.ts +246 -246
  236. package/src/toast-store.test.ts +147 -147
  237. package/src/tree-row-model.test.ts +168 -168
  238. package/src/ui-buttons.test.ts +144 -144
  239. package/src/ui-inputs.test.ts +118 -118
  240. package/src/ui-localization.test.ts +113 -113
  241. package/src/ui-range.test.ts +70 -70
  242. package/src/ui-selection.test.ts +155 -155
  243. package/src/ui-tier1.test.ts +142 -142
  244. package/src/virtual.test.ts +88 -88
  245. package/src/virtualization/column-virtualizer.test.ts +27 -27
  246. package/src/virtualization/column-virtualizer.ts +30 -30
  247. package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
  248. package/src/virtualization/types.ts +30 -30
  249. package/src/virtualization/virtualizer.test.ts +47 -47
  250. package/src/virtualization/virtualizer.ts +296 -296
  251. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/_svelte_metadata.json +0 -1
  252. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/_metadata.json +0 -178
  253. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js +0 -3843
  254. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js.map +0 -1
  255. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js +0 -23
  256. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js.map +0 -1
  257. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js +0 -1925
  258. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js.map +0 -1
  259. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js +0 -206
  260. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js.map +0 -1
  261. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js +0 -20
  262. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js.map +0 -1
  263. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js +0 -264
  264. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js.map +0 -1
  265. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js +0 -698
  266. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js.map +0 -1
  267. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/package.json +0 -3
  268. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js +0 -135
  269. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js.map +0 -1
  270. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js +0 -57
  271. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js.map +0 -1
  272. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_attachments.js +0 -2
  273. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js +0 -46691
  274. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js.map +0 -1
  275. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js +0 -239
  276. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js.map +0 -1
  277. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_events.js +0 -2
  278. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js +0 -6
  279. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js.map +0 -1
  280. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_client.js +0 -7
  281. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js +0 -6
  282. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  283. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js +0 -7
  284. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  285. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js +0 -7
  286. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  287. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js +0 -7
  288. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  289. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_server.js +0 -6
  290. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js +0 -85
  291. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js.map +0 -1
  292. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js +0 -561
  293. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js.map +0 -1
  294. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js +0 -26
  295. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js.map +0 -1
  296. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js +0 -124
  297. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  298. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_server.js +0 -2
  299. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js +0 -91
  300. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js.map +0 -1
  301. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js +0 -242
  302. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js.map +0 -1
  303. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js +0 -497
  304. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js.map +0 -1
  305. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js +0 -4929
  306. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js.map +0 -1
  307. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js +0 -192
  308. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js.map +0 -1
  309. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js +0 -10
  310. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js.map +0 -1
  311. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js +0 -140
  312. package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js.map +0 -1
  313. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/_svelte_metadata.json +0 -1
  314. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/_metadata.json +0 -178
  315. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js +0 -3843
  316. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js.map +0 -1
  317. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js +0 -23
  318. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js.map +0 -1
  319. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js +0 -1925
  320. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js.map +0 -1
  321. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js +0 -206
  322. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js.map +0 -1
  323. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js +0 -20
  324. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js.map +0 -1
  325. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js +0 -264
  326. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js.map +0 -1
  327. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js +0 -698
  328. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js.map +0 -1
  329. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/package.json +0 -3
  330. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js +0 -135
  331. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js.map +0 -1
  332. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js +0 -57
  333. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js.map +0 -1
  334. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_attachments.js +0 -2
  335. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js +0 -46691
  336. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js.map +0 -1
  337. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js +0 -239
  338. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js.map +0 -1
  339. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_events.js +0 -2
  340. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js +0 -6
  341. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js.map +0 -1
  342. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_client.js +0 -7
  343. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js +0 -6
  344. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  345. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js +0 -7
  346. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  347. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js +0 -7
  348. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  349. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js +0 -7
  350. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  351. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_server.js +0 -6
  352. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js +0 -85
  353. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js.map +0 -1
  354. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js +0 -561
  355. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js.map +0 -1
  356. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js +0 -26
  357. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js.map +0 -1
  358. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js +0 -124
  359. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  360. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_server.js +0 -2
  361. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js +0 -91
  362. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js.map +0 -1
  363. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js +0 -242
  364. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js.map +0 -1
  365. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js +0 -497
  366. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js.map +0 -1
  367. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js +0 -4929
  368. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js.map +0 -1
  369. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js +0 -192
  370. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js.map +0 -1
  371. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js +0 -10
  372. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js.map +0 -1
  373. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js +0 -140
  374. package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js.map +0 -1
@@ -1,254 +1,254 @@
1
- <script lang="ts">
2
- /**
3
- * SvDrawer - an edge-anchored side sheet (right / left / top / bottom): a
4
- * backdrop, a sliding panel, and the full dialog a11y contract. Built entirely
5
- * on the shared primitives - `createFocusTrap`, `lockScroll` and
6
- * `createDismissableLayer` - so its focus, scroll-lock and Escape/backdrop
7
- * behaviour is identical to SvModal and nested overlays close top-first.
8
- * Portalled to <body>. Controlled via `open`.
9
- *
10
- * ```svelte
11
- * <SvDrawer bind:open side="right" title="Filters">
12
- * <p>Body</p>
13
- * {#snippet footer()}<button onclick={() => open = false}>Apply</button>{/snippet}
14
- * </SvDrawer>
15
- * ```
16
- */
17
- import type { Snippet } from 'svelte'
18
- import { untrack } from 'svelte'
19
- import { portalToBody } from './popover'
20
- import { nextEditorId } from './editor-contract'
21
- import { createOverlay } from './createOverlay.svelte'
22
-
23
- /** Edge the drawer slides from. Kept in sync with the `DrawerSide` export in
24
- * index.ts (a bare type-only module script trips the Svelte/Vite parser). */
25
- type DrawerSide = 'right' | 'left' | 'top' | 'bottom'
26
-
27
- type Props = {
28
- open?: boolean
29
- onClose?: () => void
30
- /** Edge the drawer slides from. Default 'right'. */
31
- side?: DrawerSide
32
- /** Panel size along its axis (width for left/right, height for top/bottom).
33
- * Any CSS length; defaults to a sensible per-axis value. */
34
- size?: string
35
- title?: string
36
- closeOnBackdrop?: boolean
37
- closeOnEsc?: boolean
38
- /** Hide the header close (x) button. */
39
- hideClose?: boolean
40
- /** Render as a mobile bottom-sheet: bottom-anchored, rounded top, a grab
41
- * handle, and swipe-down-to-close. Overrides `side`. */
42
- sheet?: boolean
43
- /** Accessible name when there is no visible `title`. */
44
- ariaLabel?: string
45
- /** Fired after the close (exit) animation has finished and the drawer has
46
- * left the DOM. Use it to clear the data the drawer was showing so the
47
- * content stays put while it slides out. */
48
- onClosed?: () => void
49
- children?: Snippet
50
- footer?: Snippet
51
- }
52
-
53
- let {
54
- open = $bindable(false),
55
- onClose,
56
- side = 'right',
57
- size,
58
- title,
59
- closeOnBackdrop = true,
60
- closeOnEsc = true,
61
- hideClose = false,
62
- sheet = false,
63
- ariaLabel,
64
- onClosed,
65
- children,
66
- footer,
67
- }: Props = $props()
68
-
69
- const titleId = nextEditorId('sv-drawer-title')
70
- let dialogEl = $state<HTMLDivElement | null>(null)
71
-
72
- // A sheet is a bottom drawer with mobile affordances.
73
- const effectiveSide = $derived<DrawerSide>(sheet ? 'bottom' : side)
74
- const horizontal = $derived(effectiveSide === 'left' || effectiveSide === 'right')
75
- const sizeVar = $derived(size ?? (horizontal ? 'min(400px, 92vw)' : 'min(360px, 85vh)'))
76
-
77
- function close() { open = false; onClose?.() }
78
-
79
- // Enter/exit animation via CSS @keyframes (the pattern SvModal uses - keyframes
80
- // play on a `use:portalToBody` element; the Svelte `transition:` directive does
81
- // NOT). `show` keeps the panel mounted; the enter keyframe fires on mount, and
82
- // on close we add `is-leaving` (exit keyframe) and unmount + fire `onClosed`
83
- // after the duration. Honors reduced-motion by dropping the hold to 0ms.
84
- const reduceMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches
85
- const EXIT_MS = 260
86
- let show = $state(false)
87
- let leaving = $state(false)
88
- let leaveTimer: ReturnType<typeof setTimeout> | undefined
89
- $effect(() => {
90
- if (open) {
91
- clearTimeout(leaveTimer)
92
- leaving = false
93
- show = true
94
- return
95
- }
96
- // Only run the leave sequence if the drawer was actually shown (skips the
97
- // initial closed mount, which must not fire onClosed).
98
- if (untrack(() => show)) {
99
- leaving = true
100
- leaveTimer = setTimeout(() => { show = false; leaving = false; onClosed?.() }, reduceMotion ? 0 : EXIT_MS)
101
- }
102
- // `open` is this effect's only dependency, so the cleanup runs on reopen (a
103
- // no-op after the clearTimeout above) or on destroy - where it matters, so a
104
- // drawer unmounted mid-exit doesn't leave a timer firing into a dead scope.
105
- return () => clearTimeout(leaveTimer)
106
- })
107
-
108
- // Swipe-down-to-close for the sheet grab handle.
109
- let dragY = $state(0)
110
- let dragging = $state(false)
111
- let dragStartY = 0
112
- function onGrabDown(e: PointerEvent) {
113
- dragging = true
114
- dragStartY = e.clientY
115
- ;(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId)
116
- }
117
- function onGrabMove(e: PointerEvent) {
118
- if (!dragging) return
119
- dragY = Math.max(0, e.clientY - dragStartY)
120
- }
121
- function onGrabUp(e: PointerEvent) {
122
- if (!dragging) return
123
- dragging = false
124
- ;(e.currentTarget as HTMLElement).releasePointerCapture?.(e.pointerId)
125
- if (dragY > 80) close()
126
- else dragY = 0
127
- }
128
-
129
- // Focus trap + scroll lock + Escape/backdrop dismissal come from the shared
130
- // headless overlay core - one tested implementation across every dialog-like
131
- // overlay, and nested overlays close top-first. See createOverlay.svelte.ts.
132
- const overlay = createOverlay({
133
- open: () => open,
134
- getDialog: () => dialogEl,
135
- onClose: close,
136
- closeOnEsc: () => closeOnEsc,
137
- closeOnBackdrop: () => closeOnBackdrop,
138
- onOpen: () => { dragY = 0 },
139
- })
140
- </script>
141
-
142
- {#if show}
143
- <div class="sv-drawer__backdrop" class:is-leaving={leaving} use:portalToBody>
144
- <div
145
- bind:this={dialogEl}
146
- class="sv-drawer sv-drawer--{effectiveSide}"
147
- class:is-leaving={leaving}
148
- class:is-sheet={sheet}
149
- class:is-dragging={dragging}
150
- {...overlay.dialogProps({ labelledBy: title ? titleId : undefined, label: !title ? ariaLabel : undefined })}
151
- style:--sv-drawer-size={sizeVar}
152
- style:transform={sheet && dragY ? `translateY(${dragY}px)` : undefined}
153
- >
154
- {#if sheet}
155
- <!-- svelte-ignore a11y_no_static_element_interactions -->
156
- <div
157
- class="sv-drawer__grab"
158
- aria-hidden="true"
159
- onpointerdown={onGrabDown}
160
- onpointermove={onGrabMove}
161
- onpointerup={onGrabUp}
162
- onpointercancel={onGrabUp}
163
- ><span></span></div>
164
- {/if}
165
- {#if title || !hideClose}
166
- <div class="sv-drawer__header">
167
- <h2 class="sv-drawer__title" id={titleId}>{title ?? ''}</h2>
168
- {#if !hideClose}
169
- <button type="button" class="sv-drawer__x" aria-label="Close" onclick={close}>&times;</button>
170
- {/if}
171
- </div>
172
- {/if}
173
- <div class="sv-drawer__body">{@render children?.()}</div>
174
- {#if footer}<div class="sv-drawer__footer">{@render footer()}</div>{/if}
175
- </div>
176
- </div>
177
- {/if}
178
-
179
- <style>
180
- :global(.sv-drawer__backdrop) {
181
- position: fixed; inset: 0; z-index: 2147483000;
182
- background: rgba(15, 23, 42, 0.45); backdrop-filter: blur(1.5px);
183
- animation: sv-drawer-bd-in 0.2s ease backwards;
184
- }
185
- :global(.sv-drawer__backdrop.is-leaving) { animation: sv-drawer-bd-out 0.2s ease forwards; }
186
- @keyframes sv-drawer-bd-in { from { opacity: 0 } to { opacity: 1 } }
187
- @keyframes sv-drawer-bd-out { from { opacity: 1 } to { opacity: 0 } }
188
-
189
- :global(.sv-drawer) {
190
- position: fixed;
191
- display: flex; flex-direction: column;
192
- background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a);
193
- box-shadow: 0 24px 64px -16px rgba(15, 23, 42, 0.5);
194
- overflow: hidden;
195
- /* Slide in on mount; `backwards` fill shows the off-screen start frame with no
196
- flash, and does NOT hold the end frame - so the sheet drag transform wins. */
197
- animation: sv-drawer-in 0.26s cubic-bezier(0.16, 1, 0.3, 1) backwards;
198
- }
199
- /* Exit keyframe; `forwards` fill holds the off-screen frame until we unmount. */
200
- :global(.sv-drawer.is-leaving) { animation: sv-drawer-out 0.26s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
201
- /* Off-screen vector per edge - the enter/exit keyframes read `--sv-off`. `side`
202
- is a stated physical edge (like SvToaster's position prop), not a text-flow
203
- "start/end" - so it stays physical left/right regardless of page dir. */
204
- :global(.sv-drawer--right), :global(.sv-drawer--left) {
205
- top: 0; bottom: 0; width: var(--sv-drawer-size); max-width: 100vw;
206
- }
207
- :global(.sv-drawer--right) { right: 0; border-left: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateX(100%); }
208
- :global(.sv-drawer--left) { left: 0; border-right: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateX(-100%); }
209
- /* Top / bottom: full width, fixed height, slide along Y. */
210
- :global(.sv-drawer--top), :global(.sv-drawer--bottom) {
211
- left: 0; right: 0; height: var(--sv-drawer-size); max-height: 100vh;
212
- }
213
- :global(.sv-drawer--top) { top: 0; border-bottom: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateY(-100%); }
214
- :global(.sv-drawer--bottom) { bottom: 0; border-top: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateY(100%); }
215
- @keyframes sv-drawer-in { from { transform: var(--sv-off) } to { transform: none } }
216
- @keyframes sv-drawer-out { from { transform: none } to { transform: var(--sv-off) } }
217
-
218
- /* Mobile bottom-sheet: centered, fixed width, rounded top, grab handle. Slides
219
- along Y like a bottom drawer (enter/exit keyframes read --sv-off from --bottom). */
220
- :global(.sv-drawer.is-sheet) {
221
- left: 0; right: 0; margin: 0 auto; top: auto;
222
- width: min(560px, 100vw); height: auto; max-height: 85vh;
223
- border: 1px solid var(--sg-border, #e2e8f0); border-bottom: 0;
224
- border-radius: 16px 16px 0 0;
225
- }
226
- /* No transition while the user is dragging the grab handle - follow the finger. */
227
- :global(.sv-drawer.is-dragging) { transition: none; }
228
- :global(.sv-drawer__grab) {
229
- flex: none; display: grid; place-items: center; padding: 8px 0 2px; cursor: grab; touch-action: none;
230
- }
231
- :global(.sv-drawer__grab span) {
232
- display: block; width: 40px; height: 4px; border-radius: 999px; background: var(--sg-border, #cbd5e1);
233
- }
234
- @media (prefers-reduced-motion: reduce) {
235
- :global(.sv-drawer__backdrop), :global(.sv-drawer__backdrop.is-leaving),
236
- :global(.sv-drawer), :global(.sv-drawer.is-leaving) { animation: none; }
237
- }
238
-
239
- :global(.sv-drawer__header) {
240
- display: flex; align-items: center; gap: 12px; padding: 13px 16px;
241
- border-bottom: 1px solid var(--sg-border, #e2e8f0);
242
- }
243
- :global(.sv-drawer__title) { flex: 1; margin: 0; font-size: 15px; font-weight: 650; }
244
- :global(.sv-drawer__x) {
245
- flex: none; width: 28px; height: 28px; display: grid; place-items: center;
246
- background: none; border: 0; color: var(--sg-muted, #64748b); cursor: pointer; border-radius: 6px; font-size: 20px; line-height: 1;
247
- }
248
- :global(.sv-drawer__x:hover) { background: var(--sg-row-hover-bg, #f1f5f9); color: var(--sg-fg, #0f172a); }
249
- :global(.sv-drawer__body) { padding: 16px; overflow: auto; flex: 1; font-size: 13.5px; line-height: 1.6; }
250
- :global(.sv-drawer__footer) {
251
- display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px;
252
- border-top: 1px solid var(--sg-border, #e2e8f0);
253
- }
254
- </style>
1
+ <script lang="ts">
2
+ /**
3
+ * SvDrawer - an edge-anchored side sheet (right / left / top / bottom): a
4
+ * backdrop, a sliding panel, and the full dialog a11y contract. Built entirely
5
+ * on the shared primitives - `createFocusTrap`, `lockScroll` and
6
+ * `createDismissableLayer` - so its focus, scroll-lock and Escape/backdrop
7
+ * behaviour is identical to SvModal and nested overlays close top-first.
8
+ * Portalled to <body>. Controlled via `open`.
9
+ *
10
+ * ```svelte
11
+ * <SvDrawer bind:open side="right" title="Filters">
12
+ * <p>Body</p>
13
+ * {#snippet footer()}<button onclick={() => open = false}>Apply</button>{/snippet}
14
+ * </SvDrawer>
15
+ * ```
16
+ */
17
+ import type { Snippet } from 'svelte'
18
+ import { untrack } from 'svelte'
19
+ import { portalToBody } from './popover'
20
+ import { nextEditorId } from './editor-contract'
21
+ import { createOverlay } from './createOverlay.svelte'
22
+
23
+ /** Edge the drawer slides from. Kept in sync with the `DrawerSide` export in
24
+ * index.ts (a bare type-only module script trips the Svelte/Vite parser). */
25
+ type DrawerSide = 'right' | 'left' | 'top' | 'bottom'
26
+
27
+ type Props = {
28
+ open?: boolean
29
+ onClose?: () => void
30
+ /** Edge the drawer slides from. Default 'right'. */
31
+ side?: DrawerSide
32
+ /** Panel size along its axis (width for left/right, height for top/bottom).
33
+ * Any CSS length; defaults to a sensible per-axis value. */
34
+ size?: string
35
+ title?: string
36
+ closeOnBackdrop?: boolean
37
+ closeOnEsc?: boolean
38
+ /** Hide the header close (x) button. */
39
+ hideClose?: boolean
40
+ /** Render as a mobile bottom-sheet: bottom-anchored, rounded top, a grab
41
+ * handle, and swipe-down-to-close. Overrides `side`. */
42
+ sheet?: boolean
43
+ /** Accessible name when there is no visible `title`. */
44
+ ariaLabel?: string
45
+ /** Fired after the close (exit) animation has finished and the drawer has
46
+ * left the DOM. Use it to clear the data the drawer was showing so the
47
+ * content stays put while it slides out. */
48
+ onClosed?: () => void
49
+ children?: Snippet
50
+ footer?: Snippet
51
+ }
52
+
53
+ let {
54
+ open = $bindable(false),
55
+ onClose,
56
+ side = 'right',
57
+ size,
58
+ title,
59
+ closeOnBackdrop = true,
60
+ closeOnEsc = true,
61
+ hideClose = false,
62
+ sheet = false,
63
+ ariaLabel,
64
+ onClosed,
65
+ children,
66
+ footer,
67
+ }: Props = $props()
68
+
69
+ const titleId = nextEditorId('sv-drawer-title')
70
+ let dialogEl = $state<HTMLDivElement | null>(null)
71
+
72
+ // A sheet is a bottom drawer with mobile affordances.
73
+ const effectiveSide = $derived<DrawerSide>(sheet ? 'bottom' : side)
74
+ const horizontal = $derived(effectiveSide === 'left' || effectiveSide === 'right')
75
+ const sizeVar = $derived(size ?? (horizontal ? 'min(400px, 92vw)' : 'min(360px, 85vh)'))
76
+
77
+ function close() { open = false; onClose?.() }
78
+
79
+ // Enter/exit animation via CSS @keyframes (the pattern SvModal uses - keyframes
80
+ // play on a `use:portalToBody` element; the Svelte `transition:` directive does
81
+ // NOT). `show` keeps the panel mounted; the enter keyframe fires on mount, and
82
+ // on close we add `is-leaving` (exit keyframe) and unmount + fire `onClosed`
83
+ // after the duration. Honors reduced-motion by dropping the hold to 0ms.
84
+ const reduceMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches
85
+ const EXIT_MS = 260
86
+ let show = $state(false)
87
+ let leaving = $state(false)
88
+ let leaveTimer: ReturnType<typeof setTimeout> | undefined
89
+ $effect(() => {
90
+ if (open) {
91
+ clearTimeout(leaveTimer)
92
+ leaving = false
93
+ show = true
94
+ return
95
+ }
96
+ // Only run the leave sequence if the drawer was actually shown (skips the
97
+ // initial closed mount, which must not fire onClosed).
98
+ if (untrack(() => show)) {
99
+ leaving = true
100
+ leaveTimer = setTimeout(() => { show = false; leaving = false; onClosed?.() }, reduceMotion ? 0 : EXIT_MS)
101
+ }
102
+ // `open` is this effect's only dependency, so the cleanup runs on reopen (a
103
+ // no-op after the clearTimeout above) or on destroy - where it matters, so a
104
+ // drawer unmounted mid-exit doesn't leave a timer firing into a dead scope.
105
+ return () => clearTimeout(leaveTimer)
106
+ })
107
+
108
+ // Swipe-down-to-close for the sheet grab handle.
109
+ let dragY = $state(0)
110
+ let dragging = $state(false)
111
+ let dragStartY = 0
112
+ function onGrabDown(e: PointerEvent) {
113
+ dragging = true
114
+ dragStartY = e.clientY
115
+ ;(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId)
116
+ }
117
+ function onGrabMove(e: PointerEvent) {
118
+ if (!dragging) return
119
+ dragY = Math.max(0, e.clientY - dragStartY)
120
+ }
121
+ function onGrabUp(e: PointerEvent) {
122
+ if (!dragging) return
123
+ dragging = false
124
+ ;(e.currentTarget as HTMLElement).releasePointerCapture?.(e.pointerId)
125
+ if (dragY > 80) close()
126
+ else dragY = 0
127
+ }
128
+
129
+ // Focus trap + scroll lock + Escape/backdrop dismissal come from the shared
130
+ // headless overlay core - one tested implementation across every dialog-like
131
+ // overlay, and nested overlays close top-first. See createOverlay.svelte.ts.
132
+ const overlay = createOverlay({
133
+ open: () => open,
134
+ getDialog: () => dialogEl,
135
+ onClose: close,
136
+ closeOnEsc: () => closeOnEsc,
137
+ closeOnBackdrop: () => closeOnBackdrop,
138
+ onOpen: () => { dragY = 0 },
139
+ })
140
+ </script>
141
+
142
+ {#if show}
143
+ <div class="sv-drawer__backdrop" class:is-leaving={leaving} use:portalToBody>
144
+ <div
145
+ bind:this={dialogEl}
146
+ class="sv-drawer sv-drawer--{effectiveSide}"
147
+ class:is-leaving={leaving}
148
+ class:is-sheet={sheet}
149
+ class:is-dragging={dragging}
150
+ {...overlay.dialogProps({ labelledBy: title ? titleId : undefined, label: !title ? ariaLabel : undefined })}
151
+ style:--sv-drawer-size={sizeVar}
152
+ style:transform={sheet && dragY ? `translateY(${dragY}px)` : undefined}
153
+ >
154
+ {#if sheet}
155
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
156
+ <div
157
+ class="sv-drawer__grab"
158
+ aria-hidden="true"
159
+ onpointerdown={onGrabDown}
160
+ onpointermove={onGrabMove}
161
+ onpointerup={onGrabUp}
162
+ onpointercancel={onGrabUp}
163
+ ><span></span></div>
164
+ {/if}
165
+ {#if title || !hideClose}
166
+ <div class="sv-drawer__header">
167
+ <h2 class="sv-drawer__title" id={titleId}>{title ?? ''}</h2>
168
+ {#if !hideClose}
169
+ <button type="button" class="sv-drawer__x" aria-label="Close" onclick={close}>&times;</button>
170
+ {/if}
171
+ </div>
172
+ {/if}
173
+ <div class="sv-drawer__body">{@render children?.()}</div>
174
+ {#if footer}<div class="sv-drawer__footer">{@render footer()}</div>{/if}
175
+ </div>
176
+ </div>
177
+ {/if}
178
+
179
+ <style>
180
+ :global(.sv-drawer__backdrop) {
181
+ position: fixed; inset: 0; z-index: 2147483000;
182
+ background: rgba(15, 23, 42, 0.45); backdrop-filter: blur(1.5px);
183
+ animation: sv-drawer-bd-in 0.2s ease backwards;
184
+ }
185
+ :global(.sv-drawer__backdrop.is-leaving) { animation: sv-drawer-bd-out 0.2s ease forwards; }
186
+ @keyframes sv-drawer-bd-in { from { opacity: 0 } to { opacity: 1 } }
187
+ @keyframes sv-drawer-bd-out { from { opacity: 1 } to { opacity: 0 } }
188
+
189
+ :global(.sv-drawer) {
190
+ position: fixed;
191
+ display: flex; flex-direction: column;
192
+ background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a);
193
+ box-shadow: 0 24px 64px -16px rgba(15, 23, 42, 0.5);
194
+ overflow: hidden;
195
+ /* Slide in on mount; `backwards` fill shows the off-screen start frame with no
196
+ flash, and does NOT hold the end frame - so the sheet drag transform wins. */
197
+ animation: sv-drawer-in 0.26s cubic-bezier(0.16, 1, 0.3, 1) backwards;
198
+ }
199
+ /* Exit keyframe; `forwards` fill holds the off-screen frame until we unmount. */
200
+ :global(.sv-drawer.is-leaving) { animation: sv-drawer-out 0.26s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
201
+ /* Off-screen vector per edge - the enter/exit keyframes read `--sv-off`. `side`
202
+ is a stated physical edge (like SvToaster's position prop), not a text-flow
203
+ "start/end" - so it stays physical left/right regardless of page dir. */
204
+ :global(.sv-drawer--right), :global(.sv-drawer--left) {
205
+ top: 0; bottom: 0; width: var(--sv-drawer-size); max-width: 100vw;
206
+ }
207
+ :global(.sv-drawer--right) { right: 0; border-left: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateX(100%); }
208
+ :global(.sv-drawer--left) { left: 0; border-right: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateX(-100%); }
209
+ /* Top / bottom: full width, fixed height, slide along Y. */
210
+ :global(.sv-drawer--top), :global(.sv-drawer--bottom) {
211
+ left: 0; right: 0; height: var(--sv-drawer-size); max-height: 100vh;
212
+ }
213
+ :global(.sv-drawer--top) { top: 0; border-bottom: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateY(-100%); }
214
+ :global(.sv-drawer--bottom) { bottom: 0; border-top: 1px solid var(--sg-border, #e2e8f0); --sv-off: translateY(100%); }
215
+ @keyframes sv-drawer-in { from { transform: var(--sv-off) } to { transform: none } }
216
+ @keyframes sv-drawer-out { from { transform: none } to { transform: var(--sv-off) } }
217
+
218
+ /* Mobile bottom-sheet: centered, fixed width, rounded top, grab handle. Slides
219
+ along Y like a bottom drawer (enter/exit keyframes read --sv-off from --bottom). */
220
+ :global(.sv-drawer.is-sheet) {
221
+ left: 0; right: 0; margin: 0 auto; top: auto;
222
+ width: min(560px, 100vw); height: auto; max-height: 85vh;
223
+ border: 1px solid var(--sg-border, #e2e8f0); border-bottom: 0;
224
+ border-radius: 16px 16px 0 0;
225
+ }
226
+ /* No transition while the user is dragging the grab handle - follow the finger. */
227
+ :global(.sv-drawer.is-dragging) { transition: none; }
228
+ :global(.sv-drawer__grab) {
229
+ flex: none; display: grid; place-items: center; padding: 8px 0 2px; cursor: grab; touch-action: none;
230
+ }
231
+ :global(.sv-drawer__grab span) {
232
+ display: block; width: 40px; height: 4px; border-radius: 999px; background: var(--sg-border, #cbd5e1);
233
+ }
234
+ @media (prefers-reduced-motion: reduce) {
235
+ :global(.sv-drawer__backdrop), :global(.sv-drawer__backdrop.is-leaving),
236
+ :global(.sv-drawer), :global(.sv-drawer.is-leaving) { animation: none; }
237
+ }
238
+
239
+ :global(.sv-drawer__header) {
240
+ display: flex; align-items: center; gap: 12px; padding: 13px 16px;
241
+ border-bottom: 1px solid var(--sg-border, #e2e8f0);
242
+ }
243
+ :global(.sv-drawer__title) { flex: 1; margin: 0; font-size: 15px; font-weight: 650; }
244
+ :global(.sv-drawer__x) {
245
+ flex: none; width: 28px; height: 28px; display: grid; place-items: center;
246
+ background: none; border: 0; color: var(--sg-muted, #64748b); cursor: pointer; border-radius: 6px; font-size: 20px; line-height: 1;
247
+ }
248
+ :global(.sv-drawer__x:hover) { background: var(--sg-row-hover-bg, #f1f5f9); color: var(--sg-fg, #0f172a); }
249
+ :global(.sv-drawer__body) { padding: 16px; overflow: auto; flex: 1; font-size: 13.5px; line-height: 1.6; }
250
+ :global(.sv-drawer__footer) {
251
+ display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px;
252
+ border-top: 1px solid var(--sg-border, #e2e8f0);
253
+ }
254
+ </style>