@flanksource/clicky-ui 0.3.28 → 0.3.29

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 (852) hide show
  1. package/dist/comments/CommentAuthor.d.ts +1 -1
  2. package/dist/comments/CommentAuthor.d.ts.map +1 -1
  3. package/dist/comments/CommentCard.d.ts +2 -2
  4. package/dist/comments/CommentCard.d.ts.map +1 -1
  5. package/dist/comments/CommentComposer.d.ts +1 -1
  6. package/dist/comments/CommentComposer.d.ts.map +1 -1
  7. package/dist/comments/CommentFilterBar.d.ts +1 -1
  8. package/dist/comments/CommentFilterBar.d.ts.map +1 -1
  9. package/dist/comments/CommentMarkdown.d.ts +1 -1
  10. package/dist/comments/CommentMarkdown.d.ts.map +1 -1
  11. package/dist/comments/CommentProgress.d.ts +1 -1
  12. package/dist/comments/CommentProgress.d.ts.map +1 -1
  13. package/dist/comments/CommentProvider.d.ts +2 -2
  14. package/dist/comments/CommentProvider.d.ts.map +1 -1
  15. package/dist/comments/CommentSidePanel.d.ts +1 -1
  16. package/dist/comments/CommentSidePanel.d.ts.map +1 -1
  17. package/dist/comments/CommentThread.d.ts +2 -2
  18. package/dist/comments/CommentThread.d.ts.map +1 -1
  19. package/dist/comments/CommentThreadList.d.ts +2 -2
  20. package/dist/comments/CommentThreadList.d.ts.map +1 -1
  21. package/dist/comments/GroupedComments.d.ts +1 -1
  22. package/dist/comments/GroupedComments.d.ts.map +1 -1
  23. package/dist/comments/MentionTextarea.d.ts +1 -1
  24. package/dist/comments/comment-context.d.ts +4 -4
  25. package/dist/comments/comment-fixtures.d.ts +1 -1
  26. package/dist/comments/comment-types.d.ts +1 -1
  27. package/dist/components/AccordionList.d.ts +2 -2
  28. package/dist/components/AccordionList.d.ts.map +1 -1
  29. package/dist/components/Combobox.cjs +6 -6
  30. package/dist/components/Combobox.cjs.map +1 -1
  31. package/dist/components/Combobox.d.ts +1 -1
  32. package/dist/components/Combobox.d.ts.map +1 -1
  33. package/dist/components/Combobox.js +2 -2
  34. package/dist/components/Combobox.js.map +1 -1
  35. package/dist/components/ComboboxActions.d.ts +1 -1
  36. package/dist/components/ComboboxActions.d.ts.map +1 -1
  37. package/dist/components/ComboboxControl.cjs +3 -2
  38. package/dist/components/ComboboxControl.cjs.map +1 -1
  39. package/dist/components/ComboboxControl.d.ts +5 -5
  40. package/dist/components/ComboboxControl.d.ts.map +1 -1
  41. package/dist/components/ComboboxControl.js +2 -1
  42. package/dist/components/ComboboxControl.js.map +1 -1
  43. package/dist/components/ComboboxMenu.cjs +154 -134
  44. package/dist/components/ComboboxMenu.cjs.map +1 -1
  45. package/dist/components/ComboboxMenu.d.ts +4 -4
  46. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  47. package/dist/components/ComboboxMenu.js +154 -134
  48. package/dist/components/ComboboxMenu.js.map +1 -1
  49. package/dist/components/ComboboxTags.d.ts +1 -1
  50. package/dist/components/ComboboxTags.d.ts.map +1 -1
  51. package/dist/components/ConnectionLoggingPolicy.d.ts +1 -1
  52. package/dist/components/ConnectionLoggingPolicy.d.ts.map +1 -1
  53. package/dist/components/CopyButton.d.ts +1 -1
  54. package/dist/components/CopyButton.d.ts.map +1 -1
  55. package/dist/components/CountryFlag.d.ts +1 -1
  56. package/dist/components/CountryFlag.d.ts.map +1 -1
  57. package/dist/components/CountryPicker.d.ts +1 -1
  58. package/dist/components/CountryPicker.d.ts.map +1 -1
  59. package/dist/components/DaemonSetIcon.d.ts +1 -1
  60. package/dist/components/DaemonSetIcon.d.ts.map +1 -1
  61. package/dist/components/DateField.d.ts +3 -3
  62. package/dist/components/DatePicker.d.ts +3 -3
  63. package/dist/components/DateTimePicker.d.ts +3 -3
  64. package/dist/components/DimensionField.d.ts +1 -1
  65. package/dist/components/DimensionField.d.ts.map +1 -1
  66. package/dist/components/EndpointSelector.d.ts +1 -1
  67. package/dist/components/EndpointSelector.d.ts.map +1 -1
  68. package/dist/components/ErrorWrapper.d.ts +2 -2
  69. package/dist/components/Field.d.ts +2 -2
  70. package/dist/components/Field.d.ts.map +1 -1
  71. package/dist/components/FilterBar.cjs +100 -85
  72. package/dist/components/FilterBar.cjs.map +1 -1
  73. package/dist/components/FilterBar.d.ts +4 -4
  74. package/dist/components/FilterBar.d.ts.map +1 -1
  75. package/dist/components/FilterBar.js +101 -86
  76. package/dist/components/FilterBar.js.map +1 -1
  77. package/dist/components/FormLookupProvider.d.ts +2 -2
  78. package/dist/components/FormLookupProvider.d.ts.map +1 -1
  79. package/dist/components/FormatOptionsDropdown.d.ts +2 -2
  80. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -1
  81. package/dist/components/IconButton.d.ts +3 -3
  82. package/dist/components/InputField.d.ts +2 -2
  83. package/dist/components/ItemActions.d.ts +2 -2
  84. package/dist/components/ItemActions.d.ts.map +1 -1
  85. package/dist/components/JSONPathField.d.ts +1 -1
  86. package/dist/components/JSONPathField.d.ts.map +1 -1
  87. package/dist/components/JSONPathPlayground.d.ts +1 -1
  88. package/dist/components/JSONPathPlayground.d.ts.map +1 -1
  89. package/dist/components/JsonSchemaForm.d.ts +1 -1
  90. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  91. package/dist/components/ListMenu.d.ts +6 -6
  92. package/dist/components/ListMenu.d.ts.map +1 -1
  93. package/dist/components/MdxEditorCallout.d.ts +2 -2
  94. package/dist/components/MdxEditorCallout.d.ts.map +1 -1
  95. package/dist/components/MdxEditorField.d.ts +1 -1
  96. package/dist/components/MdxEditorField.d.ts.map +1 -1
  97. package/dist/components/MdxEditorToolbar.d.ts +1 -1
  98. package/dist/components/MdxEditorToolbar.d.ts.map +1 -1
  99. package/dist/components/MultiSelect.d.ts +2 -2
  100. package/dist/components/MultiSelect.d.ts.map +1 -1
  101. package/dist/components/NamespacePicker.d.ts +1 -1
  102. package/dist/components/NamespacePicker.d.ts.map +1 -1
  103. package/dist/components/OnePasswordSelector.d.ts +1 -1
  104. package/dist/components/OnePasswordSelector.d.ts.map +1 -1
  105. package/dist/components/RangeSlider.d.ts +1 -1
  106. package/dist/components/RangeSlider.d.ts.map +1 -1
  107. package/dist/components/SearchInput.d.ts +2 -2
  108. package/dist/components/SearchInput.d.ts.map +1 -1
  109. package/dist/components/SecretFormField.d.ts +1 -1
  110. package/dist/components/SecretFormField.d.ts.map +1 -1
  111. package/dist/components/SecretKeySelector.d.ts +1 -1
  112. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  113. package/dist/components/SegmentedControl.d.ts +2 -2
  114. package/dist/components/SegmentedControl.d.ts.map +1 -1
  115. package/dist/components/SplitButton.d.ts +2 -2
  116. package/dist/components/SplitButton.d.ts.map +1 -1
  117. package/dist/components/Switch.d.ts +2 -2
  118. package/dist/components/Switch.d.ts.map +1 -1
  119. package/dist/components/TimeRange.d.ts +1 -1
  120. package/dist/components/TimeRange.d.ts.map +1 -1
  121. package/dist/components/TreePickerField.d.ts +2 -2
  122. package/dist/components/TreePickerField.d.ts.map +1 -1
  123. package/dist/components/TriStateToggle.d.ts +1 -1
  124. package/dist/components/TriStateToggle.d.ts.map +1 -1
  125. package/dist/components/UnitStepControls.d.ts +2 -2
  126. package/dist/components/UnitStepControls.d.ts.map +1 -1
  127. package/dist/components/WorkloadPicker.d.ts +1 -1
  128. package/dist/components/WorkloadPicker.d.ts.map +1 -1
  129. package/dist/components/button.d.ts +3 -3
  130. package/dist/components/combobox-types.d.ts +1 -1
  131. package/dist/components/density-switcher.d.ts +1 -1
  132. package/dist/components/filter-bar-context.d.ts +1 -1
  133. package/dist/components/filter-bar-field-utils.d.ts +2 -2
  134. package/dist/components/filter-bar-field-utils.js +1 -1
  135. package/dist/components/filter-bar-multi.d.ts +3 -3
  136. package/dist/components/filter-bar-multi.d.ts.map +1 -1
  137. package/dist/components/form-lookup-context.d.ts +1 -1
  138. package/dist/components/icon-menu-picker.cjs.map +1 -1
  139. package/dist/components/icon-menu-picker.d.ts +2 -2
  140. package/dist/components/icon-menu-picker.d.ts.map +1 -1
  141. package/dist/components/icon-menu-picker.js.map +1 -1
  142. package/dist/components/jotai-bindings.d.ts +2 -2
  143. package/dist/components/jotai-bindings.d.ts.map +1 -1
  144. package/dist/components/json-schema-form-accordion-array.d.ts +1 -1
  145. package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
  146. package/dist/components/json-schema-form-array.d.ts +1 -1
  147. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  148. package/dist/components/json-schema-form-cards-array.d.ts +1 -1
  149. package/dist/components/json-schema-form-cards-array.d.ts.map +1 -1
  150. package/dist/components/json-schema-form-discriminator.d.ts +1 -1
  151. package/dist/components/json-schema-form-error-display.d.ts +3 -3
  152. package/dist/components/json-schema-form-error-display.d.ts.map +1 -1
  153. package/dist/components/json-schema-form-extensions.d.ts +1 -1
  154. package/dist/components/json-schema-form-fields.d.ts +12 -12
  155. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  156. package/dist/components/json-schema-form-grid.d.ts +1 -1
  157. package/dist/components/json-schema-form-grid.d.ts.map +1 -1
  158. package/dist/components/json-schema-form-item-row.d.ts +4 -4
  159. package/dist/components/json-schema-form-item-row.d.ts.map +1 -1
  160. package/dist/components/json-schema-form-layout.d.ts +6 -6
  161. package/dist/components/json-schema-form-layout.d.ts.map +1 -1
  162. package/dist/components/json-schema-form-list-array.d.ts +1 -1
  163. package/dist/components/json-schema-form-list-array.d.ts.map +1 -1
  164. package/dist/components/json-schema-form-lookup-tree.d.ts +1 -1
  165. package/dist/components/json-schema-form-lookup-tree.d.ts.map +1 -1
  166. package/dist/components/json-schema-form-object.d.ts +2 -2
  167. package/dist/components/json-schema-form-object.d.ts.map +1 -1
  168. package/dist/components/json-schema-form-render.d.ts +1 -1
  169. package/dist/components/json-schema-form-table-array.d.ts +1 -1
  170. package/dist/components/json-schema-form-table-array.d.ts.map +1 -1
  171. package/dist/components/json-schema-form-tags-combobox.cjs +2 -2
  172. package/dist/components/json-schema-form-tags-combobox.cjs.map +1 -1
  173. package/dist/components/json-schema-form-tags-combobox.d.ts +1 -1
  174. package/dist/components/json-schema-form-tags-combobox.d.ts.map +1 -1
  175. package/dist/components/json-schema-form-tags-combobox.js +1 -1
  176. package/dist/components/json-schema-form-tags-combobox.js.map +1 -1
  177. package/dist/components/json-schema-form-template-menu.d.ts +2 -2
  178. package/dist/components/json-schema-form-template-menu.d.ts.map +1 -1
  179. package/dist/components/json-schema-form-template.d.ts +1 -1
  180. package/dist/components/json-schema-form-types.d.ts +1 -1
  181. package/dist/components/loading.d.ts +4 -4
  182. package/dist/components/mdx-editor-callout.d.ts +1 -1
  183. package/dist/components/mdx-editor-options.d.ts +1 -1
  184. package/dist/components/select.d.ts +3 -3
  185. package/dist/components/theme-switcher.d.ts +1 -1
  186. package/dist/components/use-list-menu-selection.d.ts +1 -1
  187. package/dist/components/useComboboxLayout.cjs +37 -27
  188. package/dist/components/useComboboxLayout.cjs.map +1 -1
  189. package/dist/components/useComboboxLayout.d.ts +4 -4
  190. package/dist/components/useComboboxLayout.d.ts.map +1 -1
  191. package/dist/components/useComboboxLayout.js +38 -28
  192. package/dist/components/useComboboxLayout.js.map +1 -1
  193. package/dist/components/workload-picker-utils.d.ts +1 -1
  194. package/dist/components.d.ts +1 -0
  195. package/dist/components.d.ts.map +1 -1
  196. package/dist/data/AnsiHtml.d.ts +1 -1
  197. package/dist/data/AnsiHtml.d.ts.map +1 -1
  198. package/dist/data/Avatar.d.ts +2 -2
  199. package/dist/data/Avatar.d.ts.map +1 -1
  200. package/dist/data/AvatarBadge.d.ts +2 -2
  201. package/dist/data/AvatarBadge.d.ts.map +1 -1
  202. package/dist/data/Badge.d.ts +2 -2
  203. package/dist/data/Badge.d.ts.map +1 -1
  204. package/dist/data/Callout.d.ts +2 -2
  205. package/dist/data/Callout.d.ts.map +1 -1
  206. package/dist/data/Clicky.d.ts +3 -3
  207. package/dist/data/Clicky.d.ts.map +1 -1
  208. package/dist/data/CodeBlock.cjs +1 -1
  209. package/dist/data/CodeBlock.cjs.map +1 -1
  210. package/dist/data/CodeBlock.d.ts +1 -1
  211. package/dist/data/CodeBlock.d.ts.map +1 -1
  212. package/dist/data/CodeBlock.js +1 -1
  213. package/dist/data/CodeBlock.js.map +1 -1
  214. package/dist/data/CodeDiff.d.ts +1 -1
  215. package/dist/data/CodeDiff.d.ts.map +1 -1
  216. package/dist/data/DataTable.cjs +63 -27
  217. package/dist/data/DataTable.cjs.map +1 -1
  218. package/dist/data/DataTable.d.ts +11 -2
  219. package/dist/data/DataTable.d.ts.map +1 -1
  220. package/dist/data/DataTable.grouping.d.ts +1 -1
  221. package/dist/data/DataTable.js +63 -27
  222. package/dist/data/DataTable.js.map +1 -1
  223. package/dist/data/DataTableGroupingControls.d.ts +1 -1
  224. package/dist/data/DataTableGroupingControls.d.ts.map +1 -1
  225. package/dist/data/ExecutionTree.d.ts +2 -2
  226. package/dist/data/ExecutionTree.d.ts.map +1 -1
  227. package/dist/data/FilterPill.d.ts +4 -4
  228. package/dist/data/FilterPill.d.ts.map +1 -1
  229. package/dist/data/FixtureEditor/FenceForm.d.ts +1 -1
  230. package/dist/data/FixtureEditor/FenceForm.d.ts.map +1 -1
  231. package/dist/data/FixtureEditor/FixtureEditor.d.ts +1 -1
  232. package/dist/data/FixtureEditor/FixtureEditor.d.ts.map +1 -1
  233. package/dist/data/FixtureEditor/FixtureFenceCodeBlockEditor.d.ts +1 -1
  234. package/dist/data/FixtureEditor/FixtureFenceCodeBlockEditor.d.ts.map +1 -1
  235. package/dist/data/FixtureEditor/FixtureFrontmatterDialog.d.ts +1 -1
  236. package/dist/data/FixtureEditor/FixtureFrontmatterDialog.d.ts.map +1 -1
  237. package/dist/data/FixtureEditor/RawFenceEditor.d.ts +2 -2
  238. package/dist/data/FixtureEditor/RawFenceEditor.d.ts.map +1 -1
  239. package/dist/data/FixtureEditor/types.d.ts +1 -1
  240. package/dist/data/Gauge.d.ts +2 -2
  241. package/dist/data/Gauge.d.ts.map +1 -1
  242. package/dist/data/GaugeHoverCard.d.ts +2 -2
  243. package/dist/data/GaugeHoverCard.d.ts.map +1 -1
  244. package/dist/data/HighlightedTokens.d.ts +1 -1
  245. package/dist/data/HighlightedTokens.d.ts.map +1 -1
  246. package/dist/data/Icon.cjs.map +1 -1
  247. package/dist/data/Icon.d.ts +3 -3
  248. package/dist/data/Icon.d.ts.map +1 -1
  249. package/dist/data/Icon.js.map +1 -1
  250. package/dist/data/JsonView.d.ts +1 -1
  251. package/dist/data/JsonView.d.ts.map +1 -1
  252. package/dist/data/KeyValueList.d.ts +2 -2
  253. package/dist/data/KeyValueList.d.ts.map +1 -1
  254. package/dist/data/LogDetails.d.ts +1 -1
  255. package/dist/data/LogDetails.d.ts.map +1 -1
  256. package/dist/data/LogViewer.d.ts +1 -1
  257. package/dist/data/LogViewer.d.ts.map +1 -1
  258. package/dist/data/LogsTable.d.ts +1 -1
  259. package/dist/data/LogsTable.d.ts.map +1 -1
  260. package/dist/data/Markdown.d.ts +1 -1
  261. package/dist/data/Markdown.d.ts.map +1 -1
  262. package/dist/data/MarkdownEditor.d.ts +2 -2
  263. package/dist/data/MarkdownEditor.d.ts.map +1 -1
  264. package/dist/data/MatrixTable.d.ts +2 -2
  265. package/dist/data/MatrixTable.d.ts.map +1 -1
  266. package/dist/data/MethodBadge.d.ts +1 -1
  267. package/dist/data/MethodBadge.d.ts.map +1 -1
  268. package/dist/data/ObjectGraph.d.ts +2 -2
  269. package/dist/data/ObjectGraph.d.ts.map +1 -1
  270. package/dist/data/ProgressBar.d.ts +1 -1
  271. package/dist/data/ProgressBar.d.ts.map +1 -1
  272. package/dist/data/ProgressBars.d.ts +2 -2
  273. package/dist/data/ProgressBars.d.ts.map +1 -1
  274. package/dist/data/PromptBanner.d.ts +1 -1
  275. package/dist/data/PromptBanner.d.ts.map +1 -1
  276. package/dist/data/PromptDialog.d.ts +1 -1
  277. package/dist/data/PromptDialog.d.ts.map +1 -1
  278. package/dist/data/Properties.d.ts +2 -2
  279. package/dist/data/Properties.d.ts.map +1 -1
  280. package/dist/data/RadialGauge.d.ts +2 -2
  281. package/dist/data/RadialGauge.d.ts.map +1 -1
  282. package/dist/data/SchemaViewer.d.ts +4 -4
  283. package/dist/data/SchemaViewer.d.ts.map +1 -1
  284. package/dist/data/SelectionActionBar.cjs +7 -7
  285. package/dist/data/SelectionActionBar.cjs.map +1 -1
  286. package/dist/data/SelectionActionBar.d.ts +1 -1
  287. package/dist/data/SelectionActionBar.d.ts.map +1 -1
  288. package/dist/data/SelectionActionBar.js +7 -7
  289. package/dist/data/SelectionActionBar.js.map +1 -1
  290. package/dist/data/ServerTimingBadge.d.ts +1 -1
  291. package/dist/data/ServerTimingBadge.d.ts.map +1 -1
  292. package/dist/data/SignedDeltaBar.d.ts +1 -1
  293. package/dist/data/SignedDeltaBar.d.ts.map +1 -1
  294. package/dist/data/SortableHeader.d.ts +2 -2
  295. package/dist/data/SortableHeader.d.ts.map +1 -1
  296. package/dist/data/StatStrip.d.ts +2 -2
  297. package/dist/data/StatStrip.d.ts.map +1 -1
  298. package/dist/data/StatusBreakdown.d.ts +3 -3
  299. package/dist/data/StatusBreakdown.d.ts.map +1 -1
  300. package/dist/data/TabButton.d.ts +2 -2
  301. package/dist/data/TabButton.d.ts.map +1 -1
  302. package/dist/data/TaskExecDetails.d.ts +2 -2
  303. package/dist/data/TaskExecDetails.d.ts.map +1 -1
  304. package/dist/data/TaskManager.d.ts +1 -1
  305. package/dist/data/TaskManager.d.ts.map +1 -1
  306. package/dist/data/TaskManagerButton.d.ts +1 -1
  307. package/dist/data/TaskManagerButton.d.ts.map +1 -1
  308. package/dist/data/TaskProcessDetails.d.ts +1 -1
  309. package/dist/data/TaskProcessDetails.d.ts.map +1 -1
  310. package/dist/data/TaskProgress.d.ts +1 -1
  311. package/dist/data/TaskProgress.d.ts.map +1 -1
  312. package/dist/data/Timeline.d.ts +2 -2
  313. package/dist/data/Timeline.d.ts.map +1 -1
  314. package/dist/data/TimeseriesCoreBars.d.ts +1 -1
  315. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  316. package/dist/data/TimeseriesGauge.d.ts +1 -1
  317. package/dist/data/TimeseriesGauge.d.ts.map +1 -1
  318. package/dist/data/TimeseriesPanel.d.ts +1 -1
  319. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  320. package/dist/data/Tree.d.ts +2 -2
  321. package/dist/data/Tree.d.ts.map +1 -1
  322. package/dist/data/TreeGroupHeader.d.ts +2 -2
  323. package/dist/data/TreeGroupHeader.d.ts.map +1 -1
  324. package/dist/data/TreeNode.d.ts +2 -2
  325. package/dist/data/TreeNode.d.ts.map +1 -1
  326. package/dist/data/Version.d.ts +3 -3
  327. package/dist/data/WorkloadCard.d.ts +1 -1
  328. package/dist/data/WorkloadCard.d.ts.map +1 -1
  329. package/dist/data/ai/AdvancedChatConfig.d.ts +1 -1
  330. package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
  331. package/dist/data/ai/AdvancedCostsPanel.d.ts +1 -1
  332. package/dist/data/ai/AdvancedCostsPanel.d.ts.map +1 -1
  333. package/dist/data/ai/ChatButton.d.ts +1 -1
  334. package/dist/data/ai/ChatButton.d.ts.map +1 -1
  335. package/dist/data/ai/ChatFab.d.ts +1 -1
  336. package/dist/data/ai/ChatFab.d.ts.map +1 -1
  337. package/dist/data/ai/ChatWindow.d.ts +2 -2
  338. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  339. package/dist/data/ai/ChatWindow.test-utils.d.ts +1 -1
  340. package/dist/data/ai/ChatWindow.thread-status.d.ts +1 -1
  341. package/dist/data/ai/ChatWindow.thread-status.d.ts.map +1 -1
  342. package/dist/data/ai/ChatWindow.types.d.ts +1 -1
  343. package/dist/data/ai/ChatWindowManager.d.ts +2 -2
  344. package/dist/data/ai/ChatWindowManager.d.ts.map +1 -1
  345. package/dist/data/ai/ContextBadges.d.ts +2 -2
  346. package/dist/data/ai/ContextBadges.d.ts.map +1 -1
  347. package/dist/data/ai/PolicyTree.d.ts +2 -2
  348. package/dist/data/ai/PolicyTree.d.ts.map +1 -1
  349. package/dist/data/ai/PromptCatalog/PromptCatalogTable.d.ts +1 -1
  350. package/dist/data/ai/PromptCatalog/PromptCatalogTable.d.ts.map +1 -1
  351. package/dist/data/ai/PromptCatalog/PromptLayerStrip.d.ts +1 -1
  352. package/dist/data/ai/PromptCatalog/PromptLayerStrip.d.ts.map +1 -1
  353. package/dist/data/ai/PromptCatalog/PromptPage.d.ts +1 -1
  354. package/dist/data/ai/PromptCatalog/PromptPage.d.ts.map +1 -1
  355. package/dist/data/ai/PromptCatalog/PromptPageEditor.d.ts +1 -1
  356. package/dist/data/ai/PromptCatalog/PromptPageEditor.d.ts.map +1 -1
  357. package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts +2 -2
  358. package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts.map +1 -1
  359. package/dist/data/ai/PromptCatalog/PromptPagePreview.d.ts +1 -1
  360. package/dist/data/ai/PromptCatalog/PromptPagePreview.d.ts.map +1 -1
  361. package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts +1 -1
  362. package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts.map +1 -1
  363. package/dist/data/ai/PromptCatalog/PromptSourceBadge.d.ts +1 -1
  364. package/dist/data/ai/PromptCatalog/PromptSourceBadge.d.ts.map +1 -1
  365. package/dist/data/ai/PromptCatalog/types.d.ts +1 -1
  366. package/dist/data/ai/PromptPicker/PromptPicker.d.ts +2 -2
  367. package/dist/data/ai/PromptPicker/PromptPicker.d.ts.map +1 -1
  368. package/dist/data/ai/PromptPicker/PromptSourceRepair.d.ts +1 -1
  369. package/dist/data/ai/PromptPicker/PromptSourceRepair.d.ts.map +1 -1
  370. package/dist/data/ai/PromptRunEditor/index.d.ts +2 -2
  371. package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
  372. package/dist/data/ai/RuntimeModePicker.d.ts +1 -1
  373. package/dist/data/ai/RuntimeModePicker.d.ts.map +1 -1
  374. package/dist/data/ai/SandboxConnectionsSection.d.ts +1 -1
  375. package/dist/data/ai/SandboxConnectionsSection.d.ts.map +1 -1
  376. package/dist/data/ai/SandboxCreateWizard.d.ts +1 -1
  377. package/dist/data/ai/SandboxCreateWizard.d.ts.map +1 -1
  378. package/dist/data/ai/SessionChatComposer.d.ts +2 -2
  379. package/dist/data/ai/SessionChatComposer.d.ts.map +1 -1
  380. package/dist/data/ai/SessionInspector.d.ts +2 -2
  381. package/dist/data/ai/SessionInspector.d.ts.map +1 -1
  382. package/dist/data/ai/SessionInspector.files.d.ts +1 -1
  383. package/dist/data/ai/SessionInspector.files.d.ts.map +1 -1
  384. package/dist/data/ai/SessionInspector.hierarchy.d.ts +2 -2
  385. package/dist/data/ai/SessionInspector.hierarchy.d.ts.map +1 -1
  386. package/dist/data/ai/SessionInspector.panels.d.ts +1 -1
  387. package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -1
  388. package/dist/data/ai/SessionInspector.plan.d.ts +1 -1
  389. package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -1
  390. package/dist/data/ai/SessionInspector.summary.d.ts +2 -2
  391. package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
  392. package/dist/data/ai/SessionInspector.transcript.d.ts +1 -1
  393. package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
  394. package/dist/data/ai/SessionInspector.turns.d.ts +2 -2
  395. package/dist/data/ai/SessionInspector.turns.d.ts.map +1 -1
  396. package/dist/data/ai/SessionViewer.d.ts +2 -2
  397. package/dist/data/ai/SessionViewer.d.ts.map +1 -1
  398. package/dist/data/ai/SessionViewer.header.d.ts +2 -2
  399. package/dist/data/ai/SessionViewer.header.d.ts.map +1 -1
  400. package/dist/data/ai/SessionViewer.row-metadata.d.ts +3 -3
  401. package/dist/data/ai/SessionViewer.row-metadata.d.ts.map +1 -1
  402. package/dist/data/ai/SessionViewer.rows.d.ts +3 -3
  403. package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
  404. package/dist/data/ai/SessionViewer.tool-details.d.ts +5 -5
  405. package/dist/data/ai/SessionViewer.tool-details.d.ts.map +1 -1
  406. package/dist/data/ai/SessionViewer.tool-row.d.ts +1 -1
  407. package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -1
  408. package/dist/data/ai/SessionViewerMenu.d.ts +1 -1
  409. package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -1
  410. package/dist/data/ai/SpecRuntimeEditor/CLIArgsSection.d.ts +1 -1
  411. package/dist/data/ai/SpecRuntimeEditor/CLIArgsSection.d.ts.map +1 -1
  412. package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts +1 -1
  413. package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts.map +1 -1
  414. package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.d.ts +2 -2
  415. package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.d.ts.map +1 -1
  416. package/dist/data/ai/SpecRuntimeEditor/Footer.d.ts +2 -2
  417. package/dist/data/ai/SpecRuntimeEditor/Footer.d.ts.map +1 -1
  418. package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.d.ts +1 -1
  419. package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.d.ts.map +1 -1
  420. package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts +2 -2
  421. package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts.map +1 -1
  422. package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.d.ts +1 -1
  423. package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.d.ts.map +1 -1
  424. package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.d.ts +1 -1
  425. package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.d.ts.map +1 -1
  426. package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.d.ts +2 -2
  427. package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.d.ts.map +1 -1
  428. package/dist/data/ai/SpecRuntimeEditor/PresetCards.d.ts +1 -1
  429. package/dist/data/ai/SpecRuntimeEditor/PresetCards.d.ts.map +1 -1
  430. package/dist/data/ai/SpecRuntimeEditor/PromptSection.d.ts +2 -2
  431. package/dist/data/ai/SpecRuntimeEditor/PromptSection.d.ts.map +1 -1
  432. package/dist/data/ai/SpecRuntimeEditor/Rail.d.ts +2 -2
  433. package/dist/data/ai/SpecRuntimeEditor/Rail.d.ts.map +1 -1
  434. package/dist/data/ai/SpecRuntimeEditor/SandboxSection.d.ts +1 -1
  435. package/dist/data/ai/SpecRuntimeEditor/SandboxSection.d.ts.map +1 -1
  436. package/dist/data/ai/SpecRuntimeEditor/SectionCard.d.ts +2 -2
  437. package/dist/data/ai/SpecRuntimeEditor/SectionCard.d.ts.map +1 -1
  438. package/dist/data/ai/SpecRuntimeEditor/VerifySection.d.ts +1 -1
  439. package/dist/data/ai/SpecRuntimeEditor/VerifySection.d.ts.map +1 -1
  440. package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.d.ts +1 -1
  441. package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.d.ts.map +1 -1
  442. package/dist/data/ai/SpecRuntimeEditor/fields.d.ts +12 -12
  443. package/dist/data/ai/SpecRuntimeEditor/fields.d.ts.map +1 -1
  444. package/dist/data/ai/SpecRuntimeEditor/index.d.ts +2 -2
  445. package/dist/data/ai/SpecRuntimeEditor/index.d.ts.map +1 -1
  446. package/dist/data/ai/ThreadPicker.d.ts +1 -1
  447. package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
  448. package/dist/data/ai/ToolPreferences.d.ts +1 -1
  449. package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
  450. package/dist/data/ai/ToolPreferencesList.d.ts +2 -2
  451. package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -1
  452. package/dist/data/ai/ToolSchemaBrowser.d.ts +1 -1
  453. package/dist/data/ai/ToolSchemaBrowser.d.ts.map +1 -1
  454. package/dist/data/ai/ToolSchemaBrowser.detail.d.ts +1 -1
  455. package/dist/data/ai/ToolSchemaBrowser.detail.d.ts.map +1 -1
  456. package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts +1 -1
  457. package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts.map +1 -1
  458. package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts +1 -1
  459. package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts.map +1 -1
  460. package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts +1 -1
  461. package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts.map +1 -1
  462. package/dist/data/ai/chat-window-context.d.ts +1 -1
  463. package/dist/data/ai/use-session-scroll.d.ts +1 -1
  464. package/dist/data/cache-browser/CacheBrowser.d.ts +1 -1
  465. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -1
  466. package/dist/data/cache-browser/CacheDetailPanel.d.ts +1 -1
  467. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
  468. package/dist/data/cache-browser/CacheStatsOverview.d.ts +1 -1
  469. package/dist/data/cache-browser/CacheStatsOverview.d.ts.map +1 -1
  470. package/dist/data/cache-browser/CacheTree.d.ts +2 -2
  471. package/dist/data/cache-browser/CacheTree.d.ts.map +1 -1
  472. package/dist/data/cache-browser/CacheValue.d.ts +1 -1
  473. package/dist/data/cache-browser/CacheValue.d.ts.map +1 -1
  474. package/dist/data/cache-browser/adapter.d.ts +1 -1
  475. package/dist/data/cells/CellFilterActions.d.ts +2 -2
  476. package/dist/data/cells/CellFilterActions.d.ts.map +1 -1
  477. package/dist/data/cells/EntityCell.d.ts +2 -2
  478. package/dist/data/cells/EntityCell.d.ts.map +1 -1
  479. package/dist/data/cells/StatusDot.d.ts +1 -1
  480. package/dist/data/cells/StatusDot.d.ts.map +1 -1
  481. package/dist/data/cells/TagList.d.ts +3 -3
  482. package/dist/data/cells/TagList.d.ts.map +1 -1
  483. package/dist/data/cells/Timestamp.d.ts +1 -1
  484. package/dist/data/cells/Timestamp.d.ts.map +1 -1
  485. package/dist/data/cells/tag-utils.d.ts +1 -1
  486. package/dist/data/chat/Attachment.d.ts +2 -2
  487. package/dist/data/chat/Attachment.d.ts.map +1 -1
  488. package/dist/data/chat/Chat.d.ts +1 -1
  489. package/dist/data/chat/Chat.d.ts.map +1 -1
  490. package/dist/data/chat/ChatRuntimeToolbar.d.ts +1 -1
  491. package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
  492. package/dist/data/chat/ContextMeter.d.ts +1 -1
  493. package/dist/data/chat/ContextMeter.d.ts.map +1 -1
  494. package/dist/data/chat/Conversation.d.ts +1 -1
  495. package/dist/data/chat/Conversation.d.ts.map +1 -1
  496. package/dist/data/chat/Message.d.ts +1 -1
  497. package/dist/data/chat/Message.d.ts.map +1 -1
  498. package/dist/data/chat/MessageActions.d.ts +1 -1
  499. package/dist/data/chat/MessageActions.d.ts.map +1 -1
  500. package/dist/data/chat/ModelSelector.d.ts +5 -5
  501. package/dist/data/chat/ModelSelector.d.ts.map +1 -1
  502. package/dist/data/chat/PromptInput.d.ts +2 -2
  503. package/dist/data/chat/PromptInput.d.ts.map +1 -1
  504. package/dist/data/chat/Reasoning.d.ts +1 -1
  505. package/dist/data/chat/Reasoning.d.ts.map +1 -1
  506. package/dist/data/chat/Suggestion.d.ts +1 -1
  507. package/dist/data/chat/Suggestion.d.ts.map +1 -1
  508. package/dist/data/chat/ToolCall.d.ts +1 -1
  509. package/dist/data/chat/ToolCall.d.ts.map +1 -1
  510. package/dist/data/chat/tool-render/ToolArgs.d.ts +1 -1
  511. package/dist/data/chat/tool-render/ToolParams.d.ts +1 -1
  512. package/dist/data/chat/tool-render/ToolValue.d.ts +1 -1
  513. package/dist/data/chat/tool-render/adapter.d.ts +1 -1
  514. package/dist/data/chat/tool-render/context.d.ts +1 -1
  515. package/dist/data/chat/tool-render/defaults.d.ts +1 -1
  516. package/dist/data/chat/tool-render/known-tool-views.d.ts +1 -1
  517. package/dist/data/chat/tool-render/summary.d.ts +1 -1
  518. package/dist/data/chat/types.d.ts +1 -1
  519. package/dist/data/clicky-export/ClickyExportDialog.d.ts +1 -1
  520. package/dist/data/clicky-export/ClickyExportDialog.d.ts.map +1 -1
  521. package/dist/data/clicky-export/useClickyExport.d.ts +1 -1
  522. package/dist/data/code-block-actions.d.ts +1 -1
  523. package/dist/data/code-block-actions.d.ts.map +1 -1
  524. package/dist/data/data-table-server-filters.d.ts +1 -1
  525. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +2 -2
  526. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  527. package/dist/data/diagnostics/DiagnosticsTree.d.ts +1 -1
  528. package/dist/data/diagnostics/DiagnosticsTree.d.ts.map +1 -1
  529. package/dist/data/diagnostics/ErrorDetails.d.ts +4 -4
  530. package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
  531. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -1
  532. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  533. package/dist/data/diagnostics/GoroutineCard.d.ts +1 -1
  534. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -1
  535. package/dist/data/diagnostics/JvmStackTrace.d.ts +1 -1
  536. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  537. package/dist/data/diagnostics/RenderedStackTrace.d.ts +1 -1
  538. package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -1
  539. package/dist/data/diagnostics/StackFrameRow.d.ts +2 -2
  540. package/dist/data/diagnostics/StackFrameRow.d.ts.map +1 -1
  541. package/dist/data/diagnostics/ThreadCard.d.ts +1 -1
  542. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  543. package/dist/data/git/GitChangeList.d.ts +5 -5
  544. package/dist/data/git/GitChangeList.d.ts.map +1 -1
  545. package/dist/data/har/HarPanel.d.ts +1 -1
  546. package/dist/data/har/HarPanel.d.ts.map +1 -1
  547. package/dist/data/icon-fallback.d.ts +1 -1
  548. package/dist/data/query-browser/QueryBrowser.d.ts +1 -1
  549. package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
  550. package/dist/data/query-browser/QueryBrowser.types.d.ts +1 -1
  551. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +1 -1
  552. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -1
  553. package/dist/data/query-browser/QueryBrowserResults.d.ts +1 -1
  554. package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -1
  555. package/dist/data/runtime/ProviderStatusPanel.d.ts +1 -1
  556. package/dist/data/runtime/ProviderStatusPanel.d.ts.map +1 -1
  557. package/dist/data/runtime/RuntimeBar.d.ts +1 -1
  558. package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
  559. package/dist/data/runtime/RuntimeBarCombo.d.ts +1 -1
  560. package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -1
  561. package/dist/data/runtime/RuntimeBarSegments.d.ts +1 -1
  562. package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -1
  563. package/dist/data/test-runner/TestDetailPanel.d.ts +1 -1
  564. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
  565. package/dist/data/test-runner/TestFailureDetail.d.ts +3 -3
  566. package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
  567. package/dist/data/test-runner/TestFilterBar.d.ts +1 -1
  568. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
  569. package/dist/data/test-runner/TestRunSummary.d.ts +1 -1
  570. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  571. package/dist/data/test-runner/TestRunner.d.ts +2 -2
  572. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  573. package/dist/data/test-runner/TestTree.d.ts +1 -1
  574. package/dist/data/test-runner/TestTree.d.ts.map +1 -1
  575. package/dist/data/test-runner/TestTreeNode.cjs +16 -11
  576. package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
  577. package/dist/data/test-runner/TestTreeNode.d.ts +1 -1
  578. package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
  579. package/dist/data/test-runner/TestTreeNode.js +16 -11
  580. package/dist/data/test-runner/TestTreeNode.js.map +1 -1
  581. package/dist/data/test-runner/adapter.d.ts +1 -1
  582. package/dist/data/test-runner/context.d.ts +1 -1
  583. package/dist/data/version-info.cjs +3 -3
  584. package/dist/data/version-info.js +3 -3
  585. package/dist/devtools/DebugConsole.d.ts +1 -1
  586. package/dist/devtools/DebugConsole.d.ts.map +1 -1
  587. package/dist/devtools/DebugConsoleButton.d.ts +1 -1
  588. package/dist/devtools/DebugConsoleButton.d.ts.map +1 -1
  589. package/dist/devtools/DebugConsoleDock.d.ts +1 -1
  590. package/dist/devtools/DebugConsoleDock.d.ts.map +1 -1
  591. package/dist/devtools/ExecutionDetail.d.ts +1 -1
  592. package/dist/devtools/ExecutionDetail.d.ts.map +1 -1
  593. package/dist/devtools/tabs/ConsoleTab.d.ts +1 -1
  594. package/dist/devtools/tabs/ConsoleTab.d.ts.map +1 -1
  595. package/dist/devtools/tabs/InspectionCaches.d.ts +1 -1
  596. package/dist/devtools/tabs/InspectionCaches.d.ts.map +1 -1
  597. package/dist/devtools/tabs/InspectionTab.d.ts +1 -1
  598. package/dist/devtools/tabs/InspectionTab.d.ts.map +1 -1
  599. package/dist/devtools/tabs/NetworkTab.d.ts +1 -1
  600. package/dist/devtools/tabs/NetworkTab.d.ts.map +1 -1
  601. package/dist/devtools/tabs/QueriesTab.d.ts +1 -1
  602. package/dist/devtools/tabs/QueriesTab.d.ts.map +1 -1
  603. package/dist/hooks/density-provider.d.ts +3 -3
  604. package/dist/hooks/density-provider.d.ts.map +1 -1
  605. package/dist/hooks/theme-provider.d.ts +2 -2
  606. package/dist/hooks/theme-provider.d.ts.map +1 -1
  607. package/dist/hooks/use-density.d.ts +1 -1
  608. package/dist/hooks/use-theme.d.ts +1 -1
  609. package/dist/icons/registry.d.ts +1 -1
  610. package/dist/icons/types.d.ts +1 -1
  611. package/dist/layout/AppShell.cjs.map +1 -1
  612. package/dist/layout/AppShell.d.ts +10 -2
  613. package/dist/layout/AppShell.d.ts.map +1 -1
  614. package/dist/layout/AppShell.debug.d.ts +1 -1
  615. package/dist/layout/AppShell.debug.d.ts.map +1 -1
  616. package/dist/layout/AppShell.js.map +1 -1
  617. package/dist/layout/AppShell.nav.cjs +133 -76
  618. package/dist/layout/AppShell.nav.cjs.map +1 -1
  619. package/dist/layout/AppShell.nav.d.ts +1 -1
  620. package/dist/layout/AppShell.nav.d.ts.map +1 -1
  621. package/dist/layout/AppShell.nav.drag.cjs +86 -0
  622. package/dist/layout/AppShell.nav.drag.cjs.map +1 -0
  623. package/dist/layout/AppShell.nav.drag.d.ts +52 -0
  624. package/dist/layout/AppShell.nav.drag.d.ts.map +1 -0
  625. package/dist/layout/AppShell.nav.drag.js +86 -0
  626. package/dist/layout/AppShell.nav.drag.js.map +1 -0
  627. package/dist/layout/AppShell.nav.js +133 -76
  628. package/dist/layout/AppShell.nav.js.map +1 -1
  629. package/dist/layout/AppSidebar.d.ts +3 -3
  630. package/dist/layout/AppSidebar.d.ts.map +1 -1
  631. package/dist/layout/Panel.d.ts +2 -2
  632. package/dist/layout/Panel.d.ts.map +1 -1
  633. package/dist/layout/PanelFrame.d.ts +2 -2
  634. package/dist/layout/PanelFrame.d.ts.map +1 -1
  635. package/dist/layout/Section.d.ts +3 -3
  636. package/dist/layout/Section.d.ts.map +1 -1
  637. package/dist/layout/SplitPane.d.ts +2 -2
  638. package/dist/layout/SplitPane.d.ts.map +1 -1
  639. package/dist/layout/Tabs.d.ts +2 -2
  640. package/dist/layout/Tabs.d.ts.map +1 -1
  641. package/dist/layout/Workspace.d.ts +2 -2
  642. package/dist/layout/Workspace.d.ts.map +1 -1
  643. package/dist/layout/Workspace.model.d.ts +1 -1
  644. package/dist/layout/Workspace.regions.d.ts +2 -2
  645. package/dist/layout/Workspace.regions.d.ts.map +1 -1
  646. package/dist/{components/combobox-utils.cjs → lib/combobox-values.cjs} +1 -5
  647. package/dist/lib/combobox-values.cjs.map +1 -0
  648. package/dist/{components/combobox-utils.d.ts → lib/combobox-values.d.ts} +3 -13
  649. package/dist/lib/combobox-values.d.ts.map +1 -0
  650. package/dist/{components/combobox-utils.js → lib/combobox-values.js} +1 -5
  651. package/dist/lib/combobox-values.js.map +1 -0
  652. package/dist/lib/combobox.cjs +93 -0
  653. package/dist/lib/combobox.cjs.map +1 -0
  654. package/dist/lib/combobox.d.ts +20 -0
  655. package/dist/lib/combobox.d.ts.map +1 -0
  656. package/dist/lib/combobox.js +93 -0
  657. package/dist/lib/combobox.js.map +1 -0
  658. package/dist/monaco/MonacoEditor.d.ts +1 -1
  659. package/dist/monaco/MonacoEditor.d.ts.map +1 -1
  660. package/dist/monaco/MonacoProvider.d.ts +1 -1
  661. package/dist/monaco/MonacoProvider.d.ts.map +1 -1
  662. package/dist/monaco/MonacoSchemaEditor.cjs +4 -4
  663. package/dist/monaco/MonacoSchemaEditor.cjs.map +1 -1
  664. package/dist/monaco/MonacoSchemaEditor.d.ts +1 -1
  665. package/dist/monaco/MonacoSchemaEditor.d.ts.map +1 -1
  666. package/dist/monaco/MonacoSchemaEditor.js +4 -4
  667. package/dist/monaco/MonacoSchemaEditor.js.map +1 -1
  668. package/dist/monaco/types.d.ts +1 -1
  669. package/dist/monaco/use-monaco-worker.d.ts +1 -1
  670. package/dist/overlay/CellActions.d.ts +3 -3
  671. package/dist/overlay/CellActions.d.ts.map +1 -1
  672. package/dist/overlay/CommandPalette.d.ts +2 -2
  673. package/dist/overlay/CommandPalette.model.d.ts +1 -1
  674. package/dist/overlay/CommandPaletteList.cjs.map +1 -1
  675. package/dist/overlay/CommandPaletteList.d.ts +3 -3
  676. package/dist/overlay/CommandPaletteList.d.ts.map +1 -1
  677. package/dist/overlay/CommandPaletteList.js.map +1 -1
  678. package/dist/overlay/CommandPaletteTrigger.d.ts +1 -1
  679. package/dist/overlay/CommandPaletteTrigger.d.ts.map +1 -1
  680. package/dist/overlay/ContextMenu.d.ts +1 -1
  681. package/dist/overlay/ContextMenu.d.ts.map +1 -1
  682. package/dist/overlay/DropdownMenu.d.ts +2 -2
  683. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  684. package/dist/overlay/DropdownMenuSubmenu.d.ts +1 -1
  685. package/dist/overlay/DropdownMenuSubmenu.d.ts.map +1 -1
  686. package/dist/overlay/HoverCard.d.ts +2 -2
  687. package/dist/overlay/HoverCard.d.ts.map +1 -1
  688. package/dist/overlay/Modal.cjs +105 -18
  689. package/dist/overlay/Modal.cjs.map +1 -1
  690. package/dist/overlay/Modal.d.ts +2 -2
  691. package/dist/overlay/Modal.d.ts.map +1 -1
  692. package/dist/overlay/Modal.js +105 -18
  693. package/dist/overlay/Modal.js.map +1 -1
  694. package/dist/overlay/Toast.d.ts +2 -2
  695. package/dist/overlay/Toast.d.ts.map +1 -1
  696. package/dist/overlay/Tour.d.ts +1 -1
  697. package/dist/overlay/Tour.d.ts.map +1 -1
  698. package/dist/overlay/TourCard.d.ts +2 -2
  699. package/dist/overlay/TourCard.d.ts.map +1 -1
  700. package/dist/overlay/TourProvider.d.ts +2 -2
  701. package/dist/overlay/TourProvider.d.ts.map +1 -1
  702. package/dist/overlay/TourSpotlight.d.ts +1 -1
  703. package/dist/overlay/TourSpotlight.d.ts.map +1 -1
  704. package/dist/overlay/dropdownMenuContext.d.ts +1 -1
  705. package/dist/overlay/toast-context.d.ts +2 -2
  706. package/dist/overlay/tour-context.d.ts +1 -1
  707. package/dist/overlay/tour-types.d.ts +1 -1
  708. package/dist/profiles/cel/celEditor.d.ts +4 -4
  709. package/dist/profiles/cel/celEditor.d.ts.map +1 -1
  710. package/dist/profiles/connections/catalogTree.d.ts +1 -1
  711. package/dist/profiles/connections/catalogTree.d.ts.map +1 -1
  712. package/dist/profiles/connections/connectionBrowserModel.d.ts +1 -1
  713. package/dist/profiles/connections/connectionQueryWorkspace.d.ts +2 -2
  714. package/dist/profiles/connections/connectionQueryWorkspace.d.ts.map +1 -1
  715. package/dist/profiles/connections/inspectionStatus.d.ts +1 -1
  716. package/dist/profiles/connections/inspectionStatus.d.ts.map +1 -1
  717. package/dist/profiles/editor/profileBuilder.d.ts +3 -3
  718. package/dist/profiles/editor/profileBuilder.d.ts.map +1 -1
  719. package/dist/profiles/editor/profileBuilderWorkspace.d.ts +1 -1
  720. package/dist/profiles/editor/profileBuilderWorkspace.d.ts.map +1 -1
  721. package/dist/profiles/editor/profileEditor.d.ts +1 -1
  722. package/dist/profiles/editor/profileEditor.d.ts.map +1 -1
  723. package/dist/profiles/editor/profileEditorPreview.d.ts +1 -1
  724. package/dist/profiles/editor/profileEditorPreview.d.ts.map +1 -1
  725. package/dist/profiles/editor/profileEditorRail.d.ts +1 -1
  726. package/dist/profiles/editor/profileEditorRail.d.ts.map +1 -1
  727. package/dist/profiles/editor/profileEditorRaw.d.ts +1 -1
  728. package/dist/profiles/editor/profileEditorRaw.d.ts.map +1 -1
  729. package/dist/profiles/editor/profileEditorSections.d.ts +3 -3
  730. package/dist/profiles/editor/profileEditorSections.d.ts.map +1 -1
  731. package/dist/profiles/elasticsearch/esParamMappingPill.d.ts +1 -1
  732. package/dist/profiles/elasticsearch/esParamMappingPill.d.ts.map +1 -1
  733. package/dist/profiles/elasticsearch/esParamOperandExtension.d.ts +1 -1
  734. package/dist/profiles/elasticsearch/esQueryBuilder.d.ts +2 -2
  735. package/dist/profiles/elasticsearch/esQueryBuilder.d.ts.map +1 -1
  736. package/dist/profiles/elasticsearch/esQueryClauseGroup.d.ts +1 -1
  737. package/dist/profiles/elasticsearch/esQueryClauseGroup.d.ts.map +1 -1
  738. package/dist/profiles/elasticsearch/esQueryConditionRow.d.ts +1 -1
  739. package/dist/profiles/elasticsearch/esQueryConditionRow.d.ts.map +1 -1
  740. package/dist/profiles/elasticsearch/esQueryOperandEditors.d.ts +2 -2
  741. package/dist/profiles/elasticsearch/esQueryOperandEditors.d.ts.map +1 -1
  742. package/dist/profiles/elasticsearch/esQueryOutputEditor.d.ts +1 -1
  743. package/dist/profiles/elasticsearch/esQueryOutputEditor.d.ts.map +1 -1
  744. package/dist/profiles/elasticsearch/esQueryPreview.d.ts +1 -1
  745. package/dist/profiles/elasticsearch/esQueryPreview.d.ts.map +1 -1
  746. package/dist/profiles/elasticsearch/esQuerySortEditor.d.ts +1 -1
  747. package/dist/profiles/elasticsearch/esQuerySortEditor.d.ts.map +1 -1
  748. package/dist/profiles/elasticsearch/esValueCombobox.d.ts +2 -2
  749. package/dist/profiles/elasticsearch/esValueCombobox.d.ts.map +1 -1
  750. package/dist/profiles/fields/profileColumnPicker.d.ts +1 -1
  751. package/dist/profiles/fields/profileColumnPicker.d.ts.map +1 -1
  752. package/dist/profiles/fields/profileFieldControls.d.ts +3 -3
  753. package/dist/profiles/fields/profileFieldControls.d.ts.map +1 -1
  754. package/dist/profiles/fields/profileFieldEditor.d.ts +3 -3
  755. package/dist/profiles/fields/profileFieldEditor.d.ts.map +1 -1
  756. package/dist/profiles/fields/profileFieldFilterEditor.d.ts +1 -1
  757. package/dist/profiles/fields/profileFieldFilterEditor.d.ts.map +1 -1
  758. package/dist/profiles/fields/profileFieldIcons.d.ts +1 -1
  759. package/dist/profiles/fields/profileFieldList.d.ts +2 -2
  760. package/dist/profiles/fields/profileFieldList.d.ts.map +1 -1
  761. package/dist/profiles/fields/profileFieldManager.d.ts +1 -1
  762. package/dist/profiles/fields/profileFieldManager.d.ts.map +1 -1
  763. package/dist/profiles/fields/profileFieldState.d.ts +1 -1
  764. package/dist/profiles/processor/processorPipeline.d.ts +1 -1
  765. package/dist/profiles/processor/processorPipeline.d.ts.map +1 -1
  766. package/dist/profiles/processor/processorPipelineEditor.d.ts +1 -1
  767. package/dist/profiles/processor/processorPipelineEditor.d.ts.map +1 -1
  768. package/dist/profiles/processor/processorPreviewTable.d.ts +1 -1
  769. package/dist/profiles/processor/processorPreviewTable.d.ts.map +1 -1
  770. package/dist/profiles/query/jsonPathSample.d.ts +1 -1
  771. package/dist/profiles/query/jsonPathSampleRow.d.ts +2 -2
  772. package/dist/profiles/query/jsonPathSampleRow.d.ts.map +1 -1
  773. package/dist/profiles/query/kubernetesWorkloadTargetPicker.d.ts +1 -1
  774. package/dist/profiles/query/kubernetesWorkloadTargetPicker.d.ts.map +1 -1
  775. package/dist/profiles/query/prometheusResults.d.ts +2 -2
  776. package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
  777. package/dist/profiles/query/queryRowLimits.d.ts +1 -1
  778. package/dist/profiles/query/queryRowLimits.d.ts.map +1 -1
  779. package/dist/profiles/query/queryTargetPicker.d.ts +1 -1
  780. package/dist/profiles/query/queryTargetPicker.d.ts.map +1 -1
  781. package/dist/profiles/wizard/profileWizard.d.ts +1 -1
  782. package/dist/profiles/wizard/profileWizard.d.ts.map +1 -1
  783. package/dist/profiles/wizard/profileWizardQueryStep.d.ts +1 -1
  784. package/dist/profiles/wizard/profileWizardQueryStep.d.ts.map +1 -1
  785. package/dist/profiles/wizard/profileWizardSteps.d.ts +4 -4
  786. package/dist/profiles/wizard/profileWizardSteps.d.ts.map +1 -1
  787. package/dist/rpc/ChatLayer.d.ts +1 -1
  788. package/dist/rpc/ChatLayer.d.ts.map +1 -1
  789. package/dist/rpc/CommandForm.d.ts +1 -1
  790. package/dist/rpc/CommandForm.d.ts.map +1 -1
  791. package/dist/rpc/CommandOutput.d.ts +1 -1
  792. package/dist/rpc/CommandOutput.d.ts.map +1 -1
  793. package/dist/rpc/EndpointList.d.ts +2 -2
  794. package/dist/rpc/EndpointList.d.ts.map +1 -1
  795. package/dist/rpc/EntityExplorerApp.d.ts +2 -2
  796. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  797. package/dist/rpc/ExecutionResult.d.ts +1 -1
  798. package/dist/rpc/ExecutionResult.d.ts.map +1 -1
  799. package/dist/rpc/FilterForm.d.ts +1 -1
  800. package/dist/rpc/FilterForm.d.ts.map +1 -1
  801. package/dist/rpc/FilterFormFields.d.ts +1 -1
  802. package/dist/rpc/FilterFormFields.d.ts.map +1 -1
  803. package/dist/rpc/InlineError.d.ts +1 -1
  804. package/dist/rpc/InlineError.d.ts.map +1 -1
  805. package/dist/rpc/OperationActionBar.cjs +17 -5
  806. package/dist/rpc/OperationActionBar.cjs.map +1 -1
  807. package/dist/rpc/OperationActionBar.d.ts +3 -6
  808. package/dist/rpc/OperationActionBar.d.ts.map +1 -1
  809. package/dist/rpc/OperationActionBar.js +17 -5
  810. package/dist/rpc/OperationActionBar.js.map +1 -1
  811. package/dist/rpc/OperationActionDialog.d.ts +1 -1
  812. package/dist/rpc/OperationActionDialog.d.ts.map +1 -1
  813. package/dist/rpc/OperationCatalog.cjs +65 -5
  814. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  815. package/dist/rpc/OperationCatalog.d.ts +4 -2
  816. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  817. package/dist/rpc/OperationCatalog.js +66 -6
  818. package/dist/rpc/OperationCatalog.js.map +1 -1
  819. package/dist/rpc/OperationCatalogActions.cjs +38 -7
  820. package/dist/rpc/OperationCatalogActions.cjs.map +1 -1
  821. package/dist/rpc/OperationCatalogActions.d.ts +6 -1
  822. package/dist/rpc/OperationCatalogActions.d.ts.map +1 -1
  823. package/dist/rpc/OperationCatalogActions.js +38 -7
  824. package/dist/rpc/OperationCatalogActions.js.map +1 -1
  825. package/dist/rpc/OperationCommandPage.d.ts +1 -1
  826. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  827. package/dist/rpc/OperationEntityContextPicker.d.ts +2 -2
  828. package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
  829. package/dist/rpc/OperationEntityPage.d.ts +2 -2
  830. package/dist/rpc/OperationEntityPage.d.ts.map +1 -1
  831. package/dist/rpc/OperationResultView.d.ts +2 -2
  832. package/dist/rpc/OperationResultView.d.ts.map +1 -1
  833. package/dist/rpc/RouterProvider.d.ts +2 -2
  834. package/dist/rpc/RouterProvider.d.ts.map +1 -1
  835. package/dist/rpc/SchemaActionForm.d.ts +2 -2
  836. package/dist/rpc/SchemaActionForm.d.ts.map +1 -1
  837. package/dist/rpc/actionIconMap.cjs +11 -0
  838. package/dist/rpc/actionIconMap.cjs.map +1 -0
  839. package/dist/rpc/actionIconMap.d.ts +3 -0
  840. package/dist/rpc/actionIconMap.d.ts.map +1 -0
  841. package/dist/rpc/actionIconMap.js +11 -0
  842. package/dist/rpc/actionIconMap.js.map +1 -0
  843. package/dist/rpc/formMetadata.d.ts +1 -1
  844. package/dist/rpc/operationErrorDiagnostics.d.ts +1 -1
  845. package/dist/rpc/operationErrorDiagnostics.d.ts.map +1 -1
  846. package/dist/rpc/router.d.ts +1 -1
  847. package/dist/rpc/rpc-story.fixtures.d.ts +1 -1
  848. package/dist/styles.css +1 -1
  849. package/package.json +3 -3
  850. package/dist/components/combobox-utils.cjs.map +0 -1
  851. package/dist/components/combobox-utils.d.ts.map +0 -1
  852. package/dist/components/combobox-utils.js.map +0 -1
@@ -8,6 +8,7 @@ const Icon = require("../data/Icon.cjs");
8
8
  const button = require("../components/button.cjs");
9
9
  const modalStack = require("./modalStack.cjs");
10
10
  const zIndex = require("./zIndex.cjs");
11
+ const UiArrowLeft = require("../icons/components/UiArrowLeft.cjs");
11
12
  const UiFullscreen = require("../icons/components/UiFullscreen.cjs");
12
13
  const UiClose = require("../icons/components/UiClose.cjs");
13
14
  const sizeClass = {
@@ -24,6 +25,25 @@ const DEFAULT_CONFIRM = {
24
25
  confirmLabel: "Discard",
25
26
  cancelLabel: "Keep editing"
26
27
  };
28
+ const MOBILE_QUERY = "(max-width: 639px)";
29
+ const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
30
+ const MOBILE_TRANSITION_MS = 200;
31
+ const FOCUSABLE_SELECTOR = [
32
+ "a[href]",
33
+ "button:not([disabled])",
34
+ "input:not([disabled])",
35
+ "select:not([disabled])",
36
+ "textarea:not([disabled])",
37
+ "[tabindex]:not([tabindex='-1'])"
38
+ ].join(",");
39
+ function visibleFocusableElements(container) {
40
+ return Array.from(
41
+ container.querySelectorAll(FOCUSABLE_SELECTOR)
42
+ ).filter((element) => {
43
+ const style = window.getComputedStyle(element);
44
+ return !element.hidden && style.display !== "none" && style.visibility !== "hidden";
45
+ });
46
+ }
27
47
  function Modal({
28
48
  open,
29
49
  onClose,
@@ -42,13 +62,46 @@ function Modal({
42
62
  children
43
63
  }) {
44
64
  const dialogRef = react.useRef(null);
45
- const { depth } = modalStack.useModalStack(open);
65
+ const closeTimerRef = react.useRef(void 0);
66
+ const openFrameRef = react.useRef(void 0);
67
+ const [present, setPresent] = react.useState(open);
68
+ const [mobileVisible, setMobileVisible] = react.useState(false);
69
+ const { depth } = modalStack.useModalStack(present);
46
70
  const [expanded, setExpanded] = react.useState(false);
47
71
  const [confirming, setConfirming] = react.useState(false);
48
72
  const requestClose = () => {
49
73
  if (confirmClose) setConfirming(true);
50
74
  else onClose();
51
75
  };
76
+ react.useEffect(() => {
77
+ window.clearTimeout(closeTimerRef.current);
78
+ window.cancelAnimationFrame(openFrameRef.current ?? 0);
79
+ const animateMobile = window.matchMedia(MOBILE_QUERY).matches && !window.matchMedia(REDUCED_MOTION_QUERY).matches;
80
+ if (open) {
81
+ setPresent(true);
82
+ if (animateMobile) {
83
+ setMobileVisible(false);
84
+ openFrameRef.current = window.requestAnimationFrame(() => {
85
+ setMobileVisible(true);
86
+ });
87
+ } else {
88
+ setMobileVisible(true);
89
+ }
90
+ } else if (animateMobile) {
91
+ setMobileVisible(false);
92
+ closeTimerRef.current = window.setTimeout(
93
+ () => setPresent(false),
94
+ MOBILE_TRANSITION_MS
95
+ );
96
+ } else {
97
+ setMobileVisible(false);
98
+ setPresent(false);
99
+ }
100
+ return () => {
101
+ window.clearTimeout(closeTimerRef.current);
102
+ window.cancelAnimationFrame(openFrameRef.current ?? 0);
103
+ };
104
+ }, [open]);
52
105
  react.useEffect(() => {
53
106
  if (!open) {
54
107
  setExpanded(false);
@@ -58,14 +111,11 @@ function Modal({
58
111
  react.useEffect(() => {
59
112
  if (!confirmClose) setConfirming(false);
60
113
  }, [confirmClose]);
61
- modalStack.useEscapeLayer(
62
- open,
63
- () => {
64
- if (confirming) setConfirming(false);
65
- else requestClose();
66
- },
67
- closeOnEsc
68
- );
114
+ modalStack.useEscapeLayer(present, () => {
115
+ if (!open || !closeOnEsc) return;
116
+ if (confirming) setConfirming(false);
117
+ else requestClose();
118
+ });
69
119
  react.useEffect(() => {
70
120
  var _a;
71
121
  if (!open) return;
@@ -76,12 +126,12 @@ function Modal({
76
126
  return (_a2 = prev == null ? void 0 : prev.focus) == null ? void 0 : _a2.call(prev);
77
127
  };
78
128
  }, [open]);
79
- if (!open) return null;
129
+ if (!present) return null;
80
130
  const overlay = /* @__PURE__ */ jsxRuntime.jsx(
81
131
  "div",
82
132
  {
83
133
  className: utils.cn(
84
- "fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4",
134
+ "fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4 max-sm:items-stretch max-sm:justify-end max-sm:p-0 max-sm:!bg-transparent",
85
135
  // Nested modals dim less so the dialog they opened over stays visible.
86
136
  depth === 0 ? "bg-black/40" : "bg-black/20"
87
137
  ),
@@ -96,8 +146,12 @@ function Modal({
96
146
  role: "dialog",
97
147
  "aria-modal": "true",
98
148
  "aria-label": typeof title === "string" ? title : void 0,
149
+ "data-state": mobileVisible ? "open" : "closed",
99
150
  className: utils.cn(
100
151
  "relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
152
+ "max-sm:!h-dvh max-sm:!max-h-dvh max-sm:!max-w-none max-sm:!rounded-none max-sm:!border-0 max-sm:shadow-none",
153
+ "max-sm:transition-transform max-sm:duration-200 max-sm:ease-out max-sm:motion-reduce:transition-none",
154
+ "max-sm:data-[state=closed]:translate-x-full max-sm:data-[state=open]:translate-x-0",
101
155
  expanded ? sizeClass.full : sizeClass[size],
102
156
  className
103
157
  ),
@@ -106,10 +160,43 @@ function Modal({
106
160
  ...expanded ? { height: "calc(100dvh - 2rem)" } : {}
107
161
  },
108
162
  onClick: (e) => e.stopPropagation(),
163
+ onKeyDown: (event) => {
164
+ var _a;
165
+ if (event.key !== "Tab") return;
166
+ const scope = confirming ? (_a = dialogRef.current) == null ? void 0 : _a.querySelector(
167
+ "[role='alertdialog']"
168
+ ) : dialogRef.current;
169
+ if (!scope) return;
170
+ const focusable = visibleFocusableElements(scope);
171
+ const first = focusable[0];
172
+ const last = focusable[focusable.length - 1];
173
+ if (!first || !last) {
174
+ event.preventDefault();
175
+ scope.focus();
176
+ } else if (event.shiftKey && document.activeElement === first) {
177
+ event.preventDefault();
178
+ last.focus();
179
+ } else if (!event.shiftKey && document.activeElement === last) {
180
+ event.preventDefault();
181
+ first.focus();
182
+ }
183
+ },
109
184
  children: [
110
- (title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 px-density-4 py-density-3 border-b border-border", children: [
185
+ (title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 px-density-4 py-density-3 border-b border-border max-sm:min-h-14 max-sm:bg-background", children: [
111
186
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-density-2", children: [
112
- title ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold flex-1", children: title }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
187
+ !hideClose && /* @__PURE__ */ jsxRuntime.jsx(
188
+ button.Button,
189
+ {
190
+ type: "button",
191
+ onClick: requestClose,
192
+ variant: "ghost",
193
+ size: "icon",
194
+ "aria-label": "Back",
195
+ className: "-ml-2 text-foreground sm:hidden",
196
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiArrowLeft.UiArrowLeft })
197
+ }
198
+ ),
199
+ title ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold flex-1 max-sm:text-base max-sm:leading-6", children: title }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
113
200
  headerSlot,
114
201
  expandable && /* @__PURE__ */ jsxRuntime.jsx(
115
202
  "button",
@@ -117,7 +204,7 @@ function Modal({
117
204
  type: "button",
118
205
  onClick: () => setExpanded((v) => !v),
119
206
  "aria-label": expanded ? "Restore size" : "Expand to fullscreen",
120
- className: "text-muted-foreground hover:text-foreground",
207
+ className: "text-muted-foreground hover:text-foreground max-sm:hidden",
121
208
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: expanded ? UiFullscreen.UiFullscreenFilled : UiFullscreen.UiFullscreen })
122
209
  }
123
210
  ),
@@ -127,7 +214,7 @@ function Modal({
127
214
  type: "button",
128
215
  onClick: requestClose,
129
216
  "aria-label": "Close",
130
- className: "text-muted-foreground hover:text-foreground",
217
+ className: "text-muted-foreground hover:text-foreground max-sm:hidden",
131
218
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClose.UiClose })
132
219
  }
133
220
  )
@@ -139,7 +226,7 @@ function Modal({
139
226
  {
140
227
  "data-slot": "modal-body",
141
228
  className: utils.cn(
142
- "min-h-0 flex-1 px-density-4 py-density-3",
229
+ "min-h-0 flex-1 px-density-4 py-density-3 max-sm:py-density-4",
143
230
  scrollBody ? "overflow-auto" : "flex flex-col overflow-hidden"
144
231
  ),
145
232
  children
@@ -149,7 +236,7 @@ function Modal({
149
236
  "div",
150
237
  {
151
238
  "data-slot": "modal-footer",
152
- className: "shrink-0 px-density-4 py-density-3 border-t border-border",
239
+ className: "shrink-0 px-density-4 py-density-3 border-t border-border max-sm:py-density-4",
153
240
  children: footer
154
241
  }
155
242
  ),
@@ -179,7 +266,7 @@ function ConfirmClosePrompt({
179
266
  return /* @__PURE__ */ jsxRuntime.jsx(
180
267
  "div",
181
268
  {
182
- className: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4",
269
+ className: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4 max-sm:rounded-none",
183
270
  role: "alertdialog",
184
271
  "aria-modal": "true",
185
272
  "aria-label": typeof options.title === "string" ? options.title : "Confirm close",
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.cjs","sources":["../../src/overlay/Modal.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { Button } from \"../components/button\";\nimport { UiClose, UiFullscreen, UiFullscreenFilled } from \"../icons\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"full\";\n\n/** Copy for the discard-confirmation prompt shown before a guarded close. */\nexport type ConfirmCloseOptions = {\n /** Heading of the confirmation prompt. */\n title?: ReactNode;\n /** Body explaining what is lost on close. */\n message?: ReactNode;\n /** Label of the button that proceeds with closing. */\n confirmLabel?: string;\n /** Label of the button that dismisses the prompt and keeps the modal open. */\n cancelLabel?: string;\n};\n\nexport type ModalProps = {\n /** Controls whether the modal is mounted. */\n open: boolean;\n /** Called when the modal requests to close. */\n onClose: () => void;\n /**\n * Guard every close path (close button, Escape, backdrop) behind a discard\n * confirmation. `true` uses the default copy; pass options to customise it.\n * `onClose` only fires once the user confirms. Set this while the modal holds\n * unsaved edits and clear it (or pass `false`) once there is nothing to lose.\n */\n confirmClose?: boolean | ConfirmCloseOptions;\n /** Header title and accessible dialog label when it is a string. */\n title?: ReactNode;\n /**\n * Secondary header content rendered on its own row directly beneath the title.\n * The title stays a single row alongside the expand/close buttons, so a tall\n * subtitle (e.g. a tab switcher) never pushes those buttons down.\n */\n subtitle?: ReactNode;\n /** Width/height preset for the dialog. */\n size?: ModalSize;\n /** Close when the backdrop is clicked. Off by default; close via Escape or the close button. */\n closeOnBackdrop?: boolean;\n /** Close when Escape is pressed. */\n closeOnEsc?: boolean;\n /** Hide the close button. */\n hideClose?: boolean;\n /** Show an expand/restore button. */\n expandable?: boolean;\n /** Classes applied to the dialog panel. */\n className?: string;\n /** Extra header content rendered before the expand/close buttons. */\n headerSlot?: ReactNode;\n /** Footer content pinned below the scrollable body. */\n footer?: ReactNode;\n /**\n * Whether the body scrolls its overflow. Default `true`. Set `false` when the\n * body owns a single fill-height child that scrolls internally (e.g. a\n * DataTable with a sticky header): the body becomes a non-scrolling flex\n * column, so only that child's own scroll region moves.\n */\n scrollBody?: boolean;\n /** Modal body content. */\n children: ReactNode;\n};\n\nconst sizeClass: Record<ModalSize, string> = {\n sm: \"max-w-sm\",\n md: \"max-w-md\",\n lg: \"max-w-2xl\",\n xl: \"max-w-4xl\",\n \"2xl\": \"max-w-6xl\",\n full: \"max-w-[95vw]\",\n};\n\nconst DEFAULT_CONFIRM: Required<ConfirmCloseOptions> = {\n title: \"Discard changes?\",\n message: \"You have unsaved changes. Closing now will discard them.\",\n confirmLabel: \"Discard\",\n cancelLabel: \"Keep editing\",\n};\n\nexport function Modal({\n open,\n onClose,\n confirmClose = false,\n title,\n subtitle,\n size = \"md\",\n closeOnBackdrop = false,\n closeOnEsc = true,\n hideClose = false,\n expandable = true,\n className,\n headerSlot,\n footer,\n scrollBody = true,\n children,\n}: ModalProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const { depth } = useModalStack(open);\n const [expanded, setExpanded] = useState(false);\n // When confirmClose is active, a close request opens this prompt instead of\n // closing outright; onClose only fires once the user confirms the discard.\n const [confirming, setConfirming] = useState(false);\n\n // requestClose is the single entry point for every close affordance. With the\n // guard on, it surfaces the confirmation; otherwise it closes immediately.\n const requestClose = () => {\n if (confirmClose) setConfirming(true);\n else onClose();\n };\n\n useEffect(() => {\n if (!open) {\n setExpanded(false);\n setConfirming(false);\n }\n }, [open]);\n\n // A close guard that disappears mid-prompt (changes saved/reverted) should\n // not leave a stale confirmation dialog up.\n useEffect(() => {\n if (!confirmClose) setConfirming(false);\n }, [confirmClose]);\n\n useEscapeLayer(\n open,\n () => {\n // While the prompt is up, Escape dismisses the prompt rather than the modal.\n if (confirming) setConfirming(false);\n else requestClose();\n },\n closeOnEsc,\n );\n\n useEffect(() => {\n if (!open) return;\n const prev = document.activeElement as HTMLElement | null;\n dialogRef.current?.focus();\n return () => prev?.focus?.();\n }, [open]);\n\n if (!open) return null;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4\",\n // Nested modals dim less so the dialog they opened over stays visible.\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n // Sits in the modal band of the centralized z-index scale; +depth keeps\n // nested modals above their parent. Floating content (dropdowns, tooltips)\n // computes its z relative to this via useFloatingZIndex so it clears the\n // modal instead of rendering behind it.\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n onClick={closeOnBackdrop ? requestClose : undefined}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n className={cn(\n \"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n expanded ? sizeClass.full : sizeClass[size],\n className,\n )}\n // Inline maxHeight (not an arbitrary Tailwind class) so the panel stays\n // viewport-bounded even when a consumer's Tailwind build can't generate\n // the dvh utility — e.g. www aliases clicky-ui to source but scans the\n // published dist. When expanded, fill the viewport.\n style={{\n maxHeight: \"calc(100dvh - 2rem)\",\n ...(expanded ? { height: \"calc(100dvh - 2rem)\" } : {}),\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {(title || subtitle || headerSlot || expandable || !hideClose) && (\n <div className=\"shrink-0 px-density-4 py-density-3 border-b border-border\">\n <div className=\"flex items-center gap-density-2\">\n {title ? (\n <h2 className=\"text-sm font-semibold flex-1\">{title}</h2>\n ) : (\n <span className=\"flex-1\" />\n )}\n {headerSlot}\n {expandable && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-label={\n expanded ? \"Restore size\" : \"Expand to fullscreen\"\n }\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={expanded ? UiFullscreenFilled : UiFullscreen} />\n </button>\n )}\n {!hideClose && (\n <button\n type=\"button\"\n onClick={requestClose}\n aria-label=\"Close\"\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </div>\n {subtitle ? <div className=\"mt-density-2\">{subtitle}</div> : null}\n </div>\n )}\n <div\n data-slot=\"modal-body\"\n className={cn(\n \"min-h-0 flex-1 px-density-4 py-density-3\",\n scrollBody\n ? \"overflow-auto\"\n : \"flex flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div\n data-slot=\"modal-footer\"\n className=\"shrink-0 px-density-4 py-density-3 border-t border-border\"\n >\n {footer}\n </div>\n )}\n {confirming && (\n <ConfirmClosePrompt\n options={\n confirmClose === true\n ? DEFAULT_CONFIRM\n : { ...DEFAULT_CONFIRM, ...confirmClose }\n }\n onConfirm={() => {\n setConfirming(false);\n onClose();\n }}\n onCancel={() => setConfirming(false)}\n />\n )}\n </div>\n </div>\n );\n\n // Render into document.body so the fixed-position overlay escapes any ancestor\n // transform/overflow (e.g. a dropdown menu positioned via a CSS transform),\n // which would otherwise trap position:fixed inside that ancestor's box and clip\n // the modal to it.\n return typeof document !== \"undefined\"\n ? createPortal(overlay, document.body)\n : null;\n}\n\nfunction ConfirmClosePrompt({\n options,\n onConfirm,\n onCancel,\n}: {\n options: Required<ConfirmCloseOptions>;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n return (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-label={\n typeof options.title === \"string\" ? options.title : \"Confirm close\"\n }\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"w-full max-w-sm rounded-lg border border-border bg-background p-density-4 shadow-xl\">\n <h3 className=\"text-sm font-semibold\">{options.title}</h3>\n <p className=\"mt-density-2 text-sm text-muted-foreground\">\n {options.message}\n </p>\n <div className=\"mt-density-4 flex justify-end gap-density-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {options.cancelLabel}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onConfirm}>\n {options.confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["useRef","useModalStack","useState","useEffect","useEscapeLayer","_a","jsx","cn","zIndex","jsxs","Icon","UiFullscreenFilled","UiFullscreen","UiClose","createPortal","Button"],"mappings":"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"}
1
+ {"version":3,"file":"Modal.cjs","sources":["../../src/overlay/Modal.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { Button } from \"../components/button\";\nimport {\n UiArrowLeft,\n UiClose,\n UiFullscreen,\n UiFullscreenFilled,\n} from \"../icons\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"full\";\n\n/** Copy for the discard-confirmation prompt shown before a guarded close. */\nexport type ConfirmCloseOptions = {\n /** Heading of the confirmation prompt. */\n title?: ReactNode;\n /** Body explaining what is lost on close. */\n message?: ReactNode;\n /** Label of the button that proceeds with closing. */\n confirmLabel?: string;\n /** Label of the button that dismisses the prompt and keeps the modal open. */\n cancelLabel?: string;\n};\n\nexport type ModalProps = {\n /** Controls whether the modal is mounted. */\n open: boolean;\n /** Called when the modal requests to close. */\n onClose: () => void;\n /**\n * Guard every close path (close button, Escape, backdrop) behind a discard\n * confirmation. `true` uses the default copy; pass options to customise it.\n * `onClose` only fires once the user confirms. Set this while the modal holds\n * unsaved edits and clear it (or pass `false`) once there is nothing to lose.\n */\n confirmClose?: boolean | ConfirmCloseOptions;\n /** Header title and accessible dialog label when it is a string. */\n title?: ReactNode;\n /**\n * Secondary header content rendered on its own row directly beneath the title.\n * The title stays a single row alongside the expand/close buttons, so a tall\n * subtitle (e.g. a tab switcher) never pushes those buttons down.\n */\n subtitle?: ReactNode;\n /** Width/height preset for the dialog. */\n size?: ModalSize;\n /** Close when the backdrop is clicked. Off by default; close via Escape or the close button. */\n closeOnBackdrop?: boolean;\n /** Close when Escape is pressed. */\n closeOnEsc?: boolean;\n /** Hide the close button. */\n hideClose?: boolean;\n /** Show an expand/restore button. */\n expandable?: boolean;\n /** Classes applied to the dialog panel. */\n className?: string;\n /** Extra header content rendered before the expand/close buttons. */\n headerSlot?: ReactNode;\n /** Footer content pinned below the scrollable body. */\n footer?: ReactNode;\n /**\n * Whether the body scrolls its overflow. Default `true`. Set `false` when the\n * body owns a single fill-height child that scrolls internally (e.g. a\n * DataTable with a sticky header): the body becomes a non-scrolling flex\n * column, so only that child's own scroll region moves.\n */\n scrollBody?: boolean;\n /** Modal body content. */\n children: ReactNode;\n};\n\nconst sizeClass: Record<ModalSize, string> = {\n sm: \"max-w-sm\",\n md: \"max-w-md\",\n lg: \"max-w-2xl\",\n xl: \"max-w-4xl\",\n \"2xl\": \"max-w-6xl\",\n full: \"max-w-[95vw]\",\n};\n\nconst DEFAULT_CONFIRM: Required<ConfirmCloseOptions> = {\n title: \"Discard changes?\",\n message: \"You have unsaved changes. Closing now will discard them.\",\n confirmLabel: \"Discard\",\n cancelLabel: \"Keep editing\",\n};\n\nconst MOBILE_QUERY = \"(max-width: 639px)\";\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst MOBILE_TRANSITION_MS = 200;\nconst FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"[tabindex]:not([tabindex='-1'])\",\n].join(\",\");\n\nfunction visibleFocusableElements(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((element) => {\n const style = window.getComputedStyle(element);\n return (\n !element.hidden &&\n style.display !== \"none\" &&\n style.visibility !== \"hidden\"\n );\n });\n}\n\nexport function Modal({\n open,\n onClose,\n confirmClose = false,\n title,\n subtitle,\n size = \"md\",\n closeOnBackdrop = false,\n closeOnEsc = true,\n hideClose = false,\n expandable = true,\n className,\n headerSlot,\n footer,\n scrollBody = true,\n children,\n}: ModalProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const closeTimerRef = useRef<number | undefined>(undefined);\n const openFrameRef = useRef<number | undefined>(undefined);\n const [present, setPresent] = useState(open);\n const [mobileVisible, setMobileVisible] = useState(false);\n const { depth } = useModalStack(present);\n const [expanded, setExpanded] = useState(false);\n // When confirmClose is active, a close request opens this prompt instead of\n // closing outright; onClose only fires once the user confirms the discard.\n const [confirming, setConfirming] = useState(false);\n\n // requestClose is the single entry point for every close affordance. With the\n // guard on, it surfaces the confirmation; otherwise it closes immediately.\n const requestClose = () => {\n if (confirmClose) setConfirming(true);\n else onClose();\n };\n\n useEffect(() => {\n window.clearTimeout(closeTimerRef.current);\n window.cancelAnimationFrame(openFrameRef.current ?? 0);\n const animateMobile =\n window.matchMedia(MOBILE_QUERY).matches &&\n !window.matchMedia(REDUCED_MOTION_QUERY).matches;\n\n if (open) {\n setPresent(true);\n if (animateMobile) {\n setMobileVisible(false);\n openFrameRef.current = window.requestAnimationFrame(() => {\n setMobileVisible(true);\n });\n } else {\n setMobileVisible(true);\n }\n } else if (animateMobile) {\n setMobileVisible(false);\n closeTimerRef.current = window.setTimeout(\n () => setPresent(false),\n MOBILE_TRANSITION_MS,\n );\n } else {\n setMobileVisible(false);\n setPresent(false);\n }\n\n return () => {\n window.clearTimeout(closeTimerRef.current);\n window.cancelAnimationFrame(openFrameRef.current ?? 0);\n };\n }, [open]);\n\n useEffect(() => {\n if (!open) {\n setExpanded(false);\n setConfirming(false);\n }\n }, [open]);\n\n // A close guard that disappears mid-prompt (changes saved/reverted) should\n // not leave a stale confirmation dialog up.\n useEffect(() => {\n if (!confirmClose) setConfirming(false);\n }, [confirmClose]);\n\n useEscapeLayer(present, () => {\n if (!open || !closeOnEsc) return;\n // While the prompt is up, Escape dismisses the prompt rather than the modal.\n if (confirming) setConfirming(false);\n else requestClose();\n });\n\n useEffect(() => {\n if (!open) return;\n const prev = document.activeElement as HTMLElement | null;\n dialogRef.current?.focus();\n return () => prev?.focus?.();\n }, [open]);\n\n if (!present) return null;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4 max-sm:items-stretch max-sm:justify-end max-sm:p-0 max-sm:!bg-transparent\",\n // Nested modals dim less so the dialog they opened over stays visible.\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n // Sits in the modal band of the centralized z-index scale; +depth keeps\n // nested modals above their parent. Floating content (dropdowns, tooltips)\n // computes its z relative to this via useFloatingZIndex so it clears the\n // modal instead of rendering behind it.\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n onClick={closeOnBackdrop ? requestClose : undefined}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n data-state={mobileVisible ? \"open\" : \"closed\"}\n className={cn(\n \"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n \"max-sm:!h-dvh max-sm:!max-h-dvh max-sm:!max-w-none max-sm:!rounded-none max-sm:!border-0 max-sm:shadow-none\",\n \"max-sm:transition-transform max-sm:duration-200 max-sm:ease-out max-sm:motion-reduce:transition-none\",\n \"max-sm:data-[state=closed]:translate-x-full max-sm:data-[state=open]:translate-x-0\",\n expanded ? sizeClass.full : sizeClass[size],\n className,\n )}\n // Inline maxHeight (not an arbitrary Tailwind class) so the panel stays\n // viewport-bounded even when a consumer's Tailwind build can't generate\n // the dvh utility — e.g. www aliases clicky-ui to source but scans the\n // published dist. When expanded, fill the viewport.\n style={{\n maxHeight: \"calc(100dvh - 2rem)\",\n ...(expanded ? { height: \"calc(100dvh - 2rem)\" } : {}),\n }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(event) => {\n if (event.key !== \"Tab\") return;\n const scope = confirming\n ? dialogRef.current?.querySelector<HTMLElement>(\n \"[role='alertdialog']\",\n )\n : dialogRef.current;\n if (!scope) return;\n const focusable = visibleFocusableElements(scope);\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (!first || !last) {\n event.preventDefault();\n scope.focus();\n } else if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }}\n >\n {(title || subtitle || headerSlot || expandable || !hideClose) && (\n <div className=\"shrink-0 px-density-4 py-density-3 border-b border-border max-sm:min-h-14 max-sm:bg-background\">\n <div className=\"flex items-center gap-density-2\">\n {!hideClose && (\n <Button\n type=\"button\"\n onClick={requestClose}\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Back\"\n className=\"-ml-2 text-foreground sm:hidden\"\n >\n <Icon icon={UiArrowLeft} />\n </Button>\n )}\n {title ? (\n <h2 className=\"text-sm font-semibold flex-1 max-sm:text-base max-sm:leading-6\">\n {title}\n </h2>\n ) : (\n <span className=\"flex-1\" />\n )}\n {headerSlot}\n {expandable && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-label={\n expanded ? \"Restore size\" : \"Expand to fullscreen\"\n }\n className=\"text-muted-foreground hover:text-foreground max-sm:hidden\"\n >\n <Icon icon={expanded ? UiFullscreenFilled : UiFullscreen} />\n </button>\n )}\n {!hideClose && (\n <button\n type=\"button\"\n onClick={requestClose}\n aria-label=\"Close\"\n className=\"text-muted-foreground hover:text-foreground max-sm:hidden\"\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </div>\n {subtitle ? <div className=\"mt-density-2\">{subtitle}</div> : null}\n </div>\n )}\n <div\n data-slot=\"modal-body\"\n className={cn(\n \"min-h-0 flex-1 px-density-4 py-density-3 max-sm:py-density-4\",\n scrollBody ? \"overflow-auto\" : \"flex flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div\n data-slot=\"modal-footer\"\n className=\"shrink-0 px-density-4 py-density-3 border-t border-border max-sm:py-density-4\"\n >\n {footer}\n </div>\n )}\n {confirming && (\n <ConfirmClosePrompt\n options={\n confirmClose === true\n ? DEFAULT_CONFIRM\n : { ...DEFAULT_CONFIRM, ...confirmClose }\n }\n onConfirm={() => {\n setConfirming(false);\n onClose();\n }}\n onCancel={() => setConfirming(false)}\n />\n )}\n </div>\n </div>\n );\n\n // Render into document.body so the fixed-position overlay escapes any ancestor\n // transform/overflow (e.g. a dropdown menu positioned via a CSS transform),\n // which would otherwise trap position:fixed inside that ancestor's box and clip\n // the modal to it.\n return typeof document !== \"undefined\"\n ? createPortal(overlay, document.body)\n : null;\n}\n\nfunction ConfirmClosePrompt({\n options,\n onConfirm,\n onCancel,\n}: {\n options: Required<ConfirmCloseOptions>;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n return (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4 max-sm:rounded-none\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-label={\n typeof options.title === \"string\" ? options.title : \"Confirm close\"\n }\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"w-full max-w-sm rounded-lg border border-border bg-background p-density-4 shadow-xl\">\n <h3 className=\"text-sm font-semibold\">{options.title}</h3>\n <p className=\"mt-density-2 text-sm text-muted-foreground\">\n {options.message}\n </p>\n <div className=\"mt-density-4 flex justify-end gap-density-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {options.cancelLabel}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onConfirm}>\n {options.confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["useRef","useState","useModalStack","useEffect","useEscapeLayer","_a","jsx","cn","zIndex","jsxs","Button","Icon","UiArrowLeft","UiFullscreenFilled","UiFullscreen","UiClose","createPortal"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { ReactNode } from '../../../../node_modules/@types/react/index.d.ts';
2
2
  export type ModalSize = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
3
3
  /** Copy for the discard-confirmation prompt shown before a guarded close. */
4
4
  export type ConfirmCloseOptions = {
@@ -57,5 +57,5 @@ export type ModalProps = {
57
57
  /** Modal body content. */
58
58
  children: ReactNode;
59
59
  };
60
- export declare function Modal({ open, onClose, confirmClose, title, subtitle, size, closeOnBackdrop, closeOnEsc, hideClose, expandable, className, headerSlot, footer, scrollBody, children, }: ModalProps): import('react').ReactPortal | null;
60
+ export declare function Modal({ open, onClose, confirmClose, title, subtitle, size, closeOnBackdrop, closeOnEsc, hideClose, expandable, className, headerSlot, footer, scrollBody, children, }: ModalProps): import('../../../../node_modules/@types/react/index.d.ts').ReactPortal | null;
61
61
  //# sourceMappingURL=Modal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/overlay/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASpE,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnE,6EAA6E;AAC7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,6CAA6C;IAC7C,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAC7C,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,uDAAuD;IACvD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0BAA0B;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAkBF,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,OAAO,EACP,YAAoB,EACpB,KAAK,EACL,QAAQ,EACR,IAAW,EACX,eAAuB,EACvB,UAAiB,EACjB,SAAiB,EACjB,UAAiB,EACjB,SAAS,EACT,UAAU,EACV,MAAM,EACN,UAAiB,EACjB,QAAQ,GACT,EAAE,UAAU,sCAkKZ"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/overlay/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAcpE,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnE,6EAA6E;AAC7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,6CAA6C;IAC7C,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAC7C,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,uDAAuD;IACvD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0BAA0B;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AA2CF,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,OAAO,EACP,YAAoB,EACpB,KAAK,EACL,QAAQ,EACR,IAAW,EACX,eAAuB,EACvB,UAAiB,EACjB,SAAiB,EACjB,UAAiB,EACjB,SAAS,EACT,UAAU,EACV,MAAM,EACN,UAAiB,EACjB,QAAQ,GACT,EAAE,UAAU,sCA2OZ"}
@@ -6,6 +6,7 @@ import { Icon } from "../data/Icon.js";
6
6
  import { Button } from "../components/button.js";
7
7
  import { useModalStack, useEscapeLayer } from "./modalStack.js";
8
8
  import { zIndex } from "./zIndex.js";
9
+ import { UiArrowLeft } from "../icons/components/UiArrowLeft.js";
9
10
  import { UiFullscreenFilled, UiFullscreen } from "../icons/components/UiFullscreen.js";
10
11
  import { UiClose } from "../icons/components/UiClose.js";
11
12
  const sizeClass = {
@@ -22,6 +23,25 @@ const DEFAULT_CONFIRM = {
22
23
  confirmLabel: "Discard",
23
24
  cancelLabel: "Keep editing"
24
25
  };
26
+ const MOBILE_QUERY = "(max-width: 639px)";
27
+ const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
28
+ const MOBILE_TRANSITION_MS = 200;
29
+ const FOCUSABLE_SELECTOR = [
30
+ "a[href]",
31
+ "button:not([disabled])",
32
+ "input:not([disabled])",
33
+ "select:not([disabled])",
34
+ "textarea:not([disabled])",
35
+ "[tabindex]:not([tabindex='-1'])"
36
+ ].join(",");
37
+ function visibleFocusableElements(container) {
38
+ return Array.from(
39
+ container.querySelectorAll(FOCUSABLE_SELECTOR)
40
+ ).filter((element) => {
41
+ const style = window.getComputedStyle(element);
42
+ return !element.hidden && style.display !== "none" && style.visibility !== "hidden";
43
+ });
44
+ }
25
45
  function Modal({
26
46
  open,
27
47
  onClose,
@@ -40,13 +60,46 @@ function Modal({
40
60
  children
41
61
  }) {
42
62
  const dialogRef = useRef(null);
43
- const { depth } = useModalStack(open);
63
+ const closeTimerRef = useRef(void 0);
64
+ const openFrameRef = useRef(void 0);
65
+ const [present, setPresent] = useState(open);
66
+ const [mobileVisible, setMobileVisible] = useState(false);
67
+ const { depth } = useModalStack(present);
44
68
  const [expanded, setExpanded] = useState(false);
45
69
  const [confirming, setConfirming] = useState(false);
46
70
  const requestClose = () => {
47
71
  if (confirmClose) setConfirming(true);
48
72
  else onClose();
49
73
  };
74
+ useEffect(() => {
75
+ window.clearTimeout(closeTimerRef.current);
76
+ window.cancelAnimationFrame(openFrameRef.current ?? 0);
77
+ const animateMobile = window.matchMedia(MOBILE_QUERY).matches && !window.matchMedia(REDUCED_MOTION_QUERY).matches;
78
+ if (open) {
79
+ setPresent(true);
80
+ if (animateMobile) {
81
+ setMobileVisible(false);
82
+ openFrameRef.current = window.requestAnimationFrame(() => {
83
+ setMobileVisible(true);
84
+ });
85
+ } else {
86
+ setMobileVisible(true);
87
+ }
88
+ } else if (animateMobile) {
89
+ setMobileVisible(false);
90
+ closeTimerRef.current = window.setTimeout(
91
+ () => setPresent(false),
92
+ MOBILE_TRANSITION_MS
93
+ );
94
+ } else {
95
+ setMobileVisible(false);
96
+ setPresent(false);
97
+ }
98
+ return () => {
99
+ window.clearTimeout(closeTimerRef.current);
100
+ window.cancelAnimationFrame(openFrameRef.current ?? 0);
101
+ };
102
+ }, [open]);
50
103
  useEffect(() => {
51
104
  if (!open) {
52
105
  setExpanded(false);
@@ -56,14 +109,11 @@ function Modal({
56
109
  useEffect(() => {
57
110
  if (!confirmClose) setConfirming(false);
58
111
  }, [confirmClose]);
59
- useEscapeLayer(
60
- open,
61
- () => {
62
- if (confirming) setConfirming(false);
63
- else requestClose();
64
- },
65
- closeOnEsc
66
- );
112
+ useEscapeLayer(present, () => {
113
+ if (!open || !closeOnEsc) return;
114
+ if (confirming) setConfirming(false);
115
+ else requestClose();
116
+ });
67
117
  useEffect(() => {
68
118
  var _a;
69
119
  if (!open) return;
@@ -74,12 +124,12 @@ function Modal({
74
124
  return (_a2 = prev == null ? void 0 : prev.focus) == null ? void 0 : _a2.call(prev);
75
125
  };
76
126
  }, [open]);
77
- if (!open) return null;
127
+ if (!present) return null;
78
128
  const overlay = /* @__PURE__ */ jsx(
79
129
  "div",
80
130
  {
81
131
  className: cn(
82
- "fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4",
132
+ "fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4 max-sm:items-stretch max-sm:justify-end max-sm:p-0 max-sm:!bg-transparent",
83
133
  // Nested modals dim less so the dialog they opened over stays visible.
84
134
  depth === 0 ? "bg-black/40" : "bg-black/20"
85
135
  ),
@@ -94,8 +144,12 @@ function Modal({
94
144
  role: "dialog",
95
145
  "aria-modal": "true",
96
146
  "aria-label": typeof title === "string" ? title : void 0,
147
+ "data-state": mobileVisible ? "open" : "closed",
97
148
  className: cn(
98
149
  "relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
150
+ "max-sm:!h-dvh max-sm:!max-h-dvh max-sm:!max-w-none max-sm:!rounded-none max-sm:!border-0 max-sm:shadow-none",
151
+ "max-sm:transition-transform max-sm:duration-200 max-sm:ease-out max-sm:motion-reduce:transition-none",
152
+ "max-sm:data-[state=closed]:translate-x-full max-sm:data-[state=open]:translate-x-0",
99
153
  expanded ? sizeClass.full : sizeClass[size],
100
154
  className
101
155
  ),
@@ -104,10 +158,43 @@ function Modal({
104
158
  ...expanded ? { height: "calc(100dvh - 2rem)" } : {}
105
159
  },
106
160
  onClick: (e) => e.stopPropagation(),
161
+ onKeyDown: (event) => {
162
+ var _a;
163
+ if (event.key !== "Tab") return;
164
+ const scope = confirming ? (_a = dialogRef.current) == null ? void 0 : _a.querySelector(
165
+ "[role='alertdialog']"
166
+ ) : dialogRef.current;
167
+ if (!scope) return;
168
+ const focusable = visibleFocusableElements(scope);
169
+ const first = focusable[0];
170
+ const last = focusable[focusable.length - 1];
171
+ if (!first || !last) {
172
+ event.preventDefault();
173
+ scope.focus();
174
+ } else if (event.shiftKey && document.activeElement === first) {
175
+ event.preventDefault();
176
+ last.focus();
177
+ } else if (!event.shiftKey && document.activeElement === last) {
178
+ event.preventDefault();
179
+ first.focus();
180
+ }
181
+ },
107
182
  children: [
108
- (title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxs("div", { className: "shrink-0 px-density-4 py-density-3 border-b border-border", children: [
183
+ (title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxs("div", { className: "shrink-0 px-density-4 py-density-3 border-b border-border max-sm:min-h-14 max-sm:bg-background", children: [
109
184
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2", children: [
110
- title ? /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold flex-1", children: title }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
185
+ !hideClose && /* @__PURE__ */ jsx(
186
+ Button,
187
+ {
188
+ type: "button",
189
+ onClick: requestClose,
190
+ variant: "ghost",
191
+ size: "icon",
192
+ "aria-label": "Back",
193
+ className: "-ml-2 text-foreground sm:hidden",
194
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiArrowLeft })
195
+ }
196
+ ),
197
+ title ? /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold flex-1 max-sm:text-base max-sm:leading-6", children: title }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
111
198
  headerSlot,
112
199
  expandable && /* @__PURE__ */ jsx(
113
200
  "button",
@@ -115,7 +202,7 @@ function Modal({
115
202
  type: "button",
116
203
  onClick: () => setExpanded((v) => !v),
117
204
  "aria-label": expanded ? "Restore size" : "Expand to fullscreen",
118
- className: "text-muted-foreground hover:text-foreground",
205
+ className: "text-muted-foreground hover:text-foreground max-sm:hidden",
119
206
  children: /* @__PURE__ */ jsx(Icon, { icon: expanded ? UiFullscreenFilled : UiFullscreen })
120
207
  }
121
208
  ),
@@ -125,7 +212,7 @@ function Modal({
125
212
  type: "button",
126
213
  onClick: requestClose,
127
214
  "aria-label": "Close",
128
- className: "text-muted-foreground hover:text-foreground",
215
+ className: "text-muted-foreground hover:text-foreground max-sm:hidden",
129
216
  children: /* @__PURE__ */ jsx(Icon, { icon: UiClose })
130
217
  }
131
218
  )
@@ -137,7 +224,7 @@ function Modal({
137
224
  {
138
225
  "data-slot": "modal-body",
139
226
  className: cn(
140
- "min-h-0 flex-1 px-density-4 py-density-3",
227
+ "min-h-0 flex-1 px-density-4 py-density-3 max-sm:py-density-4",
141
228
  scrollBody ? "overflow-auto" : "flex flex-col overflow-hidden"
142
229
  ),
143
230
  children
@@ -147,7 +234,7 @@ function Modal({
147
234
  "div",
148
235
  {
149
236
  "data-slot": "modal-footer",
150
- className: "shrink-0 px-density-4 py-density-3 border-t border-border",
237
+ className: "shrink-0 px-density-4 py-density-3 border-t border-border max-sm:py-density-4",
151
238
  children: footer
152
239
  }
153
240
  ),
@@ -177,7 +264,7 @@ function ConfirmClosePrompt({
177
264
  return /* @__PURE__ */ jsx(
178
265
  "div",
179
266
  {
180
- className: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4",
267
+ className: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4 max-sm:rounded-none",
181
268
  role: "alertdialog",
182
269
  "aria-modal": "true",
183
270
  "aria-label": typeof options.title === "string" ? options.title : "Confirm close",
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sources":["../../src/overlay/Modal.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { Button } from \"../components/button\";\nimport { UiClose, UiFullscreen, UiFullscreenFilled } from \"../icons\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"full\";\n\n/** Copy for the discard-confirmation prompt shown before a guarded close. */\nexport type ConfirmCloseOptions = {\n /** Heading of the confirmation prompt. */\n title?: ReactNode;\n /** Body explaining what is lost on close. */\n message?: ReactNode;\n /** Label of the button that proceeds with closing. */\n confirmLabel?: string;\n /** Label of the button that dismisses the prompt and keeps the modal open. */\n cancelLabel?: string;\n};\n\nexport type ModalProps = {\n /** Controls whether the modal is mounted. */\n open: boolean;\n /** Called when the modal requests to close. */\n onClose: () => void;\n /**\n * Guard every close path (close button, Escape, backdrop) behind a discard\n * confirmation. `true` uses the default copy; pass options to customise it.\n * `onClose` only fires once the user confirms. Set this while the modal holds\n * unsaved edits and clear it (or pass `false`) once there is nothing to lose.\n */\n confirmClose?: boolean | ConfirmCloseOptions;\n /** Header title and accessible dialog label when it is a string. */\n title?: ReactNode;\n /**\n * Secondary header content rendered on its own row directly beneath the title.\n * The title stays a single row alongside the expand/close buttons, so a tall\n * subtitle (e.g. a tab switcher) never pushes those buttons down.\n */\n subtitle?: ReactNode;\n /** Width/height preset for the dialog. */\n size?: ModalSize;\n /** Close when the backdrop is clicked. Off by default; close via Escape or the close button. */\n closeOnBackdrop?: boolean;\n /** Close when Escape is pressed. */\n closeOnEsc?: boolean;\n /** Hide the close button. */\n hideClose?: boolean;\n /** Show an expand/restore button. */\n expandable?: boolean;\n /** Classes applied to the dialog panel. */\n className?: string;\n /** Extra header content rendered before the expand/close buttons. */\n headerSlot?: ReactNode;\n /** Footer content pinned below the scrollable body. */\n footer?: ReactNode;\n /**\n * Whether the body scrolls its overflow. Default `true`. Set `false` when the\n * body owns a single fill-height child that scrolls internally (e.g. a\n * DataTable with a sticky header): the body becomes a non-scrolling flex\n * column, so only that child's own scroll region moves.\n */\n scrollBody?: boolean;\n /** Modal body content. */\n children: ReactNode;\n};\n\nconst sizeClass: Record<ModalSize, string> = {\n sm: \"max-w-sm\",\n md: \"max-w-md\",\n lg: \"max-w-2xl\",\n xl: \"max-w-4xl\",\n \"2xl\": \"max-w-6xl\",\n full: \"max-w-[95vw]\",\n};\n\nconst DEFAULT_CONFIRM: Required<ConfirmCloseOptions> = {\n title: \"Discard changes?\",\n message: \"You have unsaved changes. Closing now will discard them.\",\n confirmLabel: \"Discard\",\n cancelLabel: \"Keep editing\",\n};\n\nexport function Modal({\n open,\n onClose,\n confirmClose = false,\n title,\n subtitle,\n size = \"md\",\n closeOnBackdrop = false,\n closeOnEsc = true,\n hideClose = false,\n expandable = true,\n className,\n headerSlot,\n footer,\n scrollBody = true,\n children,\n}: ModalProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const { depth } = useModalStack(open);\n const [expanded, setExpanded] = useState(false);\n // When confirmClose is active, a close request opens this prompt instead of\n // closing outright; onClose only fires once the user confirms the discard.\n const [confirming, setConfirming] = useState(false);\n\n // requestClose is the single entry point for every close affordance. With the\n // guard on, it surfaces the confirmation; otherwise it closes immediately.\n const requestClose = () => {\n if (confirmClose) setConfirming(true);\n else onClose();\n };\n\n useEffect(() => {\n if (!open) {\n setExpanded(false);\n setConfirming(false);\n }\n }, [open]);\n\n // A close guard that disappears mid-prompt (changes saved/reverted) should\n // not leave a stale confirmation dialog up.\n useEffect(() => {\n if (!confirmClose) setConfirming(false);\n }, [confirmClose]);\n\n useEscapeLayer(\n open,\n () => {\n // While the prompt is up, Escape dismisses the prompt rather than the modal.\n if (confirming) setConfirming(false);\n else requestClose();\n },\n closeOnEsc,\n );\n\n useEffect(() => {\n if (!open) return;\n const prev = document.activeElement as HTMLElement | null;\n dialogRef.current?.focus();\n return () => prev?.focus?.();\n }, [open]);\n\n if (!open) return null;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4\",\n // Nested modals dim less so the dialog they opened over stays visible.\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n // Sits in the modal band of the centralized z-index scale; +depth keeps\n // nested modals above their parent. Floating content (dropdowns, tooltips)\n // computes its z relative to this via useFloatingZIndex so it clears the\n // modal instead of rendering behind it.\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n onClick={closeOnBackdrop ? requestClose : undefined}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n className={cn(\n \"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n expanded ? sizeClass.full : sizeClass[size],\n className,\n )}\n // Inline maxHeight (not an arbitrary Tailwind class) so the panel stays\n // viewport-bounded even when a consumer's Tailwind build can't generate\n // the dvh utility — e.g. www aliases clicky-ui to source but scans the\n // published dist. When expanded, fill the viewport.\n style={{\n maxHeight: \"calc(100dvh - 2rem)\",\n ...(expanded ? { height: \"calc(100dvh - 2rem)\" } : {}),\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {(title || subtitle || headerSlot || expandable || !hideClose) && (\n <div className=\"shrink-0 px-density-4 py-density-3 border-b border-border\">\n <div className=\"flex items-center gap-density-2\">\n {title ? (\n <h2 className=\"text-sm font-semibold flex-1\">{title}</h2>\n ) : (\n <span className=\"flex-1\" />\n )}\n {headerSlot}\n {expandable && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-label={\n expanded ? \"Restore size\" : \"Expand to fullscreen\"\n }\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={expanded ? UiFullscreenFilled : UiFullscreen} />\n </button>\n )}\n {!hideClose && (\n <button\n type=\"button\"\n onClick={requestClose}\n aria-label=\"Close\"\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </div>\n {subtitle ? <div className=\"mt-density-2\">{subtitle}</div> : null}\n </div>\n )}\n <div\n data-slot=\"modal-body\"\n className={cn(\n \"min-h-0 flex-1 px-density-4 py-density-3\",\n scrollBody\n ? \"overflow-auto\"\n : \"flex flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div\n data-slot=\"modal-footer\"\n className=\"shrink-0 px-density-4 py-density-3 border-t border-border\"\n >\n {footer}\n </div>\n )}\n {confirming && (\n <ConfirmClosePrompt\n options={\n confirmClose === true\n ? DEFAULT_CONFIRM\n : { ...DEFAULT_CONFIRM, ...confirmClose }\n }\n onConfirm={() => {\n setConfirming(false);\n onClose();\n }}\n onCancel={() => setConfirming(false)}\n />\n )}\n </div>\n </div>\n );\n\n // Render into document.body so the fixed-position overlay escapes any ancestor\n // transform/overflow (e.g. a dropdown menu positioned via a CSS transform),\n // which would otherwise trap position:fixed inside that ancestor's box and clip\n // the modal to it.\n return typeof document !== \"undefined\"\n ? createPortal(overlay, document.body)\n : null;\n}\n\nfunction ConfirmClosePrompt({\n options,\n onConfirm,\n onCancel,\n}: {\n options: Required<ConfirmCloseOptions>;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n return (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-label={\n typeof options.title === \"string\" ? options.title : \"Confirm close\"\n }\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"w-full max-w-sm rounded-lg border border-border bg-background p-density-4 shadow-xl\">\n <h3 className=\"text-sm font-semibold\">{options.title}</h3>\n <p className=\"mt-density-2 text-sm text-muted-foreground\">\n {options.message}\n </p>\n <div className=\"mt-density-4 flex justify-end gap-density-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {options.cancelLabel}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onConfirm}>\n {options.confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"Modal.js","sources":["../../src/overlay/Modal.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { Button } from \"../components/button\";\nimport {\n UiArrowLeft,\n UiClose,\n UiFullscreen,\n UiFullscreenFilled,\n} from \"../icons\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"full\";\n\n/** Copy for the discard-confirmation prompt shown before a guarded close. */\nexport type ConfirmCloseOptions = {\n /** Heading of the confirmation prompt. */\n title?: ReactNode;\n /** Body explaining what is lost on close. */\n message?: ReactNode;\n /** Label of the button that proceeds with closing. */\n confirmLabel?: string;\n /** Label of the button that dismisses the prompt and keeps the modal open. */\n cancelLabel?: string;\n};\n\nexport type ModalProps = {\n /** Controls whether the modal is mounted. */\n open: boolean;\n /** Called when the modal requests to close. */\n onClose: () => void;\n /**\n * Guard every close path (close button, Escape, backdrop) behind a discard\n * confirmation. `true` uses the default copy; pass options to customise it.\n * `onClose` only fires once the user confirms. Set this while the modal holds\n * unsaved edits and clear it (or pass `false`) once there is nothing to lose.\n */\n confirmClose?: boolean | ConfirmCloseOptions;\n /** Header title and accessible dialog label when it is a string. */\n title?: ReactNode;\n /**\n * Secondary header content rendered on its own row directly beneath the title.\n * The title stays a single row alongside the expand/close buttons, so a tall\n * subtitle (e.g. a tab switcher) never pushes those buttons down.\n */\n subtitle?: ReactNode;\n /** Width/height preset for the dialog. */\n size?: ModalSize;\n /** Close when the backdrop is clicked. Off by default; close via Escape or the close button. */\n closeOnBackdrop?: boolean;\n /** Close when Escape is pressed. */\n closeOnEsc?: boolean;\n /** Hide the close button. */\n hideClose?: boolean;\n /** Show an expand/restore button. */\n expandable?: boolean;\n /** Classes applied to the dialog panel. */\n className?: string;\n /** Extra header content rendered before the expand/close buttons. */\n headerSlot?: ReactNode;\n /** Footer content pinned below the scrollable body. */\n footer?: ReactNode;\n /**\n * Whether the body scrolls its overflow. Default `true`. Set `false` when the\n * body owns a single fill-height child that scrolls internally (e.g. a\n * DataTable with a sticky header): the body becomes a non-scrolling flex\n * column, so only that child's own scroll region moves.\n */\n scrollBody?: boolean;\n /** Modal body content. */\n children: ReactNode;\n};\n\nconst sizeClass: Record<ModalSize, string> = {\n sm: \"max-w-sm\",\n md: \"max-w-md\",\n lg: \"max-w-2xl\",\n xl: \"max-w-4xl\",\n \"2xl\": \"max-w-6xl\",\n full: \"max-w-[95vw]\",\n};\n\nconst DEFAULT_CONFIRM: Required<ConfirmCloseOptions> = {\n title: \"Discard changes?\",\n message: \"You have unsaved changes. Closing now will discard them.\",\n confirmLabel: \"Discard\",\n cancelLabel: \"Keep editing\",\n};\n\nconst MOBILE_QUERY = \"(max-width: 639px)\";\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst MOBILE_TRANSITION_MS = 200;\nconst FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"[tabindex]:not([tabindex='-1'])\",\n].join(\",\");\n\nfunction visibleFocusableElements(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((element) => {\n const style = window.getComputedStyle(element);\n return (\n !element.hidden &&\n style.display !== \"none\" &&\n style.visibility !== \"hidden\"\n );\n });\n}\n\nexport function Modal({\n open,\n onClose,\n confirmClose = false,\n title,\n subtitle,\n size = \"md\",\n closeOnBackdrop = false,\n closeOnEsc = true,\n hideClose = false,\n expandable = true,\n className,\n headerSlot,\n footer,\n scrollBody = true,\n children,\n}: ModalProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const closeTimerRef = useRef<number | undefined>(undefined);\n const openFrameRef = useRef<number | undefined>(undefined);\n const [present, setPresent] = useState(open);\n const [mobileVisible, setMobileVisible] = useState(false);\n const { depth } = useModalStack(present);\n const [expanded, setExpanded] = useState(false);\n // When confirmClose is active, a close request opens this prompt instead of\n // closing outright; onClose only fires once the user confirms the discard.\n const [confirming, setConfirming] = useState(false);\n\n // requestClose is the single entry point for every close affordance. With the\n // guard on, it surfaces the confirmation; otherwise it closes immediately.\n const requestClose = () => {\n if (confirmClose) setConfirming(true);\n else onClose();\n };\n\n useEffect(() => {\n window.clearTimeout(closeTimerRef.current);\n window.cancelAnimationFrame(openFrameRef.current ?? 0);\n const animateMobile =\n window.matchMedia(MOBILE_QUERY).matches &&\n !window.matchMedia(REDUCED_MOTION_QUERY).matches;\n\n if (open) {\n setPresent(true);\n if (animateMobile) {\n setMobileVisible(false);\n openFrameRef.current = window.requestAnimationFrame(() => {\n setMobileVisible(true);\n });\n } else {\n setMobileVisible(true);\n }\n } else if (animateMobile) {\n setMobileVisible(false);\n closeTimerRef.current = window.setTimeout(\n () => setPresent(false),\n MOBILE_TRANSITION_MS,\n );\n } else {\n setMobileVisible(false);\n setPresent(false);\n }\n\n return () => {\n window.clearTimeout(closeTimerRef.current);\n window.cancelAnimationFrame(openFrameRef.current ?? 0);\n };\n }, [open]);\n\n useEffect(() => {\n if (!open) {\n setExpanded(false);\n setConfirming(false);\n }\n }, [open]);\n\n // A close guard that disappears mid-prompt (changes saved/reverted) should\n // not leave a stale confirmation dialog up.\n useEffect(() => {\n if (!confirmClose) setConfirming(false);\n }, [confirmClose]);\n\n useEscapeLayer(present, () => {\n if (!open || !closeOnEsc) return;\n // While the prompt is up, Escape dismisses the prompt rather than the modal.\n if (confirming) setConfirming(false);\n else requestClose();\n });\n\n useEffect(() => {\n if (!open) return;\n const prev = document.activeElement as HTMLElement | null;\n dialogRef.current?.focus();\n return () => prev?.focus?.();\n }, [open]);\n\n if (!present) return null;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex items-center justify-center p-density-2 sm:p-density-4 max-sm:items-stretch max-sm:justify-end max-sm:p-0 max-sm:!bg-transparent\",\n // Nested modals dim less so the dialog they opened over stays visible.\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n // Sits in the modal band of the centralized z-index scale; +depth keeps\n // nested modals above their parent. Floating content (dropdowns, tooltips)\n // computes its z relative to this via useFloatingZIndex so it clears the\n // modal instead of rendering behind it.\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n onClick={closeOnBackdrop ? requestClose : undefined}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n data-state={mobileVisible ? \"open\" : \"closed\"}\n className={cn(\n \"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n \"max-sm:!h-dvh max-sm:!max-h-dvh max-sm:!max-w-none max-sm:!rounded-none max-sm:!border-0 max-sm:shadow-none\",\n \"max-sm:transition-transform max-sm:duration-200 max-sm:ease-out max-sm:motion-reduce:transition-none\",\n \"max-sm:data-[state=closed]:translate-x-full max-sm:data-[state=open]:translate-x-0\",\n expanded ? sizeClass.full : sizeClass[size],\n className,\n )}\n // Inline maxHeight (not an arbitrary Tailwind class) so the panel stays\n // viewport-bounded even when a consumer's Tailwind build can't generate\n // the dvh utility — e.g. www aliases clicky-ui to source but scans the\n // published dist. When expanded, fill the viewport.\n style={{\n maxHeight: \"calc(100dvh - 2rem)\",\n ...(expanded ? { height: \"calc(100dvh - 2rem)\" } : {}),\n }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(event) => {\n if (event.key !== \"Tab\") return;\n const scope = confirming\n ? dialogRef.current?.querySelector<HTMLElement>(\n \"[role='alertdialog']\",\n )\n : dialogRef.current;\n if (!scope) return;\n const focusable = visibleFocusableElements(scope);\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (!first || !last) {\n event.preventDefault();\n scope.focus();\n } else if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }}\n >\n {(title || subtitle || headerSlot || expandable || !hideClose) && (\n <div className=\"shrink-0 px-density-4 py-density-3 border-b border-border max-sm:min-h-14 max-sm:bg-background\">\n <div className=\"flex items-center gap-density-2\">\n {!hideClose && (\n <Button\n type=\"button\"\n onClick={requestClose}\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Back\"\n className=\"-ml-2 text-foreground sm:hidden\"\n >\n <Icon icon={UiArrowLeft} />\n </Button>\n )}\n {title ? (\n <h2 className=\"text-sm font-semibold flex-1 max-sm:text-base max-sm:leading-6\">\n {title}\n </h2>\n ) : (\n <span className=\"flex-1\" />\n )}\n {headerSlot}\n {expandable && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-label={\n expanded ? \"Restore size\" : \"Expand to fullscreen\"\n }\n className=\"text-muted-foreground hover:text-foreground max-sm:hidden\"\n >\n <Icon icon={expanded ? UiFullscreenFilled : UiFullscreen} />\n </button>\n )}\n {!hideClose && (\n <button\n type=\"button\"\n onClick={requestClose}\n aria-label=\"Close\"\n className=\"text-muted-foreground hover:text-foreground max-sm:hidden\"\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </div>\n {subtitle ? <div className=\"mt-density-2\">{subtitle}</div> : null}\n </div>\n )}\n <div\n data-slot=\"modal-body\"\n className={cn(\n \"min-h-0 flex-1 px-density-4 py-density-3 max-sm:py-density-4\",\n scrollBody ? \"overflow-auto\" : \"flex flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div\n data-slot=\"modal-footer\"\n className=\"shrink-0 px-density-4 py-density-3 border-t border-border max-sm:py-density-4\"\n >\n {footer}\n </div>\n )}\n {confirming && (\n <ConfirmClosePrompt\n options={\n confirmClose === true\n ? DEFAULT_CONFIRM\n : { ...DEFAULT_CONFIRM, ...confirmClose }\n }\n onConfirm={() => {\n setConfirming(false);\n onClose();\n }}\n onCancel={() => setConfirming(false)}\n />\n )}\n </div>\n </div>\n );\n\n // Render into document.body so the fixed-position overlay escapes any ancestor\n // transform/overflow (e.g. a dropdown menu positioned via a CSS transform),\n // which would otherwise trap position:fixed inside that ancestor's box and clip\n // the modal to it.\n return typeof document !== \"undefined\"\n ? createPortal(overlay, document.body)\n : null;\n}\n\nfunction ConfirmClosePrompt({\n options,\n onConfirm,\n onCancel,\n}: {\n options: Required<ConfirmCloseOptions>;\n onConfirm: () => void;\n onCancel: () => void;\n}) {\n return (\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-background/80 p-density-4 max-sm:rounded-none\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-label={\n typeof options.title === \"string\" ? options.title : \"Confirm close\"\n }\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"w-full max-w-sm rounded-lg border border-border bg-background p-density-4 shadow-xl\">\n <h3 className=\"text-sm font-semibold\">{options.title}</h3>\n <p className=\"mt-density-2 text-sm text-muted-foreground\">\n {options.message}\n </p>\n <div className=\"mt-density-4 flex justify-end gap-density-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n {options.cancelLabel}\n </Button>\n <Button variant=\"destructive\" size=\"sm\" onClick={onConfirm}>\n {options.confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["_a"],"mappings":";;;;;;;;;;;AA2EA,MAAM,YAAuC;AAAA,EAC3C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAM;AACR;AAEA,MAAM,kBAAiD;AAAA,EACrD,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AACf;AAEA,MAAM,eAAe;AACrB,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,SAAS,yBAAyB,WAAuC;AACvE,SAAO,MAAM;AAAA,IACX,UAAU,iBAA8B,kBAAkB;AAAA,EAAA,EAC1D,OAAO,CAAC,YAAY;AACpB,UAAM,QAAQ,OAAO,iBAAiB,OAAO;AAC7C,WACE,CAAC,QAAQ,UACT,MAAM,YAAY,UAClB,MAAM,eAAe;AAAA,EAEzB,CAAC;AACH;AAEO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACF,GAAe;AACb,QAAM,YAAY,OAAuB,IAAI;AAC7C,QAAM,gBAAgB,OAA2B,MAAS;AAC1D,QAAM,eAAe,OAA2B,MAAS;AACzD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AACxD,QAAM,EAAE,MAAA,IAAU,cAAc,OAAO;AACvC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAG9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAIlD,QAAM,eAAe,MAAM;AACzB,QAAI,4BAA4B,IAAI;AAAA,QAC/B,SAAA;AAAA,EACP;AAEA,YAAU,MAAM;AACd,WAAO,aAAa,cAAc,OAAO;AACzC,WAAO,qBAAqB,aAAa,WAAW,CAAC;AACrD,UAAM,gBACJ,OAAO,WAAW,YAAY,EAAE,WAChC,CAAC,OAAO,WAAW,oBAAoB,EAAE;AAE3C,QAAI,MAAM;AACR,iBAAW,IAAI;AACf,UAAI,eAAe;AACjB,yBAAiB,KAAK;AACtB,qBAAa,UAAU,OAAO,sBAAsB,MAAM;AACxD,2BAAiB,IAAI;AAAA,QACvB,CAAC;AAAA,MACH,OAAO;AACL,yBAAiB,IAAI;AAAA,MACvB;AAAA,IACF,WAAW,eAAe;AACxB,uBAAiB,KAAK;AACtB,oBAAc,UAAU,OAAO;AAAA,QAC7B,MAAM,WAAW,KAAK;AAAA,QACtB;AAAA,MAAA;AAAA,IAEJ,OAAO;AACL,uBAAiB,KAAK;AACtB,iBAAW,KAAK;AAAA,IAClB;AAEA,WAAO,MAAM;AACX,aAAO,aAAa,cAAc,OAAO;AACzC,aAAO,qBAAqB,aAAa,WAAW,CAAC;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,YAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,kBAAY,KAAK;AACjB,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAIT,YAAU,MAAM;AACd,QAAI,CAAC,aAAc,eAAc,KAAK;AAAA,EACxC,GAAG,CAAC,YAAY,CAAC;AAEjB,iBAAe,SAAS,MAAM;AAC5B,QAAI,CAAC,QAAQ,CAAC,WAAY;AAE1B,QAAI,0BAA0B,KAAK;AAAA,QAC9B,cAAA;AAAA,EACP,CAAC;AAED,YAAU,MAAM;;AACd,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,SAAS;AACtB,oBAAU,YAAV,mBAAmB;AACnB,WAAO,MAAA;;AAAM,cAAAA,MAAA,6BAAM,UAAN,gBAAAA,IAAA;AAAA;AAAA,EACf,GAAG,CAAC,IAAI,CAAC;AAET,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,UACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA;AAAA,QAEA,UAAU,IAAI,gBAAgB;AAAA,MAAA;AAAA,MAMhC,OAAO,EAAE,QAAQ,OAAO,QAAQ,QAAQ,OAAO,UAAA;AAAA,MAC/C,SAAS,kBAAkB,eAAe;AAAA,MAC1C,MAAK;AAAA,MAEL,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,UAAU;AAAA,UACV,MAAK;AAAA,UACL,cAAW;AAAA,UACX,cAAY,OAAO,UAAU,WAAW,QAAQ;AAAA,UAChD,cAAY,gBAAgB,SAAS;AAAA,UACrC,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW,UAAU,OAAO,UAAU,IAAI;AAAA,YAC1C;AAAA,UAAA;AAAA,UAMF,OAAO;AAAA,YACL,WAAW;AAAA,YACX,GAAI,WAAW,EAAE,QAAQ,0BAA0B,CAAA;AAAA,UAAC;AAAA,UAEtD,SAAS,CAAC,MAAM,EAAE,gBAAA;AAAA,UAClB,WAAW,CAAC,UAAU;;AACpB,gBAAI,MAAM,QAAQ,MAAO;AACzB,kBAAM,QAAQ,cACV,eAAU,YAAV,mBAAmB;AAAA,cACjB;AAAA,gBAEF,UAAU;AACd,gBAAI,CAAC,MAAO;AACZ,kBAAM,YAAY,yBAAyB,KAAK;AAChD,kBAAM,QAAQ,UAAU,CAAC;AACzB,kBAAM,OAAO,UAAU,UAAU,SAAS,CAAC;AAC3C,gBAAI,CAAC,SAAS,CAAC,MAAM;AACnB,oBAAM,eAAA;AACN,oBAAM,MAAA;AAAA,YACR,WAAW,MAAM,YAAY,SAAS,kBAAkB,OAAO;AAC7D,oBAAM,eAAA;AACN,mBAAK,MAAA;AAAA,YACP,WAAW,CAAC,MAAM,YAAY,SAAS,kBAAkB,MAAM;AAC7D,oBAAM,eAAA;AACN,oBAAM,MAAA;AAAA,YACR;AAAA,UACF;AAAA,UAEE,UAAA;AAAA,aAAA,SAAS,YAAY,cAAc,cAAc,CAAC,cAClD,qBAAC,OAAA,EAAI,WAAU,kGACb,UAAA;AAAA,cAAA,qBAAC,OAAA,EAAI,WAAU,mCACZ,UAAA;AAAA,gBAAA,CAAC,aACA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS;AAAA,oBACT,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,cAAW;AAAA,oBACX,WAAU;AAAA,oBAEV,UAAA,oBAAC,MAAA,EAAK,MAAM,YAAA,CAAa;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAG5B,QACC,oBAAC,MAAA,EAAG,WAAU,kEACX,iBACH,IAEA,oBAAC,QAAA,EAAK,WAAU,SAAA,CAAS;AAAA,gBAE1B;AAAA,gBACA,cACC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;AAAA,oBACpC,cACE,WAAW,iBAAiB;AAAA,oBAE9B,WAAU;AAAA,oBAEV,UAAA,oBAAC,MAAA,EAAK,MAAM,WAAW,qBAAqB,aAAA,CAAc;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAG7D,CAAC,aACA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAW;AAAA,oBACX,WAAU;AAAA,oBAEV,UAAA,oBAAC,MAAA,EAAK,MAAM,QAAA,CAAS;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACvB,GAEJ;AAAA,cACC,WAAW,oBAAC,OAAA,EAAI,WAAU,gBAAgB,oBAAS,IAAS;AAAA,YAAA,GAC/D;AAAA,YAEF;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,aAAU;AAAA,gBACV,WAAW;AAAA,kBACT;AAAA,kBACA,aAAa,kBAAkB;AAAA,gBAAA;AAAA,gBAGhC;AAAA,cAAA;AAAA,YAAA;AAAA,YAEF,UACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,aAAU;AAAA,gBACV,WAAU;AAAA,gBAET,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGJ,cACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SACE,iBAAiB,OACb,kBACA,EAAE,GAAG,iBAAiB,GAAG,aAAA;AAAA,gBAE/B,WAAW,MAAM;AACf,gCAAc,KAAK;AACnB,0BAAA;AAAA,gBACF;AAAA,gBACA,UAAU,MAAM,cAAc,KAAK;AAAA,cAAA;AAAA,YAAA;AAAA,UACrC;AAAA,QAAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAQJ,SAAO,OAAO,aAAa,cACvB,aAAa,SAAS,SAAS,IAAI,IACnC;AACN;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAK;AAAA,MACL,cAAW;AAAA,MACX,cACE,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAAA,MAEtD,SAAS,CAAC,MAAM,EAAE,gBAAA;AAAA,MAElB,UAAA,qBAAC,OAAA,EAAI,WAAU,uFACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,yBAAyB,UAAA,QAAQ,OAAM;AAAA,QACrD,oBAAC,KAAA,EAAE,WAAU,8CACV,kBAAQ,SACX;AAAA,QACA,qBAAC,OAAA,EAAI,WAAU,+CACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,UACxC,kBAAQ,YAAA,CACX;AAAA,UACA,oBAAC,UAAO,SAAQ,eAAc,MAAK,MAAK,SAAS,WAC9C,UAAA,QAAQ,aAAA,CACX;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}