@flanksource/clicky-ui 0.3.15 → 0.3.17
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.
- package/NOTICE.md +10 -0
- package/dist/ai.cjs +33 -4
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +31 -2
- package/dist/ai.js.map +1 -1
- package/dist/chat.cjs +6 -0
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.js +7 -1
- package/dist/chat.js.map +1 -1
- package/dist/components/Combobox.cjs +92 -170
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +2 -111
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +95 -173
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/ComboboxActions.cjs +70 -0
- package/dist/components/ComboboxActions.cjs.map +1 -0
- package/dist/components/ComboboxActions.d.ts +8 -0
- package/dist/components/ComboboxActions.d.ts.map +1 -0
- package/dist/components/ComboboxActions.js +70 -0
- package/dist/components/ComboboxActions.js.map +1 -0
- package/dist/components/ComboboxMenu.cjs +160 -0
- package/dist/components/ComboboxMenu.cjs.map +1 -0
- package/dist/components/ComboboxMenu.d.ts +22 -0
- package/dist/components/ComboboxMenu.d.ts.map +1 -0
- package/dist/components/ComboboxMenu.js +160 -0
- package/dist/components/ComboboxMenu.js.map +1 -0
- package/dist/components/EndpointSelector.cjs +407 -0
- package/dist/components/EndpointSelector.cjs.map +1 -0
- package/dist/components/EndpointSelector.d.ts +3 -0
- package/dist/components/EndpointSelector.d.ts.map +1 -0
- package/dist/components/EndpointSelector.js +407 -0
- package/dist/components/EndpointSelector.js.map +1 -0
- package/dist/components/EndpointSelector.model.d.ts +52 -0
- package/dist/components/EndpointSelector.model.d.ts.map +1 -0
- package/dist/components/FilterBar.cjs +12 -0
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +4 -0
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +12 -0
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/InputField.cjs +11 -12
- package/dist/components/InputField.cjs.map +1 -1
- package/dist/components/InputField.d.ts +7 -0
- package/dist/components/InputField.d.ts.map +1 -1
- package/dist/components/InputField.js +12 -13
- package/dist/components/InputField.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +22 -16
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +22 -16
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/MultiSelect.cjs +3 -3
- package/dist/components/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect.d.ts.map +1 -1
- package/dist/components/MultiSelect.js +3 -3
- package/dist/components/MultiSelect.js.map +1 -1
- package/dist/components/SecretKeySelector.cjs +150 -77
- package/dist/components/SecretKeySelector.cjs.map +1 -1
- package/dist/components/SecretKeySelector.d.ts.map +1 -1
- package/dist/components/SecretKeySelector.js +151 -78
- package/dist/components/SecretKeySelector.js.map +1 -1
- package/dist/components/WorkloadPicker.cjs +2 -1
- package/dist/components/WorkloadPicker.cjs.map +1 -1
- package/dist/components/WorkloadPicker.d.ts +6 -1
- package/dist/components/WorkloadPicker.d.ts.map +1 -1
- package/dist/components/WorkloadPicker.js +2 -1
- package/dist/components/WorkloadPicker.js.map +1 -1
- package/dist/components/combobox-types.d.ts +107 -0
- package/dist/components/combobox-types.d.ts.map +1 -0
- package/dist/components/combobox-utils.cjs +21 -0
- package/dist/components/combobox-utils.cjs.map +1 -0
- package/dist/components/combobox-utils.d.ts +15 -0
- package/dist/components/combobox-utils.d.ts.map +1 -0
- package/dist/components/combobox-utils.js +21 -0
- package/dist/components/combobox-utils.js.map +1 -0
- package/dist/components/endpoint-port.cjs +12 -0
- package/dist/components/endpoint-port.cjs.map +1 -0
- package/dist/components/endpoint-port.d.ts +4 -0
- package/dist/components/endpoint-port.d.ts.map +1 -0
- package/dist/components/endpoint-port.js +12 -0
- package/dist/components/endpoint-port.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +12 -23
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +12 -23
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-discriminator.cjs +6 -2
- package/dist/components/json-schema-form-discriminator.cjs.map +1 -1
- package/dist/components/json-schema-form-discriminator.d.ts.map +1 -1
- package/dist/components/json-schema-form-discriminator.js +6 -2
- package/dist/components/json-schema-form-discriminator.js.map +1 -1
- package/dist/components/json-schema-form-error-display.cjs +50 -0
- package/dist/components/json-schema-form-error-display.cjs.map +1 -0
- package/dist/components/json-schema-form-error-display.d.ts +12 -0
- package/dist/components/json-schema-form-error-display.d.ts.map +1 -0
- package/dist/components/json-schema-form-error-display.js +50 -0
- package/dist/components/json-schema-form-error-display.js.map +1 -0
- package/dist/components/json-schema-form-error-types.d.ts +26 -0
- package/dist/components/json-schema-form-error-types.d.ts.map +1 -0
- package/dist/components/json-schema-form-errors.cjs +169 -0
- package/dist/components/json-schema-form-errors.cjs.map +1 -0
- package/dist/components/json-schema-form-errors.d.ts +14 -0
- package/dist/components/json-schema-form-errors.d.ts.map +1 -0
- package/dist/components/json-schema-form-errors.js +169 -0
- package/dist/components/json-schema-form-errors.js.map +1 -0
- package/dist/components/json-schema-form-object.cjs +12 -2
- package/dist/components/json-schema-form-object.cjs.map +1 -1
- package/dist/components/json-schema-form-object.d.ts.map +1 -1
- package/dist/components/json-schema-form-object.js +12 -2
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-refs.cjs +84 -19
- package/dist/components/json-schema-form-refs.cjs.map +1 -1
- package/dist/components/json-schema-form-refs.d.ts.map +1 -1
- package/dist/components/json-schema-form-refs.js +84 -19
- package/dist/components/json-schema-form-refs.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +33 -10
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +34 -11
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +16 -4
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts +1 -0
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +17 -5
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +4 -3
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components.cjs +13 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +8 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +15 -2
- package/dist/components.js.map +1 -1
- package/dist/data/DataTable.cjs +205 -14
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +41 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.grouping.cjs +21 -0
- package/dist/data/DataTable.grouping.cjs.map +1 -0
- package/dist/data/DataTable.grouping.d.ts +26 -0
- package/dist/data/DataTable.grouping.d.ts.map +1 -0
- package/dist/data/DataTable.grouping.js +21 -0
- package/dist/data/DataTable.grouping.js.map +1 -0
- package/dist/data/DataTable.js +205 -14
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Markdown.cjs +45 -1
- package/dist/data/Markdown.cjs.map +1 -1
- package/dist/data/Markdown.d.ts +3 -2
- package/dist/data/Markdown.d.ts.map +1 -1
- package/dist/data/Markdown.js +45 -1
- package/dist/data/Markdown.js.map +1 -1
- package/dist/data/MarkdownEditor.cjs +4 -3
- package/dist/data/MarkdownEditor.cjs.map +1 -1
- package/dist/data/MarkdownEditor.d.ts +6 -2
- package/dist/data/MarkdownEditor.d.ts.map +1 -1
- package/dist/data/MarkdownEditor.js +4 -3
- package/dist/data/MarkdownEditor.js.map +1 -1
- package/dist/data/ServerTimingBadge.cjs +64 -0
- package/dist/data/ServerTimingBadge.cjs.map +1 -0
- package/dist/data/ServerTimingBadge.d.ts +9 -0
- package/dist/data/ServerTimingBadge.d.ts.map +1 -0
- package/dist/data/ServerTimingBadge.js +64 -0
- package/dist/data/ServerTimingBadge.js.map +1 -0
- package/dist/data/StatStrip.cjs +99 -0
- package/dist/data/StatStrip.cjs.map +1 -0
- package/dist/data/StatStrip.d.ts +41 -0
- package/dist/data/StatStrip.d.ts.map +1 -0
- package/dist/data/StatStrip.js +99 -0
- package/dist/data/StatStrip.js.map +1 -0
- package/dist/data/TaskManager.cjs +20 -1
- package/dist/data/TaskManager.cjs.map +1 -1
- package/dist/data/TaskManager.d.ts +3 -1
- package/dist/data/TaskManager.d.ts.map +1 -1
- package/dist/data/TaskManager.js +20 -1
- package/dist/data/TaskManager.js.map +1 -1
- package/dist/data/TaskManagerButton.cjs +49 -0
- package/dist/data/TaskManagerButton.cjs.map +1 -0
- package/dist/data/TaskManagerButton.d.ts +8 -0
- package/dist/data/TaskManagerButton.d.ts.map +1 -0
- package/dist/data/TaskManagerButton.js +49 -0
- package/dist/data/TaskManagerButton.js.map +1 -0
- package/dist/data/TaskProcessDetails.cjs +113 -0
- package/dist/data/TaskProcessDetails.cjs.map +1 -0
- package/dist/data/TaskProcessDetails.d.ts +6 -0
- package/dist/data/TaskProcessDetails.d.ts.map +1 -0
- package/dist/data/TaskProcessDetails.js +113 -0
- package/dist/data/TaskProcessDetails.js.map +1 -0
- package/dist/data/TaskProgress.cjs +106 -19
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +4 -2
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +107 -20
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +43 -0
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/Tree.cjs +91 -82
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +3 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +91 -82
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/TreeNode.cjs +3 -0
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts +2 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +3 -0
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +18 -141
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +2 -40
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +15 -138
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.models.cjs +11 -0
- package/dist/data/ai/ChatWindow.models.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.models.d.ts +3 -0
- package/dist/data/ai/ChatWindow.models.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.models.js +11 -0
- package/dist/data/ai/ChatWindow.models.js.map +1 -0
- package/dist/data/ai/ChatWindow.preferences.cjs +57 -0
- package/dist/data/ai/ChatWindow.preferences.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.preferences.d.ts +13 -0
- package/dist/data/ai/ChatWindow.preferences.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.preferences.js +57 -0
- package/dist/data/ai/ChatWindow.preferences.js.map +1 -0
- package/dist/data/ai/ChatWindow.thread-status.cjs +14 -0
- package/dist/data/ai/ChatWindow.thread-status.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.thread-status.d.ts +5 -0
- package/dist/data/ai/ChatWindow.thread-status.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.thread-status.js +14 -0
- package/dist/data/ai/ChatWindow.thread-status.js.map +1 -0
- package/dist/data/ai/ChatWindow.thread.cjs +68 -0
- package/dist/data/ai/ChatWindow.thread.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.thread.d.ts +16 -0
- package/dist/data/ai/ChatWindow.thread.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.thread.js +68 -0
- package/dist/data/ai/ChatWindow.thread.js.map +1 -0
- package/dist/data/ai/ChatWindow.tool-catalog.cjs +99 -0
- package/dist/data/ai/ChatWindow.tool-catalog.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts +3 -0
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.tool-catalog.js +99 -0
- package/dist/data/ai/ChatWindow.tool-catalog.js.map +1 -0
- package/dist/data/ai/ChatWindow.types.d.ts +41 -0
- package/dist/data/ai/ChatWindow.types.d.ts.map +1 -0
- package/dist/data/ai/ContextBadges.cjs +76 -46
- package/dist/data/ai/ContextBadges.cjs.map +1 -1
- package/dist/data/ai/ContextBadges.d.ts.map +1 -1
- package/dist/data/ai/ContextBadges.js +77 -47
- package/dist/data/ai/ContextBadges.js.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.cjs +151 -32
- package/dist/data/ai/PromptPicker/PromptPicker.cjs.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.d.ts +7 -4
- package/dist/data/ai/PromptPicker/PromptPicker.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.js +152 -33
- package/dist/data/ai/PromptPicker/PromptPicker.js.map +1 -1
- package/dist/data/ai/PromptPicker/PromptSourceRepair.cjs +133 -0
- package/dist/data/ai/PromptPicker/PromptSourceRepair.cjs.map +1 -0
- package/dist/data/ai/PromptPicker/PromptSourceRepair.d.ts +11 -0
- package/dist/data/ai/PromptPicker/PromptSourceRepair.d.ts.map +1 -0
- package/dist/data/ai/PromptPicker/PromptSourceRepair.js +133 -0
- package/dist/data/ai/PromptPicker/PromptSourceRepair.js.map +1 -0
- package/dist/data/ai/PromptPicker/index.d.ts +2 -1
- package/dist/data/ai/PromptPicker/index.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/types.cjs +7 -0
- package/dist/data/ai/PromptPicker/types.cjs.map +1 -0
- package/dist/data/ai/PromptPicker/types.d.ts +18 -2
- package/dist/data/ai/PromptPicker/types.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/types.js +7 -0
- package/dist/data/ai/PromptPicker/types.js.map +1 -0
- package/dist/data/ai/PromptRunEditor/index.cjs +171 -91
- package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts +9 -9
- package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.js +175 -95
- package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/model.cjs +47 -0
- package/dist/data/ai/PromptRunEditor/model.cjs.map +1 -0
- package/dist/data/ai/PromptRunEditor/model.d.ts +17 -0
- package/dist/data/ai/PromptRunEditor/model.d.ts.map +1 -0
- package/dist/data/ai/PromptRunEditor/model.js +47 -0
- package/dist/data/ai/PromptRunEditor/model.js.map +1 -0
- package/dist/data/ai/RuntimeBar.cjs +408 -0
- package/dist/data/ai/RuntimeBar.cjs.map +1 -0
- package/dist/data/ai/RuntimeBar.d.ts +20 -0
- package/dist/data/ai/RuntimeBar.d.ts.map +1 -0
- package/dist/data/ai/RuntimeBar.js +408 -0
- package/dist/data/ai/RuntimeBar.js.map +1 -0
- package/dist/data/ai/RuntimeBar.model.cjs +14 -0
- package/dist/data/ai/RuntimeBar.model.cjs.map +1 -0
- package/dist/data/ai/RuntimeBar.model.d.ts +10 -0
- package/dist/data/ai/RuntimeBar.model.d.ts.map +1 -0
- package/dist/data/ai/RuntimeBar.model.js +14 -0
- package/dist/data/ai/RuntimeBar.model.js.map +1 -0
- package/dist/data/ai/RuntimeBarCombo.cjs +359 -0
- package/dist/data/ai/RuntimeBarCombo.cjs.map +1 -0
- package/dist/data/ai/RuntimeBarCombo.d.ts +22 -0
- package/dist/data/ai/RuntimeBarCombo.d.ts.map +1 -0
- package/dist/data/ai/RuntimeBarCombo.js +359 -0
- package/dist/data/ai/RuntimeBarCombo.js.map +1 -0
- package/dist/data/ai/SessionChatComposer.cjs +56 -0
- package/dist/data/ai/SessionChatComposer.cjs.map +1 -0
- package/dist/data/ai/SessionChatComposer.d.ts +24 -0
- package/dist/data/ai/SessionChatComposer.d.ts.map +1 -0
- package/dist/data/ai/SessionChatComposer.js +56 -0
- package/dist/data/ai/SessionChatComposer.js.map +1 -0
- package/dist/data/ai/SessionInspector.cjs +222 -382
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection-types.d.ts +55 -0
- package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.collection.cjs +377 -0
- package/dist/data/ai/SessionInspector.collection.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.collection.d.ts +15 -0
- package/dist/data/ai/SessionInspector.collection.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.collection.js +377 -0
- package/dist/data/ai/SessionInspector.collection.js.map +1 -0
- package/dist/data/ai/SessionInspector.d.ts +9 -4
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.files.cjs +162 -0
- package/dist/data/ai/SessionInspector.files.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.files.d.ts +5 -0
- package/dist/data/ai/SessionInspector.files.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.files.js +162 -0
- package/dist/data/ai/SessionInspector.files.js.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs +148 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts +15 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.js +148 -0
- package/dist/data/ai/SessionInspector.hierarchy-state.js.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy.cjs +256 -0
- package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy.d.ts +9 -0
- package/dist/data/ai/SessionInspector.hierarchy.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.hierarchy.js +256 -0
- package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -0
- package/dist/data/ai/SessionInspector.js +224 -384
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.model.cjs +125 -0
- package/dist/data/ai/SessionInspector.model.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.model.d.ts +14 -0
- package/dist/data/ai/SessionInspector.model.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.model.js +125 -0
- package/dist/data/ai/SessionInspector.model.js.map +1 -0
- package/dist/data/ai/SessionInspector.panels.cjs +265 -0
- package/dist/data/ai/SessionInspector.panels.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.panels.d.ts +10 -0
- package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.panels.js +265 -0
- package/dist/data/ai/SessionInspector.panels.js.map +1 -0
- package/dist/data/ai/SessionInspector.plan.cjs +77 -0
- package/dist/data/ai/SessionInspector.plan.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.plan.d.ts +6 -0
- package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.plan.js +77 -0
- package/dist/data/ai/SessionInspector.plan.js.map +1 -0
- package/dist/data/ai/SessionInspector.summary.cjs +182 -0
- package/dist/data/ai/SessionInspector.summary.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.summary.d.ts +8 -0
- package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.summary.js +182 -0
- package/dist/data/ai/SessionInspector.summary.js.map +1 -0
- package/dist/data/ai/SessionInspector.transcript.cjs +94 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.transcript.d.ts +7 -0
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.transcript.js +94 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -0
- package/dist/data/ai/SessionInspector.turns.d.ts +11 -0
- package/dist/data/ai/SessionInspector.turns.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +86 -121
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +8 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.fixtures.d.ts +2 -0
- package/dist/data/ai/SessionViewer.fixtures.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.header.cjs +118 -0
- package/dist/data/ai/SessionViewer.header.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.header.d.ts +11 -0
- package/dist/data/ai/SessionViewer.header.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.header.js +118 -0
- package/dist/data/ai/SessionViewer.header.js.map +1 -0
- package/dist/data/ai/SessionViewer.js +87 -122
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.model.cjs +111 -39
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +6 -0
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js +111 -39
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.row-metadata.cjs +132 -0
- package/dist/data/ai/SessionViewer.row-metadata.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.row-metadata.d.ts +14 -0
- package/dist/data/ai/SessionViewer.row-metadata.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.row-metadata.js +132 -0
- package/dist/data/ai/SessionViewer.row-metadata.js.map +1 -0
- package/dist/data/ai/SessionViewer.row-time.cjs +15 -0
- package/dist/data/ai/SessionViewer.row-time.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.row-time.d.ts +3 -0
- package/dist/data/ai/SessionViewer.row-time.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.row-time.js +15 -0
- package/dist/data/ai/SessionViewer.row-time.js.map +1 -0
- package/dist/data/ai/SessionViewer.rows.cjs +37 -424
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts +5 -2
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +31 -418
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SessionViewer.tool-details.cjs +65 -0
- package/dist/data/ai/SessionViewer.tool-details.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tool-details.d.ts +20 -0
- package/dist/data/ai/SessionViewer.tool-details.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tool-details.js +65 -0
- package/dist/data/ai/SessionViewer.tool-details.js.map +1 -0
- package/dist/data/ai/SessionViewer.tool-row.cjs +404 -0
- package/dist/data/ai/SessionViewer.tool-row.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tool-row.d.ts +12 -0
- package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tool-row.js +404 -0
- package/dist/data/ai/SessionViewer.tool-row.js.map +1 -0
- package/dist/data/ai/SessionViewer.unified.d.ts +11 -2
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs +44 -26
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js +47 -29
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs +45 -153
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js +51 -159
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +0 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +0 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.cjs +0 -5
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.js +0 -5
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/fields.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.cjs +19 -6
- package/dist/data/ai/SpecRuntimeEditor/update.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts +5 -2
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.js +19 -6
- package/dist/data/ai/SpecRuntimeEditor/update.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.cjs +67 -10
- package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts +31 -4
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.js +67 -10
- package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
- package/dist/data/ai/ThreadPicker.cjs.map +1 -1
- package/dist/data/ai/ThreadPicker.d.ts +2 -0
- package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
- package/dist/data/ai/ThreadPicker.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +2 -1
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +2 -1
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/agent-action-icons.cjs +7 -10
- package/dist/data/ai/agent-action-icons.cjs.map +1 -1
- package/dist/data/ai/agent-action-icons.d.ts +1 -2
- package/dist/data/ai/agent-action-icons.d.ts.map +1 -1
- package/dist/data/ai/agent-action-icons.js +8 -11
- package/dist/data/ai/agent-action-icons.js.map +1 -1
- package/dist/data/ai/context.cjs.map +1 -1
- package/dist/data/ai/context.d.ts +4 -0
- package/dist/data/ai/context.d.ts.map +1 -1
- package/dist/data/ai/context.js.map +1 -1
- package/dist/data/ai/examples/sessions/claude-complete.cjs +513 -0
- package/dist/data/ai/examples/sessions/claude-complete.cjs.map +1 -0
- package/dist/data/ai/examples/sessions/claude-complete.d.ts +3 -0
- package/dist/data/ai/examples/sessions/claude-complete.d.ts.map +1 -0
- package/dist/data/ai/examples/sessions/claude-complete.js +513 -0
- package/dist/data/ai/examples/sessions/claude-complete.js.map +1 -0
- package/dist/data/ai/examples/sessions/claude.cjs +252 -0
- package/dist/data/ai/examples/sessions/claude.cjs.map +1 -0
- package/dist/data/ai/examples/sessions/claude.d.ts +3 -0
- package/dist/data/ai/examples/sessions/claude.d.ts.map +1 -0
- package/dist/data/ai/examples/sessions/claude.js +252 -0
- package/dist/data/ai/examples/sessions/claude.js.map +1 -0
- package/dist/data/ai/examples/sessions/codex-complete.cjs +394 -0
- package/dist/data/ai/examples/sessions/codex-complete.cjs.map +1 -0
- package/dist/data/ai/examples/sessions/codex-complete.d.ts +3 -0
- package/dist/data/ai/examples/sessions/codex-complete.d.ts.map +1 -0
- package/dist/data/ai/examples/sessions/codex-complete.js +394 -0
- package/dist/data/ai/examples/sessions/codex-complete.js.map +1 -0
- package/dist/data/ai/examples/sessions/codex.cjs +236 -0
- package/dist/data/ai/examples/sessions/codex.cjs.map +1 -0
- package/dist/data/ai/examples/sessions/codex.d.ts +3 -0
- package/dist/data/ai/examples/sessions/codex.d.ts.map +1 -0
- package/dist/data/ai/examples/sessions/codex.js +236 -0
- package/dist/data/ai/examples/sessions/codex.js.map +1 -0
- package/dist/data/ai/examples/sessions/index.cjs +21 -0
- package/dist/data/ai/examples/sessions/index.cjs.map +1 -0
- package/dist/data/ai/examples/sessions/index.d.ts +10 -0
- package/dist/data/ai/examples/sessions/index.d.ts.map +1 -0
- package/dist/data/ai/examples/sessions/index.js +21 -0
- package/dist/data/ai/examples/sessions/index.js.map +1 -0
- package/dist/data/ai/index.d.ts +9 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/model-capabilities.cjs +12 -1
- package/dist/data/ai/model-capabilities.cjs.map +1 -1
- package/dist/data/ai/model-capabilities.d.ts +2 -6
- package/dist/data/ai/model-capabilities.d.ts.map +1 -1
- package/dist/data/ai/model-capabilities.js +12 -1
- package/dist/data/ai/model-capabilities.js.map +1 -1
- package/dist/data/ai/runtime-mode.cjs +72 -1
- package/dist/data/ai/runtime-mode.cjs.map +1 -1
- package/dist/data/ai/runtime-mode.d.ts +28 -0
- package/dist/data/ai/runtime-mode.d.ts.map +1 -1
- package/dist/data/ai/runtime-mode.js +73 -2
- package/dist/data/ai/runtime-mode.js.map +1 -1
- package/dist/data/cells/EntityCell.cjs +64 -0
- package/dist/data/cells/EntityCell.cjs.map +1 -0
- package/dist/data/cells/EntityCell.d.ts +27 -0
- package/dist/data/cells/EntityCell.d.ts.map +1 -0
- package/dist/data/cells/EntityCell.js +64 -0
- package/dist/data/cells/EntityCell.js.map +1 -0
- package/dist/data/chat/Attachment.cjs +53 -13
- package/dist/data/chat/Attachment.cjs.map +1 -1
- package/dist/data/chat/Attachment.d.ts +9 -3
- package/dist/data/chat/Attachment.d.ts.map +1 -1
- package/dist/data/chat/Attachment.js +54 -14
- package/dist/data/chat/Attachment.js.map +1 -1
- package/dist/data/chat/Chat.cjs +113 -36
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +11 -4
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.js +111 -34
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ContextMeter.cjs +240 -66
- package/dist/data/chat/ContextMeter.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.d.ts +11 -3
- package/dist/data/chat/ContextMeter.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.js +241 -67
- package/dist/data/chat/ContextMeter.js.map +1 -1
- package/dist/data/chat/Conversation.cjs +55 -3
- package/dist/data/chat/Conversation.cjs.map +1 -1
- package/dist/data/chat/Conversation.d.ts +5 -1
- package/dist/data/chat/Conversation.d.ts.map +1 -1
- package/dist/data/chat/Conversation.js +55 -3
- package/dist/data/chat/Conversation.js.map +1 -1
- package/dist/data/chat/ModelSelector.cjs +8 -10
- package/dist/data/chat/ModelSelector.cjs.map +1 -1
- package/dist/data/chat/ModelSelector.d.ts.map +1 -1
- package/dist/data/chat/ModelSelector.js +9 -11
- package/dist/data/chat/ModelSelector.js.map +1 -1
- package/dist/data/chat/PromptInput.cjs +56 -5
- package/dist/data/chat/PromptInput.cjs.map +1 -1
- package/dist/data/chat/PromptInput.d.ts +10 -1
- package/dist/data/chat/PromptInput.d.ts.map +1 -1
- package/dist/data/chat/PromptInput.js +57 -6
- package/dist/data/chat/PromptInput.js.map +1 -1
- package/dist/data/chat/approval.cjs +21 -0
- package/dist/data/chat/approval.cjs.map +1 -0
- package/dist/data/chat/approval.d.ts +11 -0
- package/dist/data/chat/approval.d.ts.map +1 -0
- package/dist/data/chat/approval.js +21 -0
- package/dist/data/chat/approval.js.map +1 -0
- package/dist/data/chat/attachment-upload.cjs +33 -0
- package/dist/data/chat/attachment-upload.cjs.map +1 -0
- package/dist/data/chat/attachment-upload.d.ts +21 -0
- package/dist/data/chat/attachment-upload.d.ts.map +1 -0
- package/dist/data/chat/attachment-upload.js +33 -0
- package/dist/data/chat/attachment-upload.js.map +1 -0
- package/dist/data/chat/effort-icons.cjs +36 -6
- package/dist/data/chat/effort-icons.cjs.map +1 -1
- package/dist/data/chat/effort-icons.d.ts +6 -3
- package/dist/data/chat/effort-icons.d.ts.map +1 -1
- package/dist/data/chat/effort-icons.js +37 -7
- package/dist/data/chat/effort-icons.js.map +1 -1
- package/dist/data/chat/index.d.ts +3 -1
- package/dist/data/chat/index.d.ts.map +1 -1
- package/dist/data/chat/models.cjs +8 -0
- package/dist/data/chat/models.cjs.map +1 -0
- package/dist/data/chat/models.d.ts +11 -0
- package/dist/data/chat/models.d.ts.map +1 -0
- package/dist/data/chat/models.js +8 -0
- package/dist/data/chat/models.js.map +1 -0
- package/dist/data/chat/provider-icons.cjs +49 -16
- package/dist/data/chat/provider-icons.cjs.map +1 -1
- package/dist/data/chat/provider-icons.d.ts +2 -0
- package/dist/data/chat/provider-icons.d.ts.map +1 -1
- package/dist/data/chat/provider-icons.js +50 -17
- package/dist/data/chat/provider-icons.js.map +1 -1
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +21 -0
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/examples/markdown-preview-mock.cjs +45 -0
- package/dist/data/examples/markdown-preview-mock.cjs.map +1 -0
- package/dist/data/examples/markdown-preview-mock.d.ts +23 -0
- package/dist/data/examples/markdown-preview-mock.d.ts.map +1 -0
- package/dist/data/examples/markdown-preview-mock.js +45 -0
- package/dist/data/examples/markdown-preview-mock.js.map +1 -0
- package/dist/data/examples/markdown-syntax.cjs +36 -0
- package/dist/data/examples/markdown-syntax.cjs.map +1 -0
- package/dist/data/examples/markdown-syntax.d.ts +12 -0
- package/dist/data/examples/markdown-syntax.d.ts.map +1 -0
- package/dist/data/examples/markdown-syntax.js +36 -0
- package/dist/data/examples/markdown-syntax.js.map +1 -0
- package/dist/data/examples/markdown-syntax.md.cjs +4 -0
- package/dist/data/examples/markdown-syntax.md.cjs.map +1 -0
- package/dist/data/examples/markdown-syntax.md.js +5 -0
- package/dist/data/examples/markdown-syntax.md.js.map +1 -0
- package/dist/data/server-timing.cjs +120 -0
- package/dist/data/server-timing.cjs.map +1 -0
- package/dist/data/server-timing.d.ts +11 -0
- package/dist/data/server-timing.d.ts.map +1 -0
- package/dist/data/server-timing.js +120 -0
- package/dist/data/server-timing.js.map +1 -0
- package/dist/data/task-process-details.cjs +48 -0
- package/dist/data/task-process-details.cjs.map +1 -0
- package/dist/data/task-process-details.d.ts +5 -0
- package/dist/data/task-process-details.d.ts.map +1 -0
- package/dist/data/task-process-details.js +48 -0
- package/dist/data/task-process-details.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +37 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +9 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +37 -0
- package/dist/data.js.map +1 -1
- package/dist/hooks/use-hotkey.cjs +98 -0
- package/dist/hooks/use-hotkey.cjs.map +1 -0
- package/dist/hooks/use-hotkey.d.ts +42 -0
- package/dist/hooks/use-hotkey.d.ts.map +1 -0
- package/dist/hooks/use-hotkey.js +98 -0
- package/dist/hooks/use-hotkey.js.map +1 -0
- package/dist/hooks/use-task-run.cjs +23 -1
- package/dist/hooks/use-task-run.cjs.map +1 -1
- package/dist/hooks/use-task-run.d.ts.map +1 -1
- package/dist/hooks/use-task-run.js +23 -1
- package/dist/hooks/use-task-run.js.map +1 -1
- package/dist/hooks.cjs +4 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/icons/components/UiBank.cjs +15 -0
- package/dist/icons/components/UiBank.cjs.map +1 -0
- package/dist/icons/components/UiBank.d.ts +15 -0
- package/dist/icons/components/UiBank.d.ts.map +1 -0
- package/dist/icons/components/UiBank.js +15 -0
- package/dist/icons/components/UiBank.js.map +1 -0
- package/dist/icons/components/UiChartOfAccounts.cjs +15 -0
- package/dist/icons/components/UiChartOfAccounts.cjs.map +1 -0
- package/dist/icons/components/UiChartOfAccounts.d.ts +15 -0
- package/dist/icons/components/UiChartOfAccounts.d.ts.map +1 -0
- package/dist/icons/components/UiChartOfAccounts.js +15 -0
- package/dist/icons/components/UiChartOfAccounts.js.map +1 -0
- package/dist/icons/components/UiCloudUpload.cjs +15 -0
- package/dist/icons/components/UiCloudUpload.cjs.map +1 -0
- package/dist/icons/components/UiCloudUpload.d.ts +15 -0
- package/dist/icons/components/UiCloudUpload.d.ts.map +1 -0
- package/dist/icons/components/UiCloudUpload.js +15 -0
- package/dist/icons/components/UiCloudUpload.js.map +1 -0
- package/dist/icons/components/UiLedger.cjs +15 -0
- package/dist/icons/components/UiLedger.cjs.map +1 -0
- package/dist/icons/components/UiLedger.d.ts +15 -0
- package/dist/icons/components/UiLedger.d.ts.map +1 -0
- package/dist/icons/components/UiLedger.js +15 -0
- package/dist/icons/components/UiLedger.js.map +1 -0
- package/dist/icons/components/UiReceipt.cjs +15 -0
- package/dist/icons/components/UiReceipt.cjs.map +1 -0
- package/dist/icons/components/UiReceipt.d.ts +15 -0
- package/dist/icons/components/UiReceipt.d.ts.map +1 -0
- package/dist/icons/components/UiReceipt.js +15 -0
- package/dist/icons/components/UiReceipt.js.map +1 -0
- package/dist/icons/index.d.ts +10 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons.cjs +15 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +15 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +54 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +56 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +270 -238
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +9 -0
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.debug.cjs +53 -0
- package/dist/layout/AppShell.debug.cjs.map +1 -0
- package/dist/layout/AppShell.debug.d.ts +6 -0
- package/dist/layout/AppShell.debug.d.ts.map +1 -0
- package/dist/layout/AppShell.debug.js +53 -0
- package/dist/layout/AppShell.debug.js.map +1 -0
- package/dist/layout/AppShell.js +269 -237
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/layout/AppShell.nav.cjs +90 -0
- package/dist/layout/AppShell.nav.cjs.map +1 -0
- package/dist/layout/AppShell.nav.d.ts +7 -0
- package/dist/layout/AppShell.nav.d.ts.map +1 -0
- package/dist/layout/AppShell.nav.js +90 -0
- package/dist/layout/AppShell.nav.js.map +1 -0
- package/dist/layout/AppSidebar.cjs +35 -5
- package/dist/layout/AppSidebar.cjs.map +1 -1
- package/dist/layout/AppSidebar.d.ts +4 -1
- package/dist/layout/AppSidebar.d.ts.map +1 -1
- package/dist/layout/AppSidebar.js +35 -5
- package/dist/layout/AppSidebar.js.map +1 -1
- package/dist/layout/Panel.cjs +25 -41
- package/dist/layout/Panel.cjs.map +1 -1
- package/dist/layout/Panel.d.ts +2 -1
- package/dist/layout/Panel.d.ts.map +1 -1
- package/dist/layout/Panel.js +26 -42
- package/dist/layout/Panel.js.map +1 -1
- package/dist/layout/PanelFrame.cjs +56 -0
- package/dist/layout/PanelFrame.cjs.map +1 -0
- package/dist/layout/PanelFrame.d.ts +15 -0
- package/dist/layout/PanelFrame.d.ts.map +1 -0
- package/dist/layout/PanelFrame.js +56 -0
- package/dist/layout/PanelFrame.js.map +1 -0
- package/dist/layout/Section.cjs +51 -41
- package/dist/layout/Section.cjs.map +1 -1
- package/dist/layout/Section.d.ts +3 -2
- package/dist/layout/Section.d.ts.map +1 -1
- package/dist/layout/Section.js +51 -41
- package/dist/layout/Section.js.map +1 -1
- package/dist/layout/content-width.cjs +8 -0
- package/dist/layout/content-width.cjs.map +1 -0
- package/dist/layout/content-width.d.ts +3 -0
- package/dist/layout/content-width.d.ts.map +1 -0
- package/dist/layout/content-width.js +8 -0
- package/dist/layout/content-width.js.map +1 -0
- package/dist/overlay/CommandPalette.cjs +207 -0
- package/dist/overlay/CommandPalette.cjs.map +1 -0
- package/dist/overlay/CommandPalette.d.ts +71 -0
- package/dist/overlay/CommandPalette.d.ts.map +1 -0
- package/dist/overlay/CommandPalette.js +207 -0
- package/dist/overlay/CommandPalette.js.map +1 -0
- package/dist/overlay/CommandPalette.model.cjs +70 -0
- package/dist/overlay/CommandPalette.model.cjs.map +1 -0
- package/dist/overlay/CommandPalette.model.d.ts +71 -0
- package/dist/overlay/CommandPalette.model.d.ts.map +1 -0
- package/dist/overlay/CommandPalette.model.js +70 -0
- package/dist/overlay/CommandPalette.model.js.map +1 -0
- package/dist/overlay/CommandPaletteList.cjs +88 -0
- package/dist/overlay/CommandPaletteList.cjs.map +1 -0
- package/dist/overlay/CommandPaletteList.d.ts +23 -0
- package/dist/overlay/CommandPaletteList.d.ts.map +1 -0
- package/dist/overlay/CommandPaletteList.js +88 -0
- package/dist/overlay/CommandPaletteList.js.map +1 -0
- package/dist/overlay/CommandPaletteTrigger.cjs +36 -0
- package/dist/overlay/CommandPaletteTrigger.cjs.map +1 -0
- package/dist/overlay/CommandPaletteTrigger.d.ts +22 -0
- package/dist/overlay/CommandPaletteTrigger.d.ts.map +1 -0
- package/dist/overlay/CommandPaletteTrigger.js +36 -0
- package/dist/overlay/CommandPaletteTrigger.js.map +1 -0
- package/dist/overlay/HoverCard.cjs.map +1 -1
- package/dist/overlay/HoverCard.d.ts +2 -2
- package/dist/overlay/HoverCard.d.ts.map +1 -1
- package/dist/overlay/HoverCard.js.map +1 -1
- package/dist/overlay/Modal.cjs +12 -5
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +12 -5
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/modalStack.js +1 -1
- package/dist/overlay/zIndex.cjs +2 -0
- package/dist/overlay/zIndex.cjs.map +1 -1
- package/dist/overlay/zIndex.js +2 -0
- package/dist/overlay/zIndex.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +6 -0
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +6 -0
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +45 -71
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +12 -2
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +46 -72
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationResultView.cjs +42 -0
- package/dist/rpc/OperationResultView.cjs.map +1 -1
- package/dist/rpc/OperationResultView.d.ts +2 -1
- package/dist/rpc/OperationResultView.d.ts.map +1 -1
- package/dist/rpc/OperationResultView.js +42 -0
- package/dist/rpc/OperationResultView.js.map +1 -1
- package/dist/rpc/clickyMetadata.cjs +2 -1
- package/dist/rpc/clickyMetadata.cjs.map +1 -1
- package/dist/rpc/clickyMetadata.d.ts.map +1 -1
- package/dist/rpc/clickyMetadata.js +2 -1
- package/dist/rpc/clickyMetadata.js.map +1 -1
- package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -1
- package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -1
- package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +25 -2
- package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -1
- package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -1
- package/dist/rpc/rpc-story.fixtures.d.ts +2 -1
- package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +1 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +15 -0
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.d.ts.map +1 -1
- package/dist/tailwind-preset.js +15 -0
- package/dist/tailwind-preset.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Icon } from "../data/Icon.js";
|
|
5
|
+
function CommandPaletteList({
|
|
6
|
+
groups,
|
|
7
|
+
items,
|
|
8
|
+
activeIndex,
|
|
9
|
+
listId,
|
|
10
|
+
optionId,
|
|
11
|
+
onActivate,
|
|
12
|
+
onHover,
|
|
13
|
+
listRef,
|
|
14
|
+
loading,
|
|
15
|
+
emptyState,
|
|
16
|
+
listMaxHeight
|
|
17
|
+
}) {
|
|
18
|
+
let flatIndex = -1;
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
ref: listRef,
|
|
23
|
+
id: listId,
|
|
24
|
+
role: "listbox",
|
|
25
|
+
"aria-label": "Commands",
|
|
26
|
+
className: "overflow-y-auto overscroll-contain py-density-1",
|
|
27
|
+
style: { maxHeight: listMaxHeight },
|
|
28
|
+
children: loading ? /* @__PURE__ */ jsx("div", { className: "px-density-3 py-density-3 text-sm text-muted-foreground", children: "Searching…" }) : items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-density-3 py-density-4 text-center text-sm text-muted-foreground", children: emptyState ?? "No results" }) : groups.map((group) => {
|
|
29
|
+
const headingId = `${listId}-group-${group.id}`;
|
|
30
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": group.heading ? headingId : void 0, children: [
|
|
31
|
+
group.heading && /* @__PURE__ */ jsx(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
id: headingId,
|
|
35
|
+
role: "presentation",
|
|
36
|
+
className: "px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground",
|
|
37
|
+
children: group.heading
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
group.items.map((item) => {
|
|
41
|
+
flatIndex += 1;
|
|
42
|
+
const index = flatIndex;
|
|
43
|
+
const active = index === activeIndex;
|
|
44
|
+
return /* @__PURE__ */ jsxs(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
id: optionId(item),
|
|
48
|
+
role: "option",
|
|
49
|
+
"aria-selected": active,
|
|
50
|
+
"aria-disabled": item.disabled || void 0,
|
|
51
|
+
onMouseMove: () => {
|
|
52
|
+
if (!item.disabled) onHover(index);
|
|
53
|
+
},
|
|
54
|
+
onClick: () => {
|
|
55
|
+
if (!item.disabled) onActivate(item);
|
|
56
|
+
},
|
|
57
|
+
className: cn(
|
|
58
|
+
"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm",
|
|
59
|
+
active && "bg-accent text-accent-foreground",
|
|
60
|
+
item.disabled && "cursor-not-allowed opacity-50"
|
|
61
|
+
),
|
|
62
|
+
children: [
|
|
63
|
+
item.icon !== void 0 && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(
|
|
64
|
+
Icon,
|
|
65
|
+
{
|
|
66
|
+
...typeof item.icon === "string" ? { name: item.icon } : { icon: item.icon }
|
|
67
|
+
}
|
|
68
|
+
) }),
|
|
69
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
70
|
+
item.label,
|
|
71
|
+
item.description && /* @__PURE__ */ jsx("span", { className: "ml-density-2 text-xs text-muted-foreground", children: item.description })
|
|
72
|
+
] }),
|
|
73
|
+
item.trailing,
|
|
74
|
+
item.shortcut && /* @__PURE__ */ jsx("kbd", { className: "shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
item.id
|
|
78
|
+
);
|
|
79
|
+
})
|
|
80
|
+
] }) }, group.id);
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
CommandPaletteList
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=CommandPaletteList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPaletteList.js","sources":["../../src/overlay/CommandPaletteList.tsx"],"sourcesContent":["import { Fragment, type RefObject } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport type { CommandGroup, CommandItem } from \"./CommandPalette.model\";\n\nexport type CommandPaletteListProps = {\n groups: CommandGroup[];\n /** Flattened rows, in render order — index space for `activeIndex`. */\n items: CommandItem[];\n activeIndex: number;\n listId: string;\n optionId: (item: CommandItem) => string;\n onActivate: (item: CommandItem) => void;\n onHover: (index: number) => void;\n listRef: RefObject<HTMLDivElement>;\n loading?: boolean | undefined;\n emptyState?: React.ReactNode;\n listMaxHeight: string | number;\n};\n\n/**\n * The palette's grouped listbox. Headings are `role=\"presentation\"` so the\n * option index space stays contiguous — the same trick Combobox uses to scroll\n * by `[role=\"option\"]` index.\n */\nexport function CommandPaletteList({\n groups,\n items,\n activeIndex,\n listId,\n optionId,\n onActivate,\n onHover,\n listRef,\n loading,\n emptyState,\n listMaxHeight,\n}: CommandPaletteListProps) {\n // A flat cursor walked alongside the nested render so each row knows its index\n // in the flattened list without a lookup.\n let flatIndex = -1;\n\n return (\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label=\"Commands\"\n className=\"overflow-y-auto overscroll-contain py-density-1\"\n style={{ maxHeight: listMaxHeight }}\n >\n {loading ? (\n <div className=\"px-density-3 py-density-3 text-sm text-muted-foreground\">Searching…</div>\n ) : items.length === 0 ? (\n <div className=\"px-density-3 py-density-4 text-center text-sm text-muted-foreground\">\n {emptyState ?? \"No results\"}\n </div>\n ) : (\n groups.map((group) => {\n const headingId = `${listId}-group-${group.id}`;\n return (\n <Fragment key={group.id}>\n <div role=\"group\" aria-labelledby={group.heading ? headingId : undefined}>\n {group.heading && (\n <div\n id={headingId}\n role=\"presentation\"\n className=\"px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground\"\n >\n {group.heading}\n </div>\n )}\n {group.items.map((item) => {\n flatIndex += 1;\n const index = flatIndex;\n const active = index === activeIndex;\n return (\n <div\n key={item.id}\n id={optionId(item)}\n role=\"option\"\n aria-selected={active}\n aria-disabled={item.disabled || undefined}\n // onMouseMove, not onMouseEnter: keyboard navigation\n // scrolls rows under a stationary cursor, and mouseenter\n // would yank the highlight back to wherever it sits.\n onMouseMove={() => {\n if (!item.disabled) onHover(index);\n }}\n onClick={() => {\n if (!item.disabled) onActivate(item);\n }}\n className={cn(\n \"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm\",\n active && \"bg-accent text-accent-foreground\",\n item.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {item.icon !== undefined && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground\">\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {item.label}\n {item.description && (\n <span className=\"ml-density-2 text-xs text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </div>\n );\n })}\n </div>\n </Fragment>\n );\n })\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAyBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAG1B,MAAI,YAAY;AAEhB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,cAAA;AAAA,MAEnB,UAAA,8BACE,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAAA,CAAU,IACjF,MAAM,WAAW,wBAClB,OAAA,EAAI,WAAU,uEACZ,UAAA,cAAc,aAAA,CACjB,IAEA,OAAO,IAAI,CAAC,UAAU;AACpB,cAAM,YAAY,GAAG,MAAM,UAAU,MAAM,EAAE;AAC7C,eACE,oBAAC,UAAA,EACC,UAAA,qBAAC,OAAA,EAAI,MAAK,SAAQ,mBAAiB,MAAM,UAAU,YAAY,QAC5D,UAAA;AAAA,UAAA,MAAM,WACL;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,WAAU;AAAA,cAET,UAAA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGV,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,yBAAa;AACb,kBAAM,QAAQ;AACd,kBAAM,SAAS,UAAU;AACzB,mBACE;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,IAAI,SAAS,IAAI;AAAA,gBACjB,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,iBAAe,KAAK,YAAY;AAAA,gBAIhC,aAAa,MAAM;AACjB,sBAAI,CAAC,KAAK,SAAU,SAAQ,KAAK;AAAA,gBACnC;AAAA,gBACA,SAAS,MAAM;AACb,sBAAI,CAAC,KAAK,SAAU,YAAW,IAAI;AAAA,gBACrC;AAAA,gBACA,WAAW;AAAA,kBACT;AAAA,kBACA,UAAU;AAAA,kBACV,KAAK,YAAY;AAAA,gBAAA;AAAA,gBAGlB,UAAA;AAAA,kBAAA,KAAK,SAAS,UACb,oBAAC,QAAA,EAAK,WAAU,2EACd,UAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACE,GAAI,OAAO,KAAK,SAAS,WACtB,EAAE,MAAM,KAAK,KAAA,IACb,EAAE,MAAM,KAAK,KAAA;AAAA,oBAAK;AAAA,kBAAA,GAE1B;AAAA,kBAEF,qBAAC,QAAA,EAAK,WAAU,2BACb,UAAA;AAAA,oBAAA,KAAK;AAAA,oBACL,KAAK,eACJ,oBAAC,UAAK,WAAU,8CACb,eAAK,YAAA,CACR;AAAA,kBAAA,GAEJ;AAAA,kBACC,KAAK;AAAA,kBACL,KAAK,YACJ,oBAAC,SAAI,WAAU,4GACZ,eAAK,SAAA,CACR;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzCG,KAAK;AAAA,YAAA;AAAA,UA6ChB,CAAC;AAAA,QAAA,GACH,EAAA,GA/Da,MAAM,EAgErB;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,EAAA;AAIT;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const utils = require("../lib/utils.cjs");
|
|
5
|
+
const Icon = require("../data/Icon.cjs");
|
|
6
|
+
const useHotkey = require("../hooks/use-hotkey.cjs");
|
|
7
|
+
const UiSearch = require("../icons/components/UiSearch.cjs");
|
|
8
|
+
function CommandPaletteTrigger({
|
|
9
|
+
onClick,
|
|
10
|
+
open,
|
|
11
|
+
label = "Search…",
|
|
12
|
+
hotkey = "mod+k",
|
|
13
|
+
className
|
|
14
|
+
}) {
|
|
15
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16
|
+
"button",
|
|
17
|
+
{
|
|
18
|
+
type: "button",
|
|
19
|
+
onClick,
|
|
20
|
+
"aria-haspopup": "dialog",
|
|
21
|
+
...open !== void 0 ? { "aria-expanded": open } : {},
|
|
22
|
+
className: utils.cn(
|
|
23
|
+
"flex h-control-h w-full items-center gap-density-2 rounded-md border border-border bg-secondary px-density-3 text-sm text-muted-foreground",
|
|
24
|
+
"transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
25
|
+
className
|
|
26
|
+
),
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSearch.UiSearch, className: "shrink-0" }),
|
|
29
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: label }),
|
|
30
|
+
hotkey && /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px]", children: useHotkey.formatHotkey(hotkey) })
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
exports.CommandPaletteTrigger = CommandPaletteTrigger;
|
|
36
|
+
//# sourceMappingURL=CommandPaletteTrigger.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPaletteTrigger.cjs","sources":["../../src/overlay/CommandPaletteTrigger.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { formatHotkey } from \"../hooks/use-hotkey\";\n\nexport type CommandPaletteTriggerProps = {\n /** Opens the palette. */\n onClick: () => void;\n /** Whether the palette it controls is open; drives `aria-expanded`. */\n open?: boolean;\n /** Placeholder-style label. Defaults to \"Search…\". */\n label?: string;\n /** Hotkey shown in the trailing `<kbd>`, in `useHotkey` syntax. Defaults to \"mod+k\". */\n hotkey?: string | null;\n className?: string;\n};\n\n/**\n * Search-field-shaped button that opens a {@link CommandPalette}, sized for\n * `AppShell`'s `search` slot.\n *\n * Deliberately a button rather than a `SearchInput`: a real `<input\n * type=\"search\">` that only opens a second search field announces itself to\n * screen readers as a searchbox that does not search, and typing into it does\n * nothing.\n */\nexport function CommandPaletteTrigger({\n onClick,\n open,\n label = \"Search…\",\n hotkey = \"mod+k\",\n className,\n}: CommandPaletteTriggerProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-haspopup=\"dialog\"\n {...(open !== undefined ? { \"aria-expanded\": open } : {})}\n className={cn(\n \"flex h-control-h w-full items-center gap-density-2 rounded-md border border-border bg-secondary px-density-3 text-sm text-muted-foreground\",\n \"transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n className,\n )}\n >\n <Icon icon={UiSearch} className=\"shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{label}</span>\n {hotkey && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px]\">\n {formatHotkey(hotkey)}\n </kbd>\n )}\n </button>\n );\n}\n"],"names":["jsxs","cn","jsx","Icon","UiSearch","formatHotkey"],"mappings":";;;;;;;AA0BO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AACF,GAA+B;AAC7B,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,iBAAc;AAAA,MACb,GAAI,SAAS,SAAY,EAAE,iBAAiB,KAAA,IAAS,CAAA;AAAA,MACtD,WAAWC,MAAAA;AAAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAAC,2BAAAA,IAACC,KAAAA,MAAA,EAAK,MAAMC,SAAAA,UAAU,WAAU,YAAW;AAAA,QAC3CF,2BAAAA,IAAC,QAAA,EAAK,WAAU,qCAAqC,UAAA,OAAM;AAAA,QAC1D,UACCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sFACZ,UAAAG,uBAAa,MAAM,EAAA,CACtB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type CommandPaletteTriggerProps = {
|
|
2
|
+
/** Opens the palette. */
|
|
3
|
+
onClick: () => void;
|
|
4
|
+
/** Whether the palette it controls is open; drives `aria-expanded`. */
|
|
5
|
+
open?: boolean;
|
|
6
|
+
/** Placeholder-style label. Defaults to "Search…". */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Hotkey shown in the trailing `<kbd>`, in `useHotkey` syntax. Defaults to "mod+k". */
|
|
9
|
+
hotkey?: string | null;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Search-field-shaped button that opens a {@link CommandPalette}, sized for
|
|
14
|
+
* `AppShell`'s `search` slot.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately a button rather than a `SearchInput`: a real `<input
|
|
17
|
+
* type="search">` that only opens a second search field announces itself to
|
|
18
|
+
* screen readers as a searchbox that does not search, and typing into it does
|
|
19
|
+
* nothing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function CommandPaletteTrigger({ onClick, open, label, hotkey, className, }: CommandPaletteTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=CommandPaletteTrigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPaletteTrigger.d.ts","sourceRoot":"","sources":["../../src/overlay/CommandPaletteTrigger.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,0BAA0B,GAAG;IACvC,yBAAyB;IACzB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,IAAI,EACJ,KAAiB,EACjB,MAAgB,EAChB,SAAS,GACV,EAAE,0BAA0B,2CAsB5B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Icon } from "../data/Icon.js";
|
|
4
|
+
import { formatHotkey } from "../hooks/use-hotkey.js";
|
|
5
|
+
import { UiSearch } from "../icons/components/UiSearch.js";
|
|
6
|
+
function CommandPaletteTrigger({
|
|
7
|
+
onClick,
|
|
8
|
+
open,
|
|
9
|
+
label = "Search…",
|
|
10
|
+
hotkey = "mod+k",
|
|
11
|
+
className
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
"button",
|
|
15
|
+
{
|
|
16
|
+
type: "button",
|
|
17
|
+
onClick,
|
|
18
|
+
"aria-haspopup": "dialog",
|
|
19
|
+
...open !== void 0 ? { "aria-expanded": open } : {},
|
|
20
|
+
className: cn(
|
|
21
|
+
"flex h-control-h w-full items-center gap-density-2 rounded-md border border-border bg-secondary px-density-3 text-sm text-muted-foreground",
|
|
22
|
+
"transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiSearch, className: "shrink-0" }),
|
|
27
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: label }),
|
|
28
|
+
hotkey && /* @__PURE__ */ jsx("kbd", { className: "shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px]", children: formatHotkey(hotkey) })
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
CommandPaletteTrigger
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=CommandPaletteTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPaletteTrigger.js","sources":["../../src/overlay/CommandPaletteTrigger.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { formatHotkey } from \"../hooks/use-hotkey\";\n\nexport type CommandPaletteTriggerProps = {\n /** Opens the palette. */\n onClick: () => void;\n /** Whether the palette it controls is open; drives `aria-expanded`. */\n open?: boolean;\n /** Placeholder-style label. Defaults to \"Search…\". */\n label?: string;\n /** Hotkey shown in the trailing `<kbd>`, in `useHotkey` syntax. Defaults to \"mod+k\". */\n hotkey?: string | null;\n className?: string;\n};\n\n/**\n * Search-field-shaped button that opens a {@link CommandPalette}, sized for\n * `AppShell`'s `search` slot.\n *\n * Deliberately a button rather than a `SearchInput`: a real `<input\n * type=\"search\">` that only opens a second search field announces itself to\n * screen readers as a searchbox that does not search, and typing into it does\n * nothing.\n */\nexport function CommandPaletteTrigger({\n onClick,\n open,\n label = \"Search…\",\n hotkey = \"mod+k\",\n className,\n}: CommandPaletteTriggerProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-haspopup=\"dialog\"\n {...(open !== undefined ? { \"aria-expanded\": open } : {})}\n className={cn(\n \"flex h-control-h w-full items-center gap-density-2 rounded-md border border-border bg-secondary px-density-3 text-sm text-muted-foreground\",\n \"transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n className,\n )}\n >\n <Icon icon={UiSearch} className=\"shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{label}</span>\n {hotkey && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px]\">\n {formatHotkey(hotkey)}\n </kbd>\n )}\n </button>\n );\n}\n"],"names":[],"mappings":";;;;;AA0BO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AACF,GAA+B;AAC7B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,iBAAc;AAAA,MACb,GAAI,SAAS,SAAY,EAAE,iBAAiB,KAAA,IAAS,CAAA;AAAA,MACtD,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAK,MAAM,UAAU,WAAU,YAAW;AAAA,QAC3C,oBAAC,QAAA,EAAK,WAAU,qCAAqC,UAAA,OAAM;AAAA,QAC1D,UACC,oBAAC,OAAA,EAAI,WAAU,sFACZ,UAAA,aAAa,MAAM,EAAA,CACtB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCard.cjs","sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"./modalStack\";\n\nexport type HoverCardPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport type HoverCardProps = {\n /** Trigger content that opens the card on hover/focus. */\n trigger: ReactNode;\n /** Floating card content. */\n children: ReactNode;\n /** Preferred placement around the trigger. */\n placement?: HoverCardPlacement;\n /** Open delay in milliseconds. */\n delay?: number;\n /** Show the directional arrow. */\n arrow?: boolean;\n /** Classes applied to the trigger wrapper. */\n className?: string;\n /** Classes applied to the floating card. */\n cardClassName?: string;\n};\n\nconst GAP_PX = 6;\n\ntype Position = { top: number; left: number };\n\n// Grace period that lets the cursor cross the gap from the trigger to the\n// portaled card without the card disappearing.\nconst HOVER_CLOSE_DELAY_MS = 120;\n\nexport function HoverCard({\n trigger,\n children,\n placement = \"top\",\n delay = 0,\n arrow = true,\n className,\n cardClassName,\n}: HoverCardProps) {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<Position | null>(null);\n const floatingZ = useFloatingZIndex();\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardRef = useRef<HTMLDivElement | null>(null);\n const openTimerRef = useRef<number | null>(null);\n const closeTimerRef = useRef<number | null>(null);\n\n const cancelClose = () => {\n if (closeTimerRef.current !== null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n function onEnter() {\n cancelClose();\n if (delay > 0) {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n openTimerRef.current = window.setTimeout(() => setOpen(true), delay);\n } else {\n setOpen(true);\n }\n }\n function onLeave() {\n if (openTimerRef.current !== null) {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n cancelClose();\n closeTimerRef.current = window.setTimeout(() => setOpen(false), HOVER_CLOSE_DELAY_MS);\n }\n\n // Recompute position whenever the card opens or the viewport scrolls/resizes\n // while it's open. We position via fixed coordinates so the card escapes\n // every overflow-hidden / transform ancestor — important when the trigger\n // sits inside a table row, dropdown, or modal that would otherwise clip it.\n useLayoutEffect(() => {\n if (!open) return;\n const update = () => {\n const trigger = triggerRef.current;\n const card = cardRef.current;\n if (!trigger || !card) return;\n const t = trigger.getBoundingClientRect();\n const c = card.getBoundingClientRect();\n let top = 0;\n let left = 0;\n switch (placement) {\n case \"top\":\n top = t.top - c.height - GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"bottom\":\n top = t.bottom + GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"left\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.left - c.width - GAP_PX;\n break;\n case \"right\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.right + GAP_PX;\n break;\n }\n // Clamp to viewport so cards near the edge don't overflow off-screen.\n const margin = 4;\n left = Math.min(Math.max(margin, left), window.innerWidth - c.width - margin);\n top = Math.min(Math.max(margin, top), window.innerHeight - c.height - margin);\n setPosition({ top, left });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open, placement, children]);\n\n useEffect(() => {\n return () => {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n if (closeTimerRef.current !== null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n const card =\n open && typeof document !== \"undefined\"\n ? createPortal(\n <div\n ref={cardRef}\n role=\"tooltip\"\n onMouseEnter={cancelClose}\n onMouseLeave={onLeave}\n style={{\n ...(position\n ? { position: \"fixed\", top: position.top, left: position.left }\n : { position: \"fixed\", top: -9999, left: -9999, visibility: \"hidden\" }),\n zIndex: floatingZ,\n }}\n className={cn(\n \"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] shadow-lg\",\n \"whitespace-nowrap\",\n cardClassName,\n )}\n >\n {children}\n {arrow && position && <Arrow placement={placement} />}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <span\n ref={triggerRef}\n className={cn(\"relative inline-flex items-center\", className)}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {trigger}\n {card}\n </span>\n );\n}\n\nfunction Arrow({ placement }: { placement: HoverCardPlacement }) {\n // The arrow is a small rotated square clipped to look like a notch on the\n // card edge that points back at the trigger. Drawn relative to the card.\n const base = \"absolute h-1.5 w-1.5 rotate-45 border bg-background border-border\";\n switch (placement) {\n case \"top\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -bottom-0.5 border-l-0 border-t-0\")}\n />\n );\n case \"bottom\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -top-0.5 border-r-0 border-b-0\")}\n />\n );\n case \"left\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -right-0.5 border-l-0 border-b-0\")}\n />\n );\n case \"right\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -left-0.5 border-r-0 border-t-0\")}\n />\n );\n }\n}\n"],"names":["useState","useFloatingZIndex","useRef","useLayoutEffect","trigger","card","useEffect","createPortal","jsxs","cn","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HoverCard.cjs","sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"./modalStack\";\n\nexport type HoverCardPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport type HoverCardProps = {\n /** Trigger content that opens the card on hover/focus. */\n trigger: ReactNode;\n /** Floating card content. */\n children: ReactNode;\n /** Preferred placement around the trigger. */\n placement?: HoverCardPlacement;\n /** Open delay in milliseconds. */\n delay?: number;\n /** Show the directional arrow. */\n arrow?: boolean;\n /** Classes applied to the trigger wrapper. */\n className?: string | undefined;\n /** Classes applied to the floating card. */\n cardClassName?: string | undefined;\n};\n\nconst GAP_PX = 6;\n\ntype Position = { top: number; left: number };\n\n// Grace period that lets the cursor cross the gap from the trigger to the\n// portaled card without the card disappearing.\nconst HOVER_CLOSE_DELAY_MS = 120;\n\nexport function HoverCard({\n trigger,\n children,\n placement = \"top\",\n delay = 0,\n arrow = true,\n className,\n cardClassName,\n}: HoverCardProps) {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<Position | null>(null);\n const floatingZ = useFloatingZIndex();\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardRef = useRef<HTMLDivElement | null>(null);\n const openTimerRef = useRef<number | null>(null);\n const closeTimerRef = useRef<number | null>(null);\n\n const cancelClose = () => {\n if (closeTimerRef.current !== null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n function onEnter() {\n cancelClose();\n if (delay > 0) {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n openTimerRef.current = window.setTimeout(() => setOpen(true), delay);\n } else {\n setOpen(true);\n }\n }\n function onLeave() {\n if (openTimerRef.current !== null) {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n cancelClose();\n closeTimerRef.current = window.setTimeout(() => setOpen(false), HOVER_CLOSE_DELAY_MS);\n }\n\n // Recompute position whenever the card opens or the viewport scrolls/resizes\n // while it's open. We position via fixed coordinates so the card escapes\n // every overflow-hidden / transform ancestor — important when the trigger\n // sits inside a table row, dropdown, or modal that would otherwise clip it.\n useLayoutEffect(() => {\n if (!open) return;\n const update = () => {\n const trigger = triggerRef.current;\n const card = cardRef.current;\n if (!trigger || !card) return;\n const t = trigger.getBoundingClientRect();\n const c = card.getBoundingClientRect();\n let top = 0;\n let left = 0;\n switch (placement) {\n case \"top\":\n top = t.top - c.height - GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"bottom\":\n top = t.bottom + GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"left\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.left - c.width - GAP_PX;\n break;\n case \"right\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.right + GAP_PX;\n break;\n }\n // Clamp to viewport so cards near the edge don't overflow off-screen.\n const margin = 4;\n left = Math.min(Math.max(margin, left), window.innerWidth - c.width - margin);\n top = Math.min(Math.max(margin, top), window.innerHeight - c.height - margin);\n setPosition({ top, left });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open, placement, children]);\n\n useEffect(() => {\n return () => {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n if (closeTimerRef.current !== null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n const card =\n open && typeof document !== \"undefined\"\n ? createPortal(\n <div\n ref={cardRef}\n role=\"tooltip\"\n onMouseEnter={cancelClose}\n onMouseLeave={onLeave}\n style={{\n ...(position\n ? { position: \"fixed\", top: position.top, left: position.left }\n : { position: \"fixed\", top: -9999, left: -9999, visibility: \"hidden\" }),\n zIndex: floatingZ,\n }}\n className={cn(\n \"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] shadow-lg\",\n \"whitespace-nowrap\",\n cardClassName,\n )}\n >\n {children}\n {arrow && position && <Arrow placement={placement} />}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <span\n ref={triggerRef}\n className={cn(\"relative inline-flex items-center\", className)}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {trigger}\n {card}\n </span>\n );\n}\n\nfunction Arrow({ placement }: { placement: HoverCardPlacement }) {\n // The arrow is a small rotated square clipped to look like a notch on the\n // card edge that points back at the trigger. Drawn relative to the card.\n const base = \"absolute h-1.5 w-1.5 rotate-45 border bg-background border-border\";\n switch (placement) {\n case \"top\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -bottom-0.5 border-l-0 border-t-0\")}\n />\n );\n case \"bottom\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -top-0.5 border-r-0 border-b-0\")}\n />\n );\n case \"left\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -right-0.5 border-l-0 border-b-0\")}\n />\n );\n case \"right\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -left-0.5 border-r-0 border-t-0\")}\n />\n );\n }\n}\n"],"names":["useState","useFloatingZIndex","useRef","useLayoutEffect","trigger","card","useEffect","createPortal","jsxs","cn","jsx"],"mappings":"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"}
|
|
@@ -12,9 +12,9 @@ export type HoverCardProps = {
|
|
|
12
12
|
/** Show the directional arrow. */
|
|
13
13
|
arrow?: boolean;
|
|
14
14
|
/** Classes applied to the trigger wrapper. */
|
|
15
|
-
className?: string;
|
|
15
|
+
className?: string | undefined;
|
|
16
16
|
/** Classes applied to the floating card. */
|
|
17
|
-
cardClassName?: string;
|
|
17
|
+
cardClassName?: string | undefined;
|
|
18
18
|
};
|
|
19
19
|
export declare function HoverCard({ trigger, children, placement, delay, arrow, className, cardClassName, }: HoverCardProps): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
//# sourceMappingURL=HoverCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../src/overlay/HoverCard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrF,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG;IAC3B,0DAA0D;IAC1D,OAAO,EAAE,SAAS,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../src/overlay/HoverCard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrF,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG;IAC3B,0DAA0D;IAC1D,OAAO,EAAE,SAAS,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;AAUF,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,QAAQ,EACR,SAAiB,EACjB,KAAS,EACT,KAAY,EACZ,SAAS,EACT,aAAa,GACd,EAAE,cAAc,2CAgIhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCard.js","sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"./modalStack\";\n\nexport type HoverCardPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport type HoverCardProps = {\n /** Trigger content that opens the card on hover/focus. */\n trigger: ReactNode;\n /** Floating card content. */\n children: ReactNode;\n /** Preferred placement around the trigger. */\n placement?: HoverCardPlacement;\n /** Open delay in milliseconds. */\n delay?: number;\n /** Show the directional arrow. */\n arrow?: boolean;\n /** Classes applied to the trigger wrapper. */\n className?: string;\n /** Classes applied to the floating card. */\n cardClassName?: string;\n};\n\nconst GAP_PX = 6;\n\ntype Position = { top: number; left: number };\n\n// Grace period that lets the cursor cross the gap from the trigger to the\n// portaled card without the card disappearing.\nconst HOVER_CLOSE_DELAY_MS = 120;\n\nexport function HoverCard({\n trigger,\n children,\n placement = \"top\",\n delay = 0,\n arrow = true,\n className,\n cardClassName,\n}: HoverCardProps) {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<Position | null>(null);\n const floatingZ = useFloatingZIndex();\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardRef = useRef<HTMLDivElement | null>(null);\n const openTimerRef = useRef<number | null>(null);\n const closeTimerRef = useRef<number | null>(null);\n\n const cancelClose = () => {\n if (closeTimerRef.current !== null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n function onEnter() {\n cancelClose();\n if (delay > 0) {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n openTimerRef.current = window.setTimeout(() => setOpen(true), delay);\n } else {\n setOpen(true);\n }\n }\n function onLeave() {\n if (openTimerRef.current !== null) {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n cancelClose();\n closeTimerRef.current = window.setTimeout(() => setOpen(false), HOVER_CLOSE_DELAY_MS);\n }\n\n // Recompute position whenever the card opens or the viewport scrolls/resizes\n // while it's open. We position via fixed coordinates so the card escapes\n // every overflow-hidden / transform ancestor — important when the trigger\n // sits inside a table row, dropdown, or modal that would otherwise clip it.\n useLayoutEffect(() => {\n if (!open) return;\n const update = () => {\n const trigger = triggerRef.current;\n const card = cardRef.current;\n if (!trigger || !card) return;\n const t = trigger.getBoundingClientRect();\n const c = card.getBoundingClientRect();\n let top = 0;\n let left = 0;\n switch (placement) {\n case \"top\":\n top = t.top - c.height - GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"bottom\":\n top = t.bottom + GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"left\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.left - c.width - GAP_PX;\n break;\n case \"right\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.right + GAP_PX;\n break;\n }\n // Clamp to viewport so cards near the edge don't overflow off-screen.\n const margin = 4;\n left = Math.min(Math.max(margin, left), window.innerWidth - c.width - margin);\n top = Math.min(Math.max(margin, top), window.innerHeight - c.height - margin);\n setPosition({ top, left });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open, placement, children]);\n\n useEffect(() => {\n return () => {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n if (closeTimerRef.current !== null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n const card =\n open && typeof document !== \"undefined\"\n ? createPortal(\n <div\n ref={cardRef}\n role=\"tooltip\"\n onMouseEnter={cancelClose}\n onMouseLeave={onLeave}\n style={{\n ...(position\n ? { position: \"fixed\", top: position.top, left: position.left }\n : { position: \"fixed\", top: -9999, left: -9999, visibility: \"hidden\" }),\n zIndex: floatingZ,\n }}\n className={cn(\n \"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] shadow-lg\",\n \"whitespace-nowrap\",\n cardClassName,\n )}\n >\n {children}\n {arrow && position && <Arrow placement={placement} />}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <span\n ref={triggerRef}\n className={cn(\"relative inline-flex items-center\", className)}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {trigger}\n {card}\n </span>\n );\n}\n\nfunction Arrow({ placement }: { placement: HoverCardPlacement }) {\n // The arrow is a small rotated square clipped to look like a notch on the\n // card edge that points back at the trigger. Drawn relative to the card.\n const base = \"absolute h-1.5 w-1.5 rotate-45 border bg-background border-border\";\n switch (placement) {\n case \"top\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -bottom-0.5 border-l-0 border-t-0\")}\n />\n );\n case \"bottom\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -top-0.5 border-r-0 border-b-0\")}\n />\n );\n case \"left\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -right-0.5 border-l-0 border-b-0\")}\n />\n );\n case \"right\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -left-0.5 border-r-0 border-t-0\")}\n />\n );\n }\n}\n"],"names":["trigger","card"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HoverCard.js","sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"./modalStack\";\n\nexport type HoverCardPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport type HoverCardProps = {\n /** Trigger content that opens the card on hover/focus. */\n trigger: ReactNode;\n /** Floating card content. */\n children: ReactNode;\n /** Preferred placement around the trigger. */\n placement?: HoverCardPlacement;\n /** Open delay in milliseconds. */\n delay?: number;\n /** Show the directional arrow. */\n arrow?: boolean;\n /** Classes applied to the trigger wrapper. */\n className?: string | undefined;\n /** Classes applied to the floating card. */\n cardClassName?: string | undefined;\n};\n\nconst GAP_PX = 6;\n\ntype Position = { top: number; left: number };\n\n// Grace period that lets the cursor cross the gap from the trigger to the\n// portaled card without the card disappearing.\nconst HOVER_CLOSE_DELAY_MS = 120;\n\nexport function HoverCard({\n trigger,\n children,\n placement = \"top\",\n delay = 0,\n arrow = true,\n className,\n cardClassName,\n}: HoverCardProps) {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<Position | null>(null);\n const floatingZ = useFloatingZIndex();\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardRef = useRef<HTMLDivElement | null>(null);\n const openTimerRef = useRef<number | null>(null);\n const closeTimerRef = useRef<number | null>(null);\n\n const cancelClose = () => {\n if (closeTimerRef.current !== null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n };\n\n function onEnter() {\n cancelClose();\n if (delay > 0) {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n openTimerRef.current = window.setTimeout(() => setOpen(true), delay);\n } else {\n setOpen(true);\n }\n }\n function onLeave() {\n if (openTimerRef.current !== null) {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n cancelClose();\n closeTimerRef.current = window.setTimeout(() => setOpen(false), HOVER_CLOSE_DELAY_MS);\n }\n\n // Recompute position whenever the card opens or the viewport scrolls/resizes\n // while it's open. We position via fixed coordinates so the card escapes\n // every overflow-hidden / transform ancestor — important when the trigger\n // sits inside a table row, dropdown, or modal that would otherwise clip it.\n useLayoutEffect(() => {\n if (!open) return;\n const update = () => {\n const trigger = triggerRef.current;\n const card = cardRef.current;\n if (!trigger || !card) return;\n const t = trigger.getBoundingClientRect();\n const c = card.getBoundingClientRect();\n let top = 0;\n let left = 0;\n switch (placement) {\n case \"top\":\n top = t.top - c.height - GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"bottom\":\n top = t.bottom + GAP_PX;\n left = t.left + t.width / 2 - c.width / 2;\n break;\n case \"left\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.left - c.width - GAP_PX;\n break;\n case \"right\":\n top = t.top + t.height / 2 - c.height / 2;\n left = t.right + GAP_PX;\n break;\n }\n // Clamp to viewport so cards near the edge don't overflow off-screen.\n const margin = 4;\n left = Math.min(Math.max(margin, left), window.innerWidth - c.width - margin);\n top = Math.min(Math.max(margin, top), window.innerHeight - c.height - margin);\n setPosition({ top, left });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open, placement, children]);\n\n useEffect(() => {\n return () => {\n if (openTimerRef.current !== null) window.clearTimeout(openTimerRef.current);\n if (closeTimerRef.current !== null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n const card =\n open && typeof document !== \"undefined\"\n ? createPortal(\n <div\n ref={cardRef}\n role=\"tooltip\"\n onMouseEnter={cancelClose}\n onMouseLeave={onLeave}\n style={{\n ...(position\n ? { position: \"fixed\", top: position.top, left: position.left }\n : { position: \"fixed\", top: -9999, left: -9999, visibility: \"hidden\" }),\n zIndex: floatingZ,\n }}\n className={cn(\n \"rounded-md border border-border bg-background px-2.5 py-1.5 text-[11px] shadow-lg\",\n \"whitespace-nowrap\",\n cardClassName,\n )}\n >\n {children}\n {arrow && position && <Arrow placement={placement} />}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <span\n ref={triggerRef}\n className={cn(\"relative inline-flex items-center\", className)}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {trigger}\n {card}\n </span>\n );\n}\n\nfunction Arrow({ placement }: { placement: HoverCardPlacement }) {\n // The arrow is a small rotated square clipped to look like a notch on the\n // card edge that points back at the trigger. Drawn relative to the card.\n const base = \"absolute h-1.5 w-1.5 rotate-45 border bg-background border-border\";\n switch (placement) {\n case \"top\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -bottom-0.5 border-l-0 border-t-0\")}\n />\n );\n case \"bottom\":\n return (\n <span\n aria-hidden\n className={cn(base, \"left-1/2 -translate-x-1/2 -top-0.5 border-r-0 border-b-0\")}\n />\n );\n case \"left\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -right-0.5 border-l-0 border-b-0\")}\n />\n );\n case \"right\":\n return (\n <span\n aria-hidden\n className={cn(base, \"top-1/2 -translate-y-1/2 -left-0.5 border-r-0 border-t-0\")}\n />\n );\n }\n}\n"],"names":["trigger","card"],"mappings":"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"}
|
package/dist/overlay/Modal.cjs
CHANGED
|
@@ -97,7 +97,7 @@ function Modal({
|
|
|
97
97
|
"aria-modal": "true",
|
|
98
98
|
"aria-label": typeof title === "string" ? title : void 0,
|
|
99
99
|
className: utils.cn(
|
|
100
|
-
"relative flex w-full flex-col rounded-lg border border-border bg-background shadow-xl",
|
|
100
|
+
"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
|
|
101
101
|
expanded ? sizeClass.full : sizeClass[size],
|
|
102
102
|
className
|
|
103
103
|
),
|
|
@@ -107,7 +107,7 @@ function Modal({
|
|
|
107
107
|
},
|
|
108
108
|
onClick: (e) => e.stopPropagation(),
|
|
109
109
|
children: [
|
|
110
|
-
(title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-density-4 py-density-3 border-b border-border", 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: [
|
|
111
111
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-density-2", children: [
|
|
112
112
|
title ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold flex-1", children: title }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
113
113
|
headerSlot,
|
|
@@ -139,13 +139,20 @@ function Modal({
|
|
|
139
139
|
{
|
|
140
140
|
"data-slot": "modal-body",
|
|
141
141
|
className: utils.cn(
|
|
142
|
-
"flex-1 px-density-4 py-density-3",
|
|
143
|
-
scrollBody ? "overflow-auto" : "flex
|
|
142
|
+
"min-h-0 flex-1 px-density-4 py-density-3",
|
|
143
|
+
scrollBody ? "overflow-auto" : "flex flex-col overflow-hidden"
|
|
144
144
|
),
|
|
145
145
|
children
|
|
146
146
|
}
|
|
147
147
|
),
|
|
148
|
-
footer && /* @__PURE__ */ jsxRuntime.jsx(
|
|
148
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
+
"div",
|
|
150
|
+
{
|
|
151
|
+
"data-slot": "modal-footer",
|
|
152
|
+
className: "shrink-0 px-density-4 py-density-3 border-t border-border",
|
|
153
|
+
children: footer
|
|
154
|
+
}
|
|
155
|
+
),
|
|
149
156
|
confirming && /* @__PURE__ */ jsxRuntime.jsx(
|
|
150
157
|
ConfirmClosePrompt,
|
|
151
158
|
{
|
|
@@ -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 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=\"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 \"flex-1 px-density-4 py-density-3\",\n scrollBody\n ? \"overflow-auto\"\n : \"flex min-h-0 flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div data-slot=\"modal-footer\" className=\"px-density-4 py-density-3 border-t border-border\">\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 { 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 +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,
|
|
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"}
|
package/dist/overlay/Modal.js
CHANGED
|
@@ -95,7 +95,7 @@ function Modal({
|
|
|
95
95
|
"aria-modal": "true",
|
|
96
96
|
"aria-label": typeof title === "string" ? title : void 0,
|
|
97
97
|
className: cn(
|
|
98
|
-
"relative flex w-full flex-col rounded-lg border border-border bg-background shadow-xl",
|
|
98
|
+
"relative flex w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
|
|
99
99
|
expanded ? sizeClass.full : sizeClass[size],
|
|
100
100
|
className
|
|
101
101
|
),
|
|
@@ -105,7 +105,7 @@ function Modal({
|
|
|
105
105
|
},
|
|
106
106
|
onClick: (e) => e.stopPropagation(),
|
|
107
107
|
children: [
|
|
108
|
-
(title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxs("div", { className: "px-density-4 py-density-3 border-b border-border", children: [
|
|
108
|
+
(title || subtitle || headerSlot || expandable || !hideClose) && /* @__PURE__ */ jsxs("div", { className: "shrink-0 px-density-4 py-density-3 border-b border-border", children: [
|
|
109
109
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2", children: [
|
|
110
110
|
title ? /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold flex-1", children: title }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
111
111
|
headerSlot,
|
|
@@ -137,13 +137,20 @@ function Modal({
|
|
|
137
137
|
{
|
|
138
138
|
"data-slot": "modal-body",
|
|
139
139
|
className: cn(
|
|
140
|
-
"flex-1 px-density-4 py-density-3",
|
|
141
|
-
scrollBody ? "overflow-auto" : "flex
|
|
140
|
+
"min-h-0 flex-1 px-density-4 py-density-3",
|
|
141
|
+
scrollBody ? "overflow-auto" : "flex flex-col overflow-hidden"
|
|
142
142
|
),
|
|
143
143
|
children
|
|
144
144
|
}
|
|
145
145
|
),
|
|
146
|
-
footer && /* @__PURE__ */ jsx(
|
|
146
|
+
footer && /* @__PURE__ */ jsx(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
"data-slot": "modal-footer",
|
|
150
|
+
className: "shrink-0 px-density-4 py-density-3 border-t border-border",
|
|
151
|
+
children: footer
|
|
152
|
+
}
|
|
153
|
+
),
|
|
147
154
|
confirming && /* @__PURE__ */ jsx(
|
|
148
155
|
ConfirmClosePrompt,
|
|
149
156
|
{
|
|
@@ -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 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=\"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 \"flex-1 px-density-4 py-density-3\",\n scrollBody\n ? \"overflow-auto\"\n : \"flex min-h-0 flex-col overflow-hidden\",\n )}\n >\n {children}\n </div>\n {footer && (\n <div data-slot=\"modal-footer\" className=\"px-density-4 py-density-3 border-t border-border\">\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 { 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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"}
|