@mastra/playground-ui 65.0.0-alpha.3 → 65.0.0-alpha.4
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/README.md +10 -0
- package/components.css +7 -0
- package/dist/{Avatar-98bsFrSV.js → Avatar-BjaG9NU_.js} +10 -8
- package/dist/Avatar-BjaG9NU_.js.map +1 -0
- package/dist/{Avatar-BCj8SvOb.cjs → Avatar-DM90rmwx.cjs} +10 -8
- package/dist/Avatar-DM90rmwx.cjs.map +1 -0
- package/dist/{Button-DH1aTzbs.cjs → Button-C4I05uT4.cjs} +17 -10
- package/dist/Button-C4I05uT4.cjs.map +1 -0
- package/dist/{Button-EGoajBQY.js → Button-D8a5EWJ5.js} +18 -11
- package/dist/Button-D8a5EWJ5.js.map +1 -0
- package/dist/{ErrorBoundary-DQPzT6am.js → ErrorBoundary-C6JifxpQ.js} +2 -2
- package/dist/{ErrorBoundary-DQPzT6am.js.map → ErrorBoundary-C6JifxpQ.js.map} +1 -1
- package/dist/{ErrorBoundary-CpUob9SO.cjs → ErrorBoundary-DP1JqmTo.cjs} +2 -2
- package/dist/{ErrorBoundary-CpUob9SO.cjs.map → ErrorBoundary-DP1JqmTo.cjs.map} +1 -1
- package/dist/Notice-BioYTS4b.js.map +1 -1
- package/dist/Notice-DYgIy4FO.cjs.map +1 -1
- package/dist/{activity-CsTUr5_l.js → activity-B7c_nQMn.js} +2 -2
- package/dist/activity-B7c_nQMn.js.map +1 -0
- package/dist/{activity-2tovEdIP.cjs → activity-D3iI9pYN.cjs} +2 -2
- package/dist/activity-D3iI9pYN.cjs.map +1 -0
- package/dist/{alert-dialog-B7JTnkF4.js → alert-dialog-B13NSeKN.js} +3 -3
- package/dist/{alert-dialog-B7JTnkF4.js.map → alert-dialog-B13NSeKN.js.map} +1 -1
- package/dist/{alert-dialog-B1gWLQm2.cjs → alert-dialog-DY2JJAnk.cjs} +3 -3
- package/dist/{alert-dialog-B1gWLQm2.cjs.map → alert-dialog-DY2JJAnk.cjs.map} +1 -1
- package/dist/arrival-C1hkyLHm.js.map +1 -1
- package/dist/arrival-Cvxloi0B.cjs.map +1 -1
- package/dist/{ask-user-card-DroerVbm.cjs → ask-user-card-DiFQcUzM.cjs} +2 -2
- package/dist/ask-user-card-DiFQcUzM.cjs.map +1 -0
- package/dist/{ask-user-card-BCjsjimu.js → ask-user-card-DnvW7jXS.js} +2 -2
- package/dist/{ask-user-card-BCjsjimu.js.map → ask-user-card-DnvW7jXS.js.map} +1 -1
- package/dist/{avatar-size-CNR0U-LW.js → avatar-size-BXzy28Bx.js} +4 -1
- package/dist/avatar-size-BXzy28Bx.js.map +1 -0
- package/dist/{avatar-size-DxStOo5A.cjs → avatar-size-DIFE4I8A.cjs} +4 -1
- package/dist/avatar-size-DIFE4I8A.cjs.map +1 -0
- package/dist/buttons-group.css +0 -4
- package/dist/code-DJReJPSX.cjs.map +1 -1
- package/dist/code-DLuATvYu.js.map +1 -1
- package/dist/{code-block-vpcX2sDQ.cjs → code-block-C79fiykv.cjs} +4 -4
- package/dist/{code-block-vpcX2sDQ.cjs.map → code-block-C79fiykv.cjs.map} +1 -1
- package/dist/{code-block-DIDa6lg6.js → code-block-D6A1DMv-.js} +4 -4
- package/dist/{code-block-DIDa6lg6.js.map → code-block-D6A1DMv-.js.map} +1 -1
- package/dist/{code-editor-BDxYMkGm.js → code-editor-8Fpinga4.js} +2 -2
- package/dist/{code-editor-BDxYMkGm.js.map → code-editor-8Fpinga4.js.map} +1 -1
- package/dist/{code-editor-DQuJ1XXd.cjs → code-editor-Bd-Cldem.cjs} +2 -2
- package/dist/{code-editor-DQuJ1XXd.cjs.map → code-editor-Bd-Cldem.cjs.map} +1 -1
- package/dist/{collapsible-box-B9ATVQzW.cjs → collapsible-box-CzU0OwJx.cjs} +2 -2
- package/dist/{collapsible-box-B9ATVQzW.cjs.map → collapsible-box-CzU0OwJx.cjs.map} +1 -1
- package/dist/{collapsible-box-CMBYunuM.js → collapsible-box-DotFa3hr.js} +2 -2
- package/dist/{collapsible-box-CMBYunuM.js.map → collapsible-box-DotFa3hr.js.map} +1 -1
- package/dist/{combobox-Bw13EcK0.js → combobox-BCoCVZHs.js} +7 -5
- package/dist/combobox-BCoCVZHs.js.map +1 -0
- package/dist/{combobox-BNlVCFgY.cjs → combobox-DbZAWh8q.cjs} +7 -5
- package/dist/combobox-DbZAWh8q.cjs.map +1 -0
- package/dist/{combobox-styles-Dr66ofEp.js → combobox-styles-Cens2tsx.js} +2 -2
- package/dist/{combobox-styles-Dr66ofEp.js.map → combobox-styles-Cens2tsx.js.map} +1 -1
- package/dist/{combobox-styles-BK2nGTNl.cjs → combobox-styles-Cy4rpw03.cjs} +2 -2
- package/dist/{combobox-styles-BK2nGTNl.cjs.map → combobox-styles-Cy4rpw03.cjs.map} +1 -1
- package/dist/{command-UEPxVJlE.cjs → command-Duh5C_Pm.cjs} +2 -2
- package/dist/command-Duh5C_Pm.cjs.map +1 -0
- package/dist/{command-V9rsKc7P.js → command-xIH7ZTdl.js} +2 -2
- package/dist/command-xIH7ZTdl.js.map +1 -0
- package/dist/components/AlertDialog.cjs.js +1 -1
- package/dist/components/AlertDialog.es.js +1 -1
- package/dist/components/Avatar.cjs.js +1 -1
- package/dist/components/Avatar.es.js +1 -1
- package/dist/components/Breadcrumb.cjs.js +7 -4
- package/dist/components/Breadcrumb.cjs.js.map +1 -1
- package/dist/components/Breadcrumb.es.js +7 -4
- package/dist/components/Breadcrumb.es.js.map +1 -1
- package/dist/components/Button.cjs.js +1 -1
- package/dist/components/Button.es.js +2 -2
- package/dist/components/ClampedText.cjs.js +2 -2
- package/dist/components/ClampedText.cjs.js.map +1 -1
- package/dist/components/ClampedText.es.js +2 -2
- package/dist/components/ClampedText.es.js.map +1 -1
- package/dist/components/CodeBlock.cjs.js +1 -1
- package/dist/components/CodeBlock.es.js +1 -1
- package/dist/components/CodeEditor.cjs.js +1 -1
- package/dist/components/CodeEditor.es.js +1 -1
- package/dist/components/CollapsibleBox.cjs.js +1 -1
- package/dist/components/CollapsibleBox.es.js +1 -1
- package/dist/components/Combobox.cjs.js +2 -2
- package/dist/components/Combobox.es.js +2 -2
- package/dist/components/Command.cjs.js +1 -1
- package/dist/components/Command.es.js +1 -1
- package/dist/components/CommandPalette.cjs.js +1 -1
- package/dist/components/CommandPalette.es.js +1 -1
- package/dist/components/Comment.cjs.js +2 -2
- package/dist/components/Comment.es.js +2 -2
- package/dist/components/CopyButton.cjs.js +1 -1
- package/dist/components/CopyButton.es.js +1 -1
- package/dist/components/DataCodeSection.cjs.js +1 -1
- package/dist/components/DataCodeSection.es.js +1 -1
- package/dist/components/DataDetailsPanel.cjs.js +2 -2
- package/dist/components/DataDetailsPanel.es.js +2 -2
- package/dist/components/DataKeysAndValues.cjs.js +1 -1
- package/dist/components/DataKeysAndValues.es.js +1 -1
- package/dist/components/DataList.cjs.js +15 -17
- package/dist/components/DataList.cjs.js.map +1 -1
- package/dist/components/DataList.es.js +4 -5
- package/dist/components/DataList.es.js.map +1 -1
- package/dist/components/DataPanel.cjs.js +1 -1
- package/dist/components/DataPanel.es.js +1 -1
- package/dist/components/DateRangeTimeline.cjs.js +1 -1
- package/dist/components/DateRangeTimeline.es.js +1 -1
- package/dist/components/DateTimePicker.cjs.js +2 -2
- package/dist/components/DateTimePicker.es.js +2 -2
- package/dist/components/DateTimeRangePicker.cjs.js +1 -1
- package/dist/components/DateTimeRangePicker.es.js +1 -1
- package/dist/components/Dialog.cjs.js +2 -2
- package/dist/components/Dialog.es.js +2 -2
- package/dist/components/DisabledFeatureButton.cjs.js +1 -1
- package/dist/components/DisabledFeatureButton.es.js +1 -1
- package/dist/components/Drawer.cjs.js +1 -1
- package/dist/components/Drawer.es.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.cjs.js +3 -3
- package/dist/components/EnvironmentVariablesEditor.cjs.js.map +1 -1
- package/dist/components/EnvironmentVariablesEditor.es.js +3 -3
- package/dist/components/EnvironmentVariablesEditor.es.js.map +1 -1
- package/dist/components/ErrorBoundary.cjs.js +1 -1
- package/dist/components/ErrorBoundary.es.js +1 -1
- package/dist/components/FilterBar.cjs.js +8 -31
- package/dist/components/FilterBar.cjs.js.map +1 -1
- package/dist/components/FilterBar.es.js +10 -33
- package/dist/components/FilterBar.es.js.map +1 -1
- package/dist/components/FormFieldBlocks.cjs.js +3 -3
- package/dist/components/FormFieldBlocks.cjs.js.map +1 -1
- package/dist/components/FormFieldBlocks.es.js +3 -3
- package/dist/components/FormFieldBlocks.es.js.map +1 -1
- package/dist/components/InputGroup.cjs.js +1 -1
- package/dist/components/InputGroup.es.js +1 -1
- package/dist/components/InputNumber.cjs.js +2 -2
- package/dist/components/InputNumber.es.js +2 -2
- package/dist/components/JSONSchemaForm.cjs.js +2 -2
- package/dist/components/JSONSchemaForm.es.js +2 -2
- package/dist/components/ListSearch.cjs.js +1 -1
- package/dist/components/ListSearch.es.js +1 -1
- package/dist/components/LogsDataList.cjs.js +5 -2
- package/dist/components/LogsDataList.cjs.js.map +1 -1
- package/dist/components/LogsDataList.es.js +5 -2
- package/dist/components/LogsDataList.es.js.map +1 -1
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/Message.cjs.js +1 -1
- package/dist/components/Message.es.js +1 -1
- package/dist/components/MetricsCard.cjs.js +1 -1
- package/dist/components/MetricsCard.es.js +1 -1
- package/dist/components/PrevNextNav.cjs.js +1 -1
- package/dist/components/PrevNextNav.es.js +1 -1
- package/dist/components/ProductAvatar.cjs.js +2 -1
- package/dist/components/ProductAvatar.cjs.js.map +1 -1
- package/dist/components/ProductAvatar.es.js +2 -1
- package/dist/components/ProductAvatar.es.js.map +1 -1
- package/dist/components/PropertyFilter.cjs.js +4 -4
- package/dist/components/PropertyFilter.cjs.js.map +1 -1
- package/dist/components/PropertyFilter.es.js +5 -5
- package/dist/components/PropertyFilter.es.js.map +1 -1
- package/dist/components/RuleBuilder.cjs.js +3 -2
- package/dist/components/RuleBuilder.cjs.js.map +1 -1
- package/dist/components/RuleBuilder.es.js +3 -2
- package/dist/components/RuleBuilder.es.js.map +1 -1
- package/dist/components/SavedViews.cjs.js +4 -8
- package/dist/components/SavedViews.cjs.js.map +1 -1
- package/dist/components/SavedViews.es.js +5 -9
- package/dist/components/SavedViews.es.js.map +1 -1
- package/dist/components/SearchInput.cjs.js +1 -1
- package/dist/components/SearchInput.es.js +1 -1
- package/dist/components/Select.cjs.js +1 -1
- package/dist/components/Select.es.js +1 -1
- package/dist/components/SideDialog.cjs.js +1 -1
- package/dist/components/SideDialog.es.js +1 -1
- package/dist/components/Sidebar.cjs.js +3 -3
- package/dist/components/Sidebar.cjs.js.map +1 -1
- package/dist/components/Sidebar.es.js +3 -3
- package/dist/components/Sidebar.es.js.map +1 -1
- package/dist/components/StatusIndicators.cjs.js.map +1 -1
- package/dist/components/StatusIndicators.es.js.map +1 -1
- package/dist/components/Table.cjs.js.map +1 -1
- package/dist/components/Table.es.js.map +1 -1
- package/dist/components/Tabs.cjs.js +1 -1
- package/dist/components/Tabs.es.js +1 -1
- package/dist/components/ThreadList.cjs.js +1 -1
- package/dist/components/ThreadList.es.js +1 -1
- package/dist/components/ThreadRail.cjs.js.map +1 -1
- package/dist/components/ThreadRail.es.js.map +1 -1
- package/dist/components/Truncate.cjs.js +1 -1
- package/dist/components/Truncate.es.js +1 -1
- package/dist/components/Workflow.cjs.js +6 -6
- package/dist/components/Workflow.es.js +6 -6
- package/dist/components/ai/activity.cjs.js +4 -4
- package/dist/components/ai/activity.es.js +4 -4
- package/dist/components/ai/ask-user.cjs.js +1 -1
- package/dist/components/ai/ask-user.es.js +1 -1
- package/dist/components/ai/plan.cjs.js +1 -1
- package/dist/components/ai/plan.es.js +1 -1
- package/dist/components/ai/tool-approval.cjs.js +1 -1
- package/dist/components/ai/tool-approval.es.js +1 -1
- package/dist/components/ai/tool-call.cjs.js +4 -4
- package/dist/components/ai/tool-call.es.js +4 -4
- package/dist/composer-Bs4iyUfe.js.map +1 -1
- package/dist/composer-CDQnP3og.cjs.map +1 -1
- package/dist/context-menu-C67xhcfa.js.map +1 -1
- package/dist/context-menu-jNuzE86D.cjs.map +1 -1
- package/dist/{copy-button-Cd0keCti.cjs → copy-button-BC02oZJo.cjs} +2 -2
- package/dist/{copy-button-Cd0keCti.cjs.map → copy-button-BC02oZJo.cjs.map} +1 -1
- package/dist/{copy-button-C_M3Tu_-.js → copy-button-B_i9lwFJ.js} +2 -2
- package/dist/{copy-button-C_M3Tu_-.js.map → copy-button-B_i9lwFJ.js.map} +1 -1
- package/dist/{data-code-section-lj3PaHjc.cjs → data-code-section-BJa6NDgN.cjs} +5 -5
- package/dist/{data-code-section-lj3PaHjc.cjs.map → data-code-section-BJa6NDgN.cjs.map} +1 -1
- package/dist/{data-code-section-mpRgtM8j.js → data-code-section-Cjs-piiY.js} +5 -5
- package/dist/{data-code-section-mpRgtM8j.js.map → data-code-section-Cjs-piiY.js.map} +1 -1
- package/dist/{data-keys-and-values-1lYi60YK.cjs → data-keys-and-values-DBXIqeXt.cjs} +2 -2
- package/dist/data-keys-and-values-DBXIqeXt.cjs.map +1 -0
- package/dist/{data-keys-and-values-CHpxKsfq.js → data-keys-and-values-DHp6cHJo.js} +2 -2
- package/dist/data-keys-and-values-DHp6cHJo.js.map +1 -0
- package/dist/{data-list-top-DJh08vFA.cjs → data-list-DlXU1PLQ.cjs} +339 -13
- package/dist/data-list-DlXU1PLQ.cjs.map +1 -0
- package/dist/{data-list-top-T-mtdIUp.js → data-list-Tor18oy5.js} +332 -5
- package/dist/data-list-Tor18oy5.js.map +1 -0
- package/dist/{data-list-skeleton-bNfITSHs.js → data-list-skeleton-CXUB-u3p.js} +2 -2
- package/dist/{data-list-skeleton-bNfITSHs.js.map → data-list-skeleton-CXUB-u3p.js.map} +1 -1
- package/dist/{data-list-skeleton-sdcaabdX.cjs → data-list-skeleton-DY0F40WQ.cjs} +6 -6
- package/dist/{data-list-skeleton-sdcaabdX.cjs.map → data-list-skeleton-DY0F40WQ.cjs.map} +1 -1
- package/dist/{data-panel-BkfjzriB.cjs → data-panel-DGNV14pm.cjs} +20 -9
- package/dist/data-panel-DGNV14pm.cjs.map +1 -0
- package/dist/{data-panel-CMkR6Avv.js → data-panel-DjtnX70w.js} +20 -9
- package/dist/data-panel-DjtnX70w.js.map +1 -0
- package/dist/{date-time-range-picker-BjQVCVUM.cjs → date-time-range-picker-CXGab8Nj.cjs} +3 -3
- package/dist/{date-time-range-picker-BjQVCVUM.cjs.map → date-time-range-picker-CXGab8Nj.cjs.map} +1 -1
- package/dist/{date-time-range-picker-D-EECKzz.js → date-time-range-picker-CcnDMZJu.js} +3 -3
- package/dist/{date-time-range-picker-D-EECKzz.js.map → date-time-range-picker-CcnDMZJu.js.map} +1 -1
- package/dist/{dialog-j2e95YNV.js → dialog-AzCRnEo3.js} +3 -3
- package/dist/{dialog-j2e95YNV.js.map → dialog-AzCRnEo3.js.map} +1 -1
- package/dist/{dialog-BMUfQ9XU.cjs → dialog-SSeOqRnH.cjs} +3 -3
- package/dist/{dialog-BMUfQ9XU.cjs.map → dialog-SSeOqRnH.cjs.map} +1 -1
- package/dist/{dialog-action-CmFDNyZX.cjs → dialog-action-Caa-pb85.cjs} +3 -3
- package/dist/{dialog-action-CmFDNyZX.cjs.map → dialog-action-Caa-pb85.cjs.map} +1 -1
- package/dist/{dialog-action-zKqvuroE.js → dialog-action-DykMOK2W.js} +3 -3
- package/dist/{dialog-action-zKqvuroE.js.map → dialog-action-DykMOK2W.js.map} +1 -1
- package/dist/domains/auth/components/session-expired.cjs.js +1 -1
- package/dist/domains/auth/components/session-expired.es.js +1 -1
- package/dist/domains/chat/attachments/attachment-preview-dialog.cjs.js +2 -2
- package/dist/domains/chat/attachments/attachment-preview-dialog.es.js +2 -2
- package/dist/domains/chat/attachments/composer-attachment.cjs.js +1 -1
- package/dist/domains/chat/attachments/composer-attachment.es.js +1 -1
- package/dist/domains/chat/components/badge-wrapper.cjs.js +1 -1
- package/dist/domains/chat/components/badge-wrapper.es.js +1 -1
- package/dist/domains/chat/components/network-choice-metadata-dialog.cjs.js +3 -3
- package/dist/domains/chat/components/network-choice-metadata-dialog.es.js +3 -3
- package/dist/domains/chat/messages/assistant-message-actions.cjs.js +2 -2
- package/dist/domains/chat/messages/assistant-message-actions.es.js +2 -2
- package/dist/domains/chat/messages/dataset-save-action.cjs.js +5 -5
- package/dist/domains/chat/messages/dataset-save-action.es.js +5 -5
- package/dist/domains/chat/messages/message-row.cjs.js +4 -4
- package/dist/domains/chat/messages/message-row.es.js +4 -4
- package/dist/domains/chat/messages/notification-signal-notice.cjs.js +1 -1
- package/dist/domains/chat/messages/notification-signal-notice.es.js +1 -1
- package/dist/domains/chat/messages/renderers/message-text.cjs.js +1 -1
- package/dist/domains/chat/messages/renderers/message-text.cjs.js.map +1 -1
- package/dist/domains/chat/messages/renderers/message-text.es.js +1 -1
- package/dist/domains/chat/messages/renderers/message-text.es.js.map +1 -1
- package/dist/domains/chat/messages/renderers/reasoning-part-renderer.cjs.js +1 -1
- package/dist/domains/chat/messages/renderers/reasoning-part-renderer.es.js +1 -1
- package/dist/domains/chat/messages/signal-badge.cjs.js +1 -1
- package/dist/domains/chat/messages/signal-badge.es.js +1 -1
- package/dist/domains/chat/messages/skill-message.cjs.js +3 -3
- package/dist/domains/chat/messages/skill-message.es.js +3 -3
- package/dist/domains/chat/messages/system-reminder-badge.cjs.js +1 -1
- package/dist/domains/chat/messages/system-reminder-badge.es.js +1 -1
- package/dist/domains/chat/om/om-parts-converter.cjs.js.map +1 -1
- package/dist/domains/chat/om/om-parts-converter.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.es.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge.cjs.js +4 -4
- package/dist/domains/chat/tools/badges/agent-badge.es.js +4 -4
- package/dist/domains/chat/tools/badges/ask-user-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/ask-user-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.cjs.js +3 -3
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.es.js +3 -3
- package/dist/domains/chat/tools/badges/background-task-metadata-dialog.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/code-mode-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/code-mode-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/file-tree-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/file-tree-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-details.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-details.es.js +2 -2
- package/dist/domains/chat/tools/badges/observation-renderer.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/observation-renderer.es.js +1 -1
- package/dist/domains/chat/tools/badges/sandbox-execution-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/sandbox-execution-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/tool-approval-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/tool-approval-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/tool-badge.cjs.js +3 -3
- package/dist/domains/chat/tools/badges/tool-badge.es.js +3 -3
- package/dist/domains/chat/tools/badges/workflow-badge.cjs.js +6 -4
- package/dist/domains/chat/tools/badges/workflow-badge.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/workflow-badge.es.js +6 -4
- package/dist/domains/chat/tools/badges/workflow-badge.es.js.map +1 -1
- package/dist/domains/chat/tools/submit-plan-tool.cjs.js +2 -2
- package/dist/domains/chat/tools/submit-plan-tool.es.js +2 -2
- package/dist/domains/chat/tools/tool-card.cjs.js +1 -1
- package/dist/domains/chat/tools/tool-card.es.js +1 -1
- package/dist/domains/datasets/components/save-as-dataset-item-dialog.cjs.js +4 -4
- package/dist/domains/datasets/components/save-as-dataset-item-dialog.es.js +4 -4
- package/dist/domains/logs/components/log-data-panel.cjs.js +4 -4
- package/dist/domains/logs/components/log-data-panel.es.js +4 -4
- package/dist/domains/logs/components/logs-list-view.cjs.js +3 -2
- package/dist/domains/logs/components/logs-list-view.cjs.js.map +1 -1
- package/dist/domains/logs/components/logs-list-view.es.js +3 -2
- package/dist/domains/logs/components/logs-list-view.es.js.map +1 -1
- package/dist/domains/logs/components/logs-toolbar.cjs.js +1 -1
- package/dist/domains/logs/components/logs-toolbar.es.js +1 -1
- package/dist/domains/logs/components/no-logs-info.cjs.js +1 -1
- package/dist/domains/logs/components/no-logs-info.es.js +1 -1
- package/dist/domains/mcps/components/mcp-app-viewer.cjs.js.map +1 -1
- package/dist/domains/mcps/components/mcp-app-viewer.es.js.map +1 -1
- package/dist/domains/memory/components/flame-graph.cjs.js +1 -1
- package/dist/domains/memory/components/flame-graph.es.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.cjs.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.es.js +1 -1
- package/dist/domains/metrics/components/agent-runs-card.cjs.js +1 -1
- package/dist/domains/metrics/components/agent-runs-card.es.js +1 -1
- package/dist/domains/metrics/components/card-action-buttons.cjs.js +1 -1
- package/dist/domains/metrics/components/card-action-buttons.es.js +1 -1
- package/dist/domains/metrics/components/chart-area.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-area.es.js +1 -1
- package/dist/domains/metrics/components/chart-card-error.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-card-error.es.js +1 -1
- package/dist/domains/metrics/components/chart-card.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-card.es.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.cjs.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.es.js +1 -1
- package/dist/domains/metrics/components/failure-rate-card.cjs.js +1 -1
- package/dist/domains/metrics/components/failure-rate-card.es.js +1 -1
- package/dist/domains/metrics/components/latency-card.cjs.js +1 -1
- package/dist/domains/metrics/components/latency-card.es.js +1 -1
- package/dist/domains/metrics/components/scores-card.cjs.js +1 -1
- package/dist/domains/metrics/components/scores-card.es.js +1 -1
- package/dist/domains/metrics/components/token-usage-card.cjs.js +1 -1
- package/dist/domains/metrics/components/token-usage-card.es.js +1 -1
- package/dist/domains/metrics/components/trace-volume-card.cjs.js +1 -1
- package/dist/domains/metrics/components/trace-volume-card.es.js +1 -1
- package/dist/domains/metrics/components/usage-card.cjs.js +1 -1
- package/dist/domains/metrics/components/usage-card.es.js +1 -1
- package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.cjs.js +4 -4
- package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.es.js +4 -4
- package/dist/domains/scores/components/score-data-panel.cjs.js +3 -3
- package/dist/domains/scores/components/score-data-panel.es.js +3 -3
- package/dist/domains/scores/components/span-scoring.cjs.js +3 -3
- package/dist/domains/scores/components/span-scoring.es.js +3 -3
- package/dist/domains/scores/components/trace-scores-tab.cjs.js +2 -1
- package/dist/domains/scores/components/trace-scores-tab.cjs.js.map +1 -1
- package/dist/domains/scores/components/trace-scores-tab.es.js +2 -1
- package/dist/domains/scores/components/trace-scores-tab.es.js.map +1 -1
- package/dist/domains/traces/components/feedback-thread.cjs.js +4 -4
- package/dist/domains/traces/components/feedback-thread.cjs.js.map +1 -1
- package/dist/domains/traces/components/feedback-thread.es.js +4 -4
- package/dist/domains/traces/components/feedback-thread.es.js.map +1 -1
- package/dist/domains/traces/components/shared.cjs.js +4 -3
- package/dist/domains/traces/components/shared.cjs.js.map +1 -1
- package/dist/domains/traces/components/shared.es.js +5 -4
- package/dist/domains/traces/components/shared.es.js.map +1 -1
- package/dist/domains/traces/components/span-data-panel-view.cjs.js +4 -4
- package/dist/domains/traces/components/span-data-panel-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-data-panel-view.es.js +4 -4
- package/dist/domains/traces/components/span-data-panel-view.es.js.map +1 -1
- package/dist/domains/traces/components/span-details-view.cjs.js +1 -1
- package/dist/domains/traces/components/span-details-view.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-error-renderer.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-error-renderer.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-input-renderers.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-input-renderers.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-output-renderers.cjs.js +3 -3
- package/dist/domains/traces/components/span-payload/span-output-renderers.es.js +3 -3
- package/dist/domains/traces/components/span-payload/span-payload-messages.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-messages.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-primitives.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-primitives.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-processor.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-processor.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-registry.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-registry.es.js.map +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-section.cjs.js +3 -3
- package/dist/domains/traces/components/span-payload/span-payload-section.es.js +3 -3
- package/dist/domains/traces/components/span-payload/span-payload-tool.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-tool.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-processor-attributes.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-processor-attributes.es.js +2 -2
- package/dist/domains/traces/components/span-rows.cjs.js +5 -0
- package/dist/domains/traces/components/span-rows.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-rows.es.js +5 -0
- package/dist/domains/traces/components/span-rows.es.js.map +1 -1
- package/dist/domains/traces/components/span-summary-description.cjs.js +1 -1
- package/dist/domains/traces/components/span-summary-description.es.js +1 -1
- package/dist/domains/traces/components/span-timeline-row.cjs.js +34 -28
- package/dist/domains/traces/components/span-timeline-row.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-timeline-row.es.js +34 -28
- package/dist/domains/traces/components/span-timeline-row.es.js.map +1 -1
- package/dist/domains/traces/components/span-timing-hover-card.cjs.js +1 -1
- package/dist/domains/traces/components/span-timing-hover-card.es.js +1 -1
- package/dist/domains/traces/components/span-token-usage.cjs.js +1 -1
- package/dist/domains/traces/components/span-token-usage.es.js +1 -1
- package/dist/domains/traces/components/span-tree-rail.cjs.js +50 -0
- package/dist/domains/traces/components/span-tree-rail.cjs.js.map +1 -0
- package/dist/domains/traces/components/span-tree-rail.d.ts +2 -0
- package/dist/domains/traces/components/span-tree-rail.es.js +42 -0
- package/dist/domains/traces/components/span-tree-rail.es.js.map +1 -0
- package/dist/domains/traces/components/span-tree-row.cjs.js +2 -2
- package/dist/domains/traces/components/span-tree-row.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-tree-row.es.js +2 -2
- package/dist/domains/traces/components/span-tree-row.es.js.map +1 -1
- package/dist/domains/traces/components/span-type-badge.cjs.js +29 -0
- package/dist/domains/traces/components/span-type-badge.cjs.js.map +1 -0
- package/dist/domains/traces/components/span-type-badge.d.ts +2 -0
- package/dist/domains/traces/components/span-type-badge.es.js +25 -0
- package/dist/domains/traces/components/span-type-badge.es.js.map +1 -0
- package/dist/domains/traces/components/span-type-legend.cjs.js +2 -2
- package/dist/domains/traces/components/span-type-legend.cjs.js.map +1 -1
- package/dist/domains/traces/components/span-type-legend.es.js +2 -2
- package/dist/domains/traces/components/span-type-legend.es.js.map +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-details.cjs.js +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-details.es.js +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-messages.cjs.js +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-messages.es.js +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-row.cjs.js.map +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-row.es.js.map +1 -1
- package/dist/domains/traces/components/thread-trace/thread-trace-spans.cjs.js +2 -2
- package/dist/domains/traces/components/thread-trace/thread-trace-spans.es.js +2 -2
- package/dist/domains/traces/components/thread-view-by-trace.cjs.js +2 -1
- package/dist/domains/traces/components/thread-view-by-trace.cjs.js.map +1 -1
- package/dist/domains/traces/components/thread-view-by-trace.es.js +2 -1
- package/dist/domains/traces/components/thread-view-by-trace.es.js.map +1 -1
- package/dist/domains/traces/components/timeline-name-col.cjs.js +53 -27
- package/dist/domains/traces/components/timeline-name-col.cjs.js.map +1 -1
- package/dist/domains/traces/components/timeline-name-col.es.js +54 -28
- package/dist/domains/traces/components/timeline-name-col.es.js.map +1 -1
- package/dist/domains/traces/components/timeline-structure-sign.cjs.js +23 -14
- package/dist/domains/traces/components/timeline-structure-sign.cjs.js.map +1 -1
- package/dist/domains/traces/components/timeline-structure-sign.es.js +24 -15
- package/dist/domains/traces/components/timeline-structure-sign.es.js.map +1 -1
- package/dist/domains/traces/components/trace-columns-menu.cjs.js +4 -4
- package/dist/domains/traces/components/trace-columns-menu.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-columns-menu.es.js +4 -4
- package/dist/domains/traces/components/trace-columns-menu.es.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +32 -5
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +32 -5
- package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel.cjs.js +5 -2
- package/dist/domains/traces/components/trace-data-panel.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel.es.js +5 -2
- package/dist/domains/traces/components/trace-data-panel.es.js.map +1 -1
- package/dist/domains/traces/components/trace-error-cell.cjs.js +35 -0
- package/dist/domains/traces/components/trace-error-cell.cjs.js.map +1 -0
- package/dist/domains/traces/components/trace-error-cell.d.ts +2 -0
- package/dist/domains/traces/components/trace-error-cell.es.js +31 -0
- package/dist/domains/traces/components/trace-error-cell.es.js.map +1 -0
- package/dist/domains/traces/components/trace-error-details.cjs.js +22 -0
- package/dist/domains/traces/components/trace-error-details.cjs.js.map +1 -0
- package/dist/domains/traces/components/trace-error-details.d.ts +2 -0
- package/dist/domains/traces/components/trace-error-details.es.js +18 -0
- package/dist/domains/traces/components/trace-error-details.es.js.map +1 -0
- package/dist/domains/traces/components/trace-error-summary.cjs.js +31 -0
- package/dist/domains/traces/components/trace-error-summary.cjs.js.map +1 -0
- package/dist/domains/traces/components/trace-error-summary.d.ts +2 -0
- package/dist/domains/traces/components/trace-error-summary.es.js +27 -0
- package/dist/domains/traces/components/trace-error-summary.es.js.map +1 -0
- package/dist/domains/traces/components/trace-id-button.cjs.js +1 -1
- package/dist/domains/traces/components/trace-id-button.es.js +1 -1
- package/dist/domains/traces/components/trace-span-panel.cjs.js +1 -1
- package/dist/domains/traces/components/trace-span-panel.es.js +1 -1
- package/dist/domains/traces/components/trace-span-tree-skeleton.cjs.js +7 -7
- package/dist/domains/traces/components/trace-span-tree-skeleton.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-span-tree-skeleton.es.js +7 -7
- package/dist/domains/traces/components/trace-span-tree-skeleton.es.js.map +1 -1
- package/dist/domains/traces/components/trace-span-tree.cjs.js +1 -2
- package/dist/domains/traces/components/trace-span-tree.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-span-tree.es.js +2 -3
- package/dist/domains/traces/components/trace-span-tree.es.js.map +1 -1
- package/dist/domains/traces/components/trace-summary-description.cjs.js +1 -1
- package/dist/domains/traces/components/trace-summary-description.es.js +1 -1
- package/dist/domains/traces/components/trace-thread-item-view.cjs.js +1 -1
- package/dist/domains/traces/components/trace-thread-item-view.es.js +1 -1
- package/dist/domains/traces/components/trace-thread-panel.cjs.js +1 -1
- package/dist/domains/traces/components/trace-thread-panel.es.js +1 -1
- package/dist/domains/traces/components/trace-time-range-chip.cjs.js +2 -2
- package/dist/domains/traces/components/trace-time-range-chip.es.js +2 -2
- package/dist/domains/traces/components/traces-list-mode-toggle.cjs.js +1 -1
- package/dist/domains/traces/components/traces-list-mode-toggle.es.js +1 -1
- package/dist/domains/traces/components/traces-list-view.cjs.js +10 -7
- package/dist/domains/traces/components/traces-list-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/traces-list-view.es.js +9 -6
- package/dist/domains/traces/components/traces-list-view.es.js.map +1 -1
- package/dist/domains/traces/components/traces-page-skeleton.cjs.js +4 -1
- package/dist/domains/traces/components/traces-page-skeleton.cjs.js.map +1 -1
- package/dist/domains/traces/components/traces-page-skeleton.es.js +4 -1
- package/dist/domains/traces/components/traces-page-skeleton.es.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-list-navigation.cjs.js.map +1 -1
- package/dist/domains/traces/hooks/use-trace-list-navigation.es.js.map +1 -1
- package/dist/domains/traces/utils/flatten-to-search-text.cjs.js.map +1 -1
- package/dist/domains/traces/utils/flatten-to-search-text.es.js.map +1 -1
- package/dist/domains/workflows/components/workflow-combobox.cjs.js +1 -1
- package/dist/domains/workflows/components/workflow-combobox.es.js +1 -1
- package/dist/domains/workflows/components/workflow-information.cjs.js +1 -1
- package/dist/domains/workflows/components/workflow-information.es.js +1 -1
- package/dist/domains/workflows/components/workflow-step-detail.cjs.js +3 -3
- package/dist/domains/workflows/components/workflow-step-detail.es.js +3 -3
- package/dist/domains/workflows/components/workflows-list/no-workflows-info.cjs.js +1 -1
- package/dist/domains/workflows/components/workflows-list/no-workflows-info.es.js +1 -1
- package/dist/domains/workflows/components/workflows-list/workflows-list.cjs.js +2 -2
- package/dist/domains/workflows/components/workflows-list/workflows-list.es.js +2 -2
- package/dist/domains/workflows/runs/workflow-run-list.cjs.js +2 -2
- package/dist/domains/workflows/runs/workflow-run-list.es.js +2 -2
- package/dist/domains/workflows/workflow/data/workflow-data-button.cjs.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-button.es.js +1 -1
- package/dist/domains/workflows/workflow/data/workflow-data-inspector.cjs.js +2 -2
- package/dist/domains/workflows/workflow/data/workflow-data-inspector.es.js +2 -2
- package/dist/domains/workflows/workflow/input/workflow-json-input.cjs.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-json-input.es.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-processor-input.cjs.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-processor-input.es.js +1 -1
- package/dist/domains/workflows/workflow/use-workflow-graph-runtime.cjs.js +2 -2
- package/dist/domains/workflows/workflow/use-workflow-graph-runtime.es.js +2 -2
- package/dist/domains/workflows/workflow/workflow-body-graph.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-body-graph.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-cancel-button.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-cancel-button.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-data-edge.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-data-edge.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-debug-step-controls.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-debug-step-controls.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-graph-boundary.cjs.js +3 -3
- package/dist/domains/workflows/workflow/workflow-graph-boundary.es.js +3 -3
- package/dist/domains/workflows/workflow/workflow-graph-inner.cjs.js +2 -2
- package/dist/domains/workflows/workflow/workflow-graph-inner.es.js +2 -2
- package/dist/domains/workflows/workflow/workflow-graph-node.cjs.js +2 -2
- package/dist/domains/workflows/workflow/workflow-graph-node.es.js +2 -2
- package/dist/domains/workflows/workflow/workflow-input-data.cjs.js +1 -2
- package/dist/domains/workflows/workflow/workflow-input-data.cjs.js.map +1 -1
- package/dist/domains/workflows/workflow/workflow-input-data.es.js +1 -2
- package/dist/domains/workflows/workflow/workflow-input-data.es.js.map +1 -1
- package/dist/domains/workflows/workflow/workflow-map-config-dialog.cjs.js +3 -3
- package/dist/domains/workflows/workflow/workflow-map-config-dialog.es.js +3 -3
- package/dist/domains/workflows/workflow/workflow-nested-graph.cjs.js +3 -3
- package/dist/domains/workflows/workflow/workflow-nested-graph.es.js +3 -3
- package/dist/domains/workflows/workflow/workflow-run-data.cjs.js +2 -2
- package/dist/domains/workflows/workflow/workflow-run-data.es.js +2 -2
- package/dist/domains/workflows/workflow/workflow-run-header.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-run-header.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-status.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-status.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-step-action-bar.cjs.js +3 -3
- package/dist/domains/workflows/workflow/workflow-step-action-bar.es.js +3 -3
- package/dist/domains/workflows/workflow/workflow-suspended-steps.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-suspended-steps.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-time-travel-form.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-time-travel-form.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-timeline-row.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-timeline-row.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-timeline.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-timeline.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-trigger-form.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-trigger-form.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-trigger-header.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-trigger-header.es.js +1 -1
- package/dist/domains/workspace/components/workspace-active-file.cjs.js +1 -1
- package/dist/domains/workspace/components/workspace-active-file.es.js +1 -1
- package/dist/domains/workspace/components/workspace-add-skill-dialog.cjs.js +5 -5
- package/dist/domains/workspace/components/workspace-add-skill-dialog.es.js +5 -5
- package/dist/domains/workspace/components/workspace-add-skill.cjs.js +1 -1
- package/dist/domains/workspace/components/workspace-add-skill.es.js +1 -1
- package/dist/domains/workspace/components/workspace-create-directory.cjs.js +2 -2
- package/dist/domains/workspace/components/workspace-create-directory.es.js +2 -2
- package/dist/domains/workspace/components/workspace-markdown-preview.cjs.js +2 -2
- package/dist/domains/workspace/components/workspace-markdown-preview.es.js +2 -2
- package/dist/domains/workspace/components/workspace-search.cjs.js +1 -1
- package/dist/domains/workspace/components/workspace-search.es.js +1 -1
- package/dist/domains/workspace/components/workspace-tree.cjs.js +2 -2
- package/dist/domains/workspace/components/workspace-tree.es.js +2 -2
- package/dist/{drawer-DROYPMUm.cjs → drawer-DdTU-nBR.cjs} +2 -2
- package/dist/{drawer-DROYPMUm.cjs.map → drawer-DdTU-nBR.cjs.map} +1 -1
- package/dist/{drawer-C-8E9yHN.js → drawer-mj-G7-Tu.js} +2 -2
- package/dist/{drawer-C-8E9yHN.js.map → drawer-mj-G7-Tu.js.map} +1 -1
- package/dist/dropdown-menu-CQ_48tVI.js.map +1 -1
- package/dist/dropdown-menu-CsynT1aD.cjs.map +1 -1
- package/dist/ee/signals/components/entity-index-list.cjs.js +3 -1
- package/dist/ee/signals/components/entity-index-list.cjs.js.map +1 -1
- package/dist/ee/signals/components/entity-index-list.es.js +3 -1
- package/dist/ee/signals/components/entity-index-list.es.js.map +1 -1
- package/dist/ee/signals/components/signals-empty-state.cjs.js +1 -1
- package/dist/ee/signals/components/signals-empty-state.es.js +1 -1
- package/dist/ee/signals/components/trace-intelligence-entity-detail.cjs.js.map +1 -1
- package/dist/ee/signals/components/trace-intelligence-entity-detail.es.js.map +1 -1
- package/dist/ee/signals/components/trace-intelligence-entity-index.cjs.js +6 -4
- package/dist/ee/signals/components/trace-intelligence-entity-index.cjs.js.map +1 -1
- package/dist/ee/signals/components/trace-intelligence-entity-index.es.js +6 -4
- package/dist/ee/signals/components/trace-intelligence-entity-index.es.js.map +1 -1
- package/dist/ee/signals/examples-pager.cjs.js +1 -1
- package/dist/ee/signals/examples-pager.es.js +1 -1
- package/dist/ee/signals/noise-detail-panel.cjs.js +1 -1
- package/dist/ee/signals/noise-detail-panel.es.js +1 -1
- package/dist/ee/signals/settings/signal-definition-form-dialog.cjs.js +2 -2
- package/dist/ee/signals/settings/signal-definition-form-dialog.es.js +2 -2
- package/dist/ee/signals/settings/trace-signal-settings.cjs.js +1 -1
- package/dist/ee/signals/settings/trace-signal-settings.es.js +1 -1
- package/dist/ee/signals/signals-error-state.cjs.js +1 -1
- package/dist/ee/signals/signals-error-state.es.js +1 -1
- package/dist/ee/signals/snapshot-timeline.cjs.js +1 -1
- package/dist/ee/signals/snapshot-timeline.es.js +1 -1
- package/dist/ee/signals/theme-detail-panel.cjs.js +1 -1
- package/dist/ee/signals/theme-detail-panel.es.js +1 -1
- package/dist/ee/signals/theme-filter-banner.cjs.js +1 -1
- package/dist/ee/signals/theme-filter-banner.es.js +1 -1
- package/dist/ee/signals/trace-insight-view.cjs.js +1 -1
- package/dist/ee/signals/trace-insight-view.es.js +1 -1
- package/dist/ee/signals/trace-intelligence-provider.cjs.js.map +1 -1
- package/dist/ee/signals/trace-intelligence-provider.es.js.map +1 -1
- package/dist/ee/signals/view-mode-tab.cjs.js +1 -1
- package/dist/ee/signals/view-mode-tab.es.js +1 -1
- package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +3 -3
- package/dist/ee/topics/components/topic-trace-summary-list.es.js +3 -3
- package/dist/{field-error-id-Dbe6IInA.cjs → field-error-id-0yYYU0ar.cjs} +2 -2
- package/dist/{field-error-id-Dbe6IInA.cjs.map → field-error-id-0yYYU0ar.cjs.map} +1 -1
- package/dist/{field-error-id-Sqhk00e4.js → field-error-id-CdzuQK5c.js} +2 -2
- package/dist/{field-error-id-Sqhk00e4.js.map → field-error-id-CdzuQK5c.js.map} +1 -1
- package/dist/{filter-bar-chip-BarAq1S2.js → filter-bar-chip-C9CXOudu.js} +3 -3
- package/dist/filter-bar-chip-C9CXOudu.js.map +1 -0
- package/dist/{filter-bar-chip-BJJ6ytJ4.cjs → filter-bar-chip-DgvuQv6c.cjs} +3 -3
- package/dist/filter-bar-chip-DgvuQv6c.cjs.map +1 -0
- package/dist/hooks/use-environment-variables-editor.cjs.js.map +1 -1
- package/dist/hooks/use-environment-variables-editor.es.js.map +1 -1
- package/dist/hooks/use-fluid-hover.cjs.js.map +1 -1
- package/dist/hooks/use-fluid-hover.es.js.map +1 -1
- package/dist/icons/Icon.cjs.js.map +1 -1
- package/dist/icons/Icon.es.js.map +1 -1
- package/dist/icons/SkillIcon.cjs.js.map +1 -1
- package/dist/icons/SkillIcon.es.js.map +1 -1
- package/dist/icons/icon-size-classes.cjs.js +4 -4
- package/dist/icons/icon-size-classes.cjs.js.map +1 -1
- package/dist/icons/icon-size-classes.es.js +4 -4
- package/dist/icons/icon-size-classes.es.js.map +1 -1
- package/dist/{input-group-CiBbTaPP.js → input-group-BAg6iSIe.js} +2 -2
- package/dist/{input-group-CiBbTaPP.js.map → input-group-BAg6iSIe.js.map} +1 -1
- package/dist/{input-group-DSW5WoSU.cjs → input-group-DRXUthxe.cjs} +2 -2
- package/dist/{input-group-DSW5WoSU.cjs.map → input-group-DRXUthxe.cjs.map} +1 -1
- package/dist/keyboard/keyboard-dispatcher.cjs.js +2 -4
- package/dist/keyboard/keyboard-dispatcher.cjs.js.map +1 -1
- package/dist/keyboard/keyboard-dispatcher.es.js +2 -4
- package/dist/keyboard/keyboard-dispatcher.es.js.map +1 -1
- package/dist/keyboard/keyboard-shortcuts-context.cjs.js.map +1 -1
- package/dist/keyboard/keyboard-shortcuts-context.es.js.map +1 -1
- package/dist/keyboard/use-keydown.cjs.js +2 -0
- package/dist/keyboard/use-keydown.cjs.js.map +1 -1
- package/dist/keyboard/use-keydown.es.js +2 -0
- package/dist/keyboard/use-keydown.es.js.map +1 -1
- package/dist/layout/tabbed-container.cjs.js +4 -4
- package/dist/layout/tabbed-container.es.js +4 -4
- package/dist/lib/form/components/array-element-wrapper.cjs.js +1 -1
- package/dist/lib/form/components/array-element-wrapper.es.js +1 -1
- package/dist/lib/form/components/array-wrapper.cjs.js +1 -1
- package/dist/lib/form/components/array-wrapper.es.js +1 -1
- package/dist/lib/form/components/date-field.cjs.js +1 -1
- package/dist/lib/form/components/date-field.es.js +1 -1
- package/dist/lib/form/components/form-submit-row.cjs.js +1 -1
- package/dist/lib/form/components/form-submit-row.es.js +1 -1
- package/dist/lib/form/components/record-field.cjs.js +1 -1
- package/dist/lib/form/components/record-field.es.js +1 -1
- package/dist/lib/form/components/select-field.cjs.js +1 -1
- package/dist/lib/form/components/select-field.es.js +1 -1
- package/dist/lib/form/components/submit-button.cjs.js +1 -1
- package/dist/lib/form/components/submit-button.es.js +1 -1
- package/dist/lib/form/zod-provider.cjs.js.map +1 -1
- package/dist/lib/form/zod-provider.es.js.map +1 -1
- package/dist/{list-search-D3I6xt0B.js → list-search-ByJdIxIh.js} +2 -2
- package/dist/{list-search-D3I6xt0B.js.map → list-search-ByJdIxIh.js.map} +1 -1
- package/dist/{list-search-DHiQ1-O6.cjs → list-search-DNJVeHmK.cjs} +2 -2
- package/dist/{list-search-DHiQ1-O6.cjs.map → list-search-DNJVeHmK.cjs.map} +1 -1
- package/dist/{logs-data-list-Cb85LPcT.js → logs-data-list-CGerYgSd.js} +2 -3
- package/dist/{logs-data-list-Cb85LPcT.js.map → logs-data-list-CGerYgSd.js.map} +1 -1
- package/dist/{logs-data-list-DlQxxrNw.cjs → logs-data-list-DEZuSjqt.cjs} +21 -22
- package/dist/{logs-data-list-DlQxxrNw.cjs.map → logs-data-list-DEZuSjqt.cjs.map} +1 -1
- package/dist/{markdown-renderer-HIfFphpI.cjs → markdown-renderer-BcpwvSl9.cjs} +3 -3
- package/dist/{markdown-renderer-HIfFphpI.cjs.map → markdown-renderer-BcpwvSl9.cjs.map} +1 -1
- package/dist/{markdown-renderer-BYxWiHRj.js → markdown-renderer-CHLpv5n5.js} +3 -3
- package/dist/{markdown-renderer-BYxWiHRj.js.map → markdown-renderer-CHLpv5n5.js.map} +1 -1
- package/dist/{message-copy-button-CnVgCy9y.cjs → message-copy-button-D3O4hWDV.cjs} +2 -2
- package/dist/{message-copy-button-CnVgCy9y.cjs.map → message-copy-button-D3O4hWDV.cjs.map} +1 -1
- package/dist/{message-copy-button-Ctew41Rr.js → message-copy-button-OI1mwAaS.js} +2 -2
- package/dist/{message-copy-button-Ctew41Rr.js.map → message-copy-button-OI1mwAaS.js.map} +1 -1
- package/dist/{metrics-card-DaFApxZY.cjs → metrics-card-CpjGYNBP.cjs} +2 -2
- package/dist/{metrics-card-DaFApxZY.cjs.map → metrics-card-CpjGYNBP.cjs.map} +1 -1
- package/dist/{metrics-card-Z_moDiV5.js → metrics-card-D6ty6a6Z.js} +2 -2
- package/dist/{metrics-card-Z_moDiV5.js.map → metrics-card-D6ty6a6Z.js.map} +1 -1
- package/dist/{notification-activity-MR63WqZm.cjs → notification-activity-BSNuqJDd.cjs} +2 -2
- package/dist/{notification-activity-MR63WqZm.cjs.map → notification-activity-BSNuqJDd.cjs.map} +1 -1
- package/dist/{notification-activity-FJcMFxIj.js → notification-activity-BWXHmlTn.js} +2 -2
- package/dist/{notification-activity-FJcMFxIj.js.map → notification-activity-BWXHmlTn.js.map} +1 -1
- package/dist/{plan-BoOK_LAB.cjs → plan-Cm3yHvs3.cjs} +4 -4
- package/dist/{plan-BoOK_LAB.cjs.map → plan-Cm3yHvs3.cjs.map} +1 -1
- package/dist/{plan-m0hj6Zgv.js → plan-TtrepVnQ.js} +4 -4
- package/dist/{plan-m0hj6Zgv.js.map → plan-TtrepVnQ.js.map} +1 -1
- package/dist/primitives/form-element.cjs.js.map +1 -1
- package/dist/primitives/form-element.es.js.map +1 -1
- package/dist/primitives/menu-item.cjs.js +4 -2
- package/dist/primitives/menu-item.cjs.js.map +1 -1
- package/dist/primitives/menu-item.es.js +4 -2
- package/dist/primitives/menu-item.es.js.map +1 -1
- package/dist/primitives/popup-anchor.cjs.js +34 -0
- package/dist/primitives/popup-anchor.cjs.js.map +1 -0
- package/dist/primitives/popup-anchor.d.ts +2 -0
- package/dist/primitives/popup-anchor.es.js +10 -0
- package/dist/primitives/popup-anchor.es.js.map +1 -0
- package/dist/primitives/trigger-button.cjs.js +1 -1
- package/dist/primitives/trigger-button.es.js +1 -1
- package/dist/{property-filter-applied-J9ob_Rss.js → property-filter-applied-BMmMf4DE.js} +2 -2
- package/dist/property-filter-applied-BMmMf4DE.js.map +1 -0
- package/dist/{property-filter-applied-CtSglSaH.cjs → property-filter-applied-Bj-bh9gv.cjs} +2 -2
- package/dist/property-filter-applied-Bj-bh9gv.cjs.map +1 -0
- package/dist/{reasoning-activity-5MFE3mzw.js → reasoning-activity-C-sJt2A9.js} +3 -3
- package/dist/{reasoning-activity-5MFE3mzw.js.map → reasoning-activity-C-sJt2A9.js.map} +1 -1
- package/dist/{reasoning-activity-DMvughvN.cjs → reasoning-activity-DpYFjxuL.cjs} +3 -3
- package/dist/{reasoning-activity-DMvughvN.cjs.map → reasoning-activity-DpYFjxuL.cjs.map} +1 -1
- package/dist/resize/panel-drawer.cjs.js +1 -1
- package/dist/resize/panel-drawer.es.js +1 -1
- package/dist/{search-input-BPqubJZC.js → search-input-C9qFBzn6.js} +2 -2
- package/dist/{search-input-BPqubJZC.js.map → search-input-C9qFBzn6.js.map} +1 -1
- package/dist/{search-input-BUMYRaUW.cjs → search-input-CMNy0JWd.cjs} +2 -2
- package/dist/{search-input-BUMYRaUW.cjs.map → search-input-CMNy0JWd.cjs.map} +1 -1
- package/dist/section-CctlZIXp.cjs.map +1 -1
- package/dist/section-D0hKTVXt.js.map +1 -1
- package/dist/{select-CQtsggxJ.js → select-7rYaECQf.js} +2 -2
- package/dist/select-7rYaECQf.js.map +1 -0
- package/dist/{select-CbNLtiAs.cjs → select-A3AFKLd9.cjs} +2 -2
- package/dist/select-A3AFKLd9.cjs.map +1 -0
- package/dist/shimmer-BCSr3Rqf.js.map +1 -1
- package/dist/shimmer-Co-XPvF9.cjs.map +1 -1
- package/dist/{side-dialog-bm8NPDXy.js → side-dialog-DSvj8H6x.js} +4 -4
- package/dist/{side-dialog-bm8NPDXy.js.map → side-dialog-DSvj8H6x.js.map} +1 -1
- package/dist/{side-dialog-BzULMBaH.cjs → side-dialog-SJCWBnbw.cjs} +4 -4
- package/dist/{side-dialog-BzULMBaH.cjs.map → side-dialog-SJCWBnbw.cjs.map} +1 -1
- package/dist/{signal-activity-D-_u7DFm.cjs → signal-activity-C_bihjcd.cjs} +2 -2
- package/dist/{signal-activity-D-_u7DFm.cjs.map → signal-activity-C_bihjcd.cjs.map} +1 -1
- package/dist/{signal-activity-BkFexFiJ.js → signal-activity-J9kpnwAF.js} +2 -2
- package/dist/{signal-activity-BkFexFiJ.js.map → signal-activity-J9kpnwAF.js.map} +1 -1
- package/dist/{span-payload-primitives-wujxDKfA.cjs → span-payload-primitives-C0KYtmtV.cjs} +3 -3
- package/dist/{span-payload-primitives-wujxDKfA.cjs.map → span-payload-primitives-C0KYtmtV.cjs.map} +1 -1
- package/dist/{span-payload-primitives-jQiJK0qI.js → span-payload-primitives-D_N9LeLk.js} +3 -3
- package/dist/{span-payload-primitives-jQiJK0qI.js.map → span-payload-primitives-D_N9LeLk.js.map} +1 -1
- package/dist/src/domains/traces/components/span-rows.d.ts +2 -0
- package/dist/src/domains/traces/components/span-tree-rail.d.ts +23 -0
- package/dist/src/domains/traces/components/span-type-badge.d.ts +9 -0
- package/dist/src/domains/traces/components/timeline-name-col.d.ts +2 -2
- package/dist/src/domains/traces/components/timeline-structure-sign.d.ts +14 -1
- package/dist/src/domains/traces/components/trace-error-cell.d.ts +8 -0
- package/dist/src/domains/traces/components/trace-error-details.d.ts +10 -0
- package/dist/src/domains/traces/components/trace-error-summary.d.ts +8 -0
- package/dist/src/domains/traces/components/trace-span-tree-skeleton.d.ts +1 -1
- package/dist/src/domains/traces/hooks/use-traces-list-source.d.ts +1 -0
- package/dist/src/ds/components/Avatar/avatar-size.d.ts +1 -1
- package/dist/src/ds/components/Breadcrumb/crumb-switcher.d.ts +0 -1
- package/dist/src/ds/components/Button/Button.d.ts +1 -1
- package/dist/src/ds/components/EnvironmentVariablesEditor/environment-variables-editor-context.d.ts +1 -2
- package/dist/src/ds/components/SavedViews/saved-view-editor.d.ts +1 -1
- package/dist/src/ds/components/Select/select.d.ts +1 -1
- package/dist/src/ds/primitives/popup-anchor.d.ts +4 -0
- package/dist/src/hooks/use-environment-variables-editor.d.ts +1 -1
- package/dist/src/lib/keyboard/keyboard-dispatcher.d.ts +2 -0
- package/dist/src/lib/keyboard/use-keydown.d.ts +8 -1
- package/dist/style.css +121 -143
- package/dist/{tabs-tab-DRaRUvQ3.cjs → tabs-tab-B0W25Dm2.cjs} +2 -2
- package/dist/{tabs-tab-DRaRUvQ3.cjs.map → tabs-tab-B0W25Dm2.cjs.map} +1 -1
- package/dist/{tabs-tab-CIVJEMoY.js → tabs-tab-CkLyKrL0.js} +2 -2
- package/dist/{tabs-tab-CIVJEMoY.js.map → tabs-tab-CkLyKrL0.js.map} +1 -1
- package/dist/{thread-list-BANpytn3.cjs → thread-list-BBPZYHh8.cjs} +2 -2
- package/dist/thread-list-BBPZYHh8.cjs.map +1 -0
- package/dist/{thread-list-lXnXsPul.js → thread-list-BGjKZfEH.js} +2 -2
- package/dist/thread-list-BGjKZfEH.js.map +1 -0
- package/dist/{time-picker-BpCfTfoe.js → time-picker-Bzdboi4W.js} +2 -2
- package/dist/{time-picker-BpCfTfoe.js.map → time-picker-Bzdboi4W.js.map} +1 -1
- package/dist/{time-picker-DhekkO5t.cjs → time-picker-CyvG-fwX.cjs} +2 -2
- package/dist/{time-picker-DhekkO5t.cjs.map → time-picker-CyvG-fwX.cjs.map} +1 -1
- package/dist/{tool-approval-BrqoN_mP.js → tool-approval-P8rUFAYp.js} +4 -4
- package/dist/{tool-approval-BrqoN_mP.js.map → tool-approval-P8rUFAYp.js.map} +1 -1
- package/dist/{tool-approval-zBfJ20iR.cjs → tool-approval-zhWdp8i6.cjs} +4 -4
- package/dist/{tool-approval-zBfJ20iR.cjs.map → tool-approval-zhWdp8i6.cjs.map} +1 -1
- package/dist/{tool-call-arguments-DwMeGQHD.cjs → tool-call-arguments-DzpFckIm.cjs} +3 -3
- package/dist/{tool-call-arguments-DwMeGQHD.cjs.map → tool-call-arguments-DzpFckIm.cjs.map} +1 -1
- package/dist/{tool-call-arguments-Dx4LW1Ni.js → tool-call-arguments-goEdIs4f.js} +3 -3
- package/dist/{tool-call-arguments-Dx4LW1Ni.js.map → tool-call-arguments-goEdIs4f.js.map} +1 -1
- package/dist/{tool-call-group-DJsiIb-B.cjs → tool-call-group-C56oARyx.cjs} +4 -4
- package/dist/tool-call-group-C56oARyx.cjs.map +1 -0
- package/dist/{tool-call-group-ZDNZog5K.js → tool-call-group-DU4T72Xn.js} +4 -4
- package/dist/tool-call-group-DU4T72Xn.js.map +1 -0
- package/dist/{tool-call-mono-Bs7y-1Cq.js → tool-call-mono-DPW6hN91.js} +2 -2
- package/dist/{tool-call-mono-Bs7y-1Cq.js.map → tool-call-mono-DPW6hN91.js.map} +1 -1
- package/dist/{tool-call-mono-I-vdqzCe.cjs → tool-call-mono-aheL8CkL.cjs} +2 -2
- package/dist/{tool-call-mono-I-vdqzCe.cjs.map → tool-call-mono-aheL8CkL.cjs.map} +1 -1
- package/dist/{tool-call-output-Dd8zlhLd.js → tool-call-output-BQYzMMMi.js} +2 -2
- package/dist/{tool-call-output-Dd8zlhLd.js.map → tool-call-output-BQYzMMMi.js.map} +1 -1
- package/dist/{tool-call-output-BrNg0Lkd.cjs → tool-call-output-CuwM5IHd.cjs} +2 -2
- package/dist/{tool-call-output-BrNg0Lkd.cjs.map → tool-call-output-CuwM5IHd.cjs.map} +1 -1
- package/dist/{tool-card-D4yrR2AE.js → tool-card-aclA3iVz.js} +4 -4
- package/dist/{tool-card-D4yrR2AE.js.map → tool-card-aclA3iVz.js.map} +1 -1
- package/dist/{tool-card-D6UdNzIX.cjs → tool-card-yii3vGHu.cjs} +4 -4
- package/dist/{tool-card-D6UdNzIX.cjs.map → tool-card-yii3vGHu.cjs.map} +1 -1
- package/dist/{traces-data-list-Bhhg9drs.cjs → traces-data-list-Co9k5J4f.cjs} +18 -20
- package/dist/{traces-data-list-Bhhg9drs.cjs.map → traces-data-list-Co9k5J4f.cjs.map} +1 -1
- package/dist/{traces-data-list-DMWPJFBc.js → traces-data-list-TCKjOldO.js} +2 -4
- package/dist/{traces-data-list-DMWPJFBc.js.map → traces-data-list-TCKjOldO.js.map} +1 -1
- package/dist/use-data-list-keyboard-DF3tLe10.cjs.map +1 -1
- package/dist/use-data-list-keyboard-DFQr4t38.js.map +1 -1
- package/dist/{use-workflow-graph-runtime-DF-56pIR.cjs → use-workflow-graph-runtime-DcQD5eA6.cjs} +3 -3
- package/dist/{use-workflow-graph-runtime-DF-56pIR.cjs.map → use-workflow-graph-runtime-DcQD5eA6.cjs.map} +1 -1
- package/dist/{use-workflow-graph-runtime-BrHXo49Q.js → use-workflow-graph-runtime-xq_aSXPh.js} +3 -3
- package/dist/{use-workflow-graph-runtime-BrHXo49Q.js.map → use-workflow-graph-runtime-xq_aSXPh.js.map} +1 -1
- package/dist/utils/workspace-compat.cjs.js.map +1 -1
- package/dist/utils/workspace-compat.es.js.map +1 -1
- package/dist/{workflow-code-dialog-content-CfVy6bGG.cjs → workflow-code-dialog-content-B_BQCuFW.cjs} +3 -3
- package/dist/{workflow-code-dialog-content-CfVy6bGG.cjs.map → workflow-code-dialog-content-B_BQCuFW.cjs.map} +1 -1
- package/dist/{workflow-code-dialog-content-DviJz1jB.js → workflow-code-dialog-content-CFEaeYUX.js} +3 -3
- package/dist/{workflow-code-dialog-content-DviJz1jB.js.map → workflow-code-dialog-content-CFEaeYUX.js.map} +1 -1
- package/dist/{workflow-condition-card-BRwhMmNO.cjs → workflow-condition-card-CMzoK307.cjs} +3 -3
- package/dist/{workflow-condition-card-BRwhMmNO.cjs.map → workflow-condition-card-CMzoK307.cjs.map} +1 -1
- package/dist/{workflow-condition-card-sFdOjlab.js → workflow-condition-card-CbQ4fCxY.js} +3 -3
- package/dist/{workflow-condition-card-sFdOjlab.js.map → workflow-condition-card-CbQ4fCxY.js.map} +1 -1
- package/dist/{workflow-data-edge-view-DpPhr9gZ.cjs → workflow-data-edge-view-0utEB4Yb.cjs} +2 -2
- package/dist/{workflow-data-edge-view-DpPhr9gZ.cjs.map → workflow-data-edge-view-0utEB4Yb.cjs.map} +1 -1
- package/dist/{workflow-data-edge-view-CuSzc6YI.js → workflow-data-edge-view-gwwJEvXz.js} +2 -2
- package/dist/{workflow-data-edge-view-CuSzc6YI.js.map → workflow-data-edge-view-gwwJEvXz.js.map} +1 -1
- package/dist/{workflow-debug-controls-CAn_6S8K.cjs → workflow-debug-controls-B5zqE_rm.cjs} +2 -2
- package/dist/{workflow-debug-controls-CAn_6S8K.cjs.map → workflow-debug-controls-B5zqE_rm.cjs.map} +1 -1
- package/dist/{workflow-debug-controls-CLzbxd5O.js → workflow-debug-controls-CPpdNzD9.js} +2 -2
- package/dist/{workflow-debug-controls-CLzbxd5O.js.map → workflow-debug-controls-CPpdNzD9.js.map} +1 -1
- package/dist/{workflow-edge-data-button-Dtt_OUz9.js → workflow-edge-data-button-YWjfx-W0.js} +4 -4
- package/dist/{workflow-edge-data-button-Dtt_OUz9.js.map → workflow-edge-data-button-YWjfx-W0.js.map} +1 -1
- package/dist/{workflow-edge-data-button-B8rQaAoK.cjs → workflow-edge-data-button-tDvziS5v.cjs} +4 -4
- package/dist/{workflow-edge-data-button-B8rQaAoK.cjs.map → workflow-edge-data-button-tDvziS5v.cjs.map} +1 -1
- package/dist/{workflow-step-action-DqFjktfs.js → workflow-step-action-D8MVfEIl.js} +2 -2
- package/dist/{workflow-step-action-DqFjktfs.js.map → workflow-step-action-D8MVfEIl.js.map} +1 -1
- package/dist/{workflow-step-action-Cu01omgz.cjs → workflow-step-action-DZgS0_fL.cjs} +2 -2
- package/dist/{workflow-step-action-Cu01omgz.cjs.map → workflow-step-action-DZgS0_fL.cjs.map} +1 -1
- package/package.json +10 -12
- package/theme/scale.css +7 -0
- package/dist/Avatar-98bsFrSV.js.map +0 -1
- package/dist/Avatar-BCj8SvOb.cjs.map +0 -1
- package/dist/Button-DH1aTzbs.cjs.map +0 -1
- package/dist/Button-EGoajBQY.js.map +0 -1
- package/dist/activity-2tovEdIP.cjs.map +0 -1
- package/dist/activity-CsTUr5_l.js.map +0 -1
- package/dist/ask-user-card-DroerVbm.cjs.map +0 -1
- package/dist/avatar-size-CNR0U-LW.js.map +0 -1
- package/dist/avatar-size-DxStOo5A.cjs.map +0 -1
- package/dist/combobox-BNlVCFgY.cjs.map +0 -1
- package/dist/combobox-Bw13EcK0.js.map +0 -1
- package/dist/command-UEPxVJlE.cjs.map +0 -1
- package/dist/command-V9rsKc7P.js.map +0 -1
- package/dist/data-keys-and-values-1lYi60YK.cjs.map +0 -1
- package/dist/data-keys-and-values-CHpxKsfq.js.map +0 -1
- package/dist/data-list-CmjTe8xE.cjs +0 -142
- package/dist/data-list-CmjTe8xE.cjs.map +0 -1
- package/dist/data-list-DT1LVR29.js +0 -138
- package/dist/data-list-DT1LVR29.js.map +0 -1
- package/dist/data-list-spacer-CdlT6bDd.cjs +0 -218
- package/dist/data-list-spacer-CdlT6bDd.cjs.map +0 -1
- package/dist/data-list-spacer-D--gDmOm.js +0 -209
- package/dist/data-list-spacer-D--gDmOm.js.map +0 -1
- package/dist/data-list-top-DJh08vFA.cjs.map +0 -1
- package/dist/data-list-top-T-mtdIUp.js.map +0 -1
- package/dist/data-panel-BkfjzriB.cjs.map +0 -1
- package/dist/data-panel-CMkR6Avv.js.map +0 -1
- package/dist/filter-bar-chip-BJJ6ytJ4.cjs.map +0 -1
- package/dist/filter-bar-chip-BarAq1S2.js.map +0 -1
- package/dist/property-filter-applied-CtSglSaH.cjs.map +0 -1
- package/dist/property-filter-applied-J9ob_Rss.js.map +0 -1
- package/dist/select-CQtsggxJ.js.map +0 -1
- package/dist/select-CbNLtiAs.cjs.map +0 -1
- package/dist/thread-list-BANpytn3.cjs.map +0 -1
- package/dist/thread-list-lXnXsPul.js.map +0 -1
- package/dist/tool-call-group-DJsiIb-B.cjs.map +0 -1
- package/dist/tool-call-group-ZDNZog5K.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group-DSW5WoSU.cjs","sources":["../src/ds/components/InputGroup/input-group.tsx"],"sourcesContent":["import { Input as InputPrimitive } from '@base-ui/react/input';\nimport { cva } from 'class-variance-authority';\nimport type { VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { Button } from '@/ds/components/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { keepOwnAccessibleName } from '@/ds/components/Field/field-control-aria';\nimport { ControlSizeContext, controlHeight } from '@/ds/primitives/control-size';\nimport type { ControlSize } from '@/ds/primitives/control-size';\nimport {\n deprecatedErrorAria,\n fieldErrorRimWithin,\n inputSurfaceAndFocusWithinStyle,\n} from '@/ds/primitives/form-element';\nimport { textFieldAutofillProps } from '@/ds/primitives/password-manager-autofill';\nimport { TextareaControl } from '@/ds/primitives/textarea-control';\nimport { cn } from '@/lib/utils';\n\n// Size flows down as `data-size` on the named group root (`group/input-group`), read by the\n// control through `group-data-[size=…]` variants — no prop drilling. The one context read is\n// upward: a wrapper that owns the rung (ButtonsGroup) hands it to the field.\n\nconst inputGroupBaseClassName = cn(\n // `flex-1` (not `min-w-0`) lets the root fill a flex row while keeping its content-floor\n // so it never collapses to 0. `items-center` centres the control: it carries its own\n // h-form-* (2px taller than the root's content box), so stretch would push its text low\n // / overflow the bottom border, while centring overlaps the (transparent) borders cleanly.\n 'group/input-group relative flex w-full flex-1 items-center',\n // The wrapper owns its control's width — a bare control has no width of its own,\n // so the group is the one that decides the input fills the remaining space.\n '[&>[data-slot=input-group-control]]:min-w-0 [&>[data-slot=input-group-control]]:flex-1',\n 'text-foreground',\n 'has-[:disabled]:cursor-not-allowed has-[:disabled]:text-muted-foreground',\n // Height is on the root (border-box) so the group matches a same-size sibling control.\n // Auto height when vertical (block-* addon) or wrapping a textarea.\n 'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col',\n 'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col',\n 'has-[textarea]:h-auto',\n 'has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:pl-0',\n 'has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:pr-0',\n // In flex-col, flex-1 zeroes the control's height; force flex-none + w-full instead.\n 'has-[>[data-align=block-start]]:[&>[data-slot=input-group-control]]:w-full has-[>[data-align=block-start]]:[&>[data-slot=input-group-control]]:flex-none',\n 'has-[>[data-align=block-end]]:[&>[data-slot=input-group-control]]:w-full has-[>[data-align=block-end]]:[&>[data-slot=input-group-control]]:flex-none',\n);\n\nconst inputGroupRoundedTextareaClassName = cn(\n // Pill (rounded-full) only fits single-line inline shapes. Fall back to rounded-xl\n // whenever the group goes vertical (block-* addon) or wraps a textarea.\n 'has-[>[data-align=block-start]]:rounded-xl',\n 'has-[>[data-align=block-end]]:rounded-xl',\n 'has-[textarea]:rounded-xl',\n);\n\n// A group wears the field material — the same `bg-card` plus rim an Input wears — so a\n// group and a bare field beside it are one surface. Its states move the rim, and they\n// read the nested control's focus (`focus-within`) because the wrapper never takes focus\n// itself. There is no second look: a transparent `outline` group existed alongside this\n// one and only ever produced two boundary languages for the same control, which is why\n// four of its call sites had wrapped it in a hand-made `bg-card rounded-full` div to get\n// the material back.\n// eslint-disable-next-line react-refresh/only-export-components -- shared with InputNumber\nexport const inputGroupClassName = cn(\n inputGroupBaseClassName,\n 'rounded-full',\n inputSurfaceAndFocusWithinStyle,\n fieldErrorRimWithin,\n inputGroupRoundedTextareaClassName,\n);\n\nexport type InputGroupProps = React.ComponentProps<'div'> & {\n size?: ControlSize;\n};\n\nfunction InputGroup({ className, size, ...props }: InputGroupProps) {\n // A wrapper's rung wins over the field's own: inside a ButtonsGroup the group owns the\n // height of every segment, so a field that kept its own type scale would sit at one rung\n // and read at another.\n const groupSize = React.useContext(ControlSizeContext);\n const resolved = groupSize ?? size ?? 'md';\n return (\n <div\n role=\"group\"\n data-slot=\"input-group\"\n data-size={resolved}\n className={cn(inputGroupClassName, controlHeight[resolved], className)}\n {...props}\n />\n );\n}\n\nconst inputGroupControlTextBySize = cn(\n 'group-data-[size=sm]/input-group:text-caption',\n 'group-data-[size=md]/input-group:text-body-sm',\n 'group-data-[size=lg]/input-group:text-body',\n);\n\nconst inputGroupAddonVariants = cva(\n cn(\n 'flex items-center justify-center gap-2 text-muted-foreground select-none',\n inputGroupControlTextBySize,\n 'group-has-[:disabled]/input-group:text-muted-foreground',\n \"[&>svg:not([class*='size-'])]:size-4\",\n ),\n {\n variants: {\n variant: {\n default: '',\n flush: '',\n },\n align: {\n 'inline-start': 'order-first pr-1 pl-3 has-[>button]:pl-1',\n 'inline-end': 'order-last pr-3 pl-1 has-[>button]:pr-1',\n 'block-start': 'order-first w-full justify-start border-b border-border px-3 pt-2 pb-1',\n 'block-end': 'order-last w-full justify-start border-t border-border px-3 pt-1 pb-2',\n },\n },\n compoundVariants: [\n { variant: 'flush', align: ['inline-start', 'inline-end'], className: 'gap-0 [&>button]:mx-0' },\n { variant: 'flush', align: 'inline-start', className: 'pl-0 has-[>button]:pl-0' },\n { variant: 'flush', align: 'inline-end', className: 'pr-0 has-[>button]:pr-0' },\n ],\n defaultVariants: {\n variant: 'default',\n align: 'inline-start',\n },\n },\n);\n\nexport type InputGroupAddonProps = React.ComponentProps<'div'> &\n Omit<VariantProps<typeof inputGroupAddonVariants>, 'variant'> & {\n /** `flush` joins inline buttons without a gap or an inset from the field's outside edge. */\n variant?: VariantProps<typeof inputGroupAddonVariants>['variant'];\n };\n\nfunction InputGroupAddon({\n className,\n align = 'inline-start',\n variant = 'default',\n onClick,\n ...props\n}: InputGroupAddonProps) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n data-variant={variant}\n className={cn(inputGroupAddonVariants({ align, variant }), className)}\n onClick={event => {\n // Click on non-interactive addon area focuses the control inside the group.\n // Skip when a button/input handled the click itself.\n const target = event.target as HTMLElement;\n if (!target.closest('button, input, textarea, [role=\"button\"]')) {\n event.currentTarget.parentElement\n ?.querySelector<HTMLInputElement | HTMLTextAreaElement>('[data-slot=input-group-control]')\n ?.focus();\n }\n onClick?.(event);\n }}\n {...props}\n />\n );\n}\n\n// Size flows from the parent group's `data-size` (no React context). All four sizes are\n// written out so Tailwind's scanner emits them. The control is sized to the root's\n// content box (token height minus the 1px border on each side) so it never overflows the\n// root — otherwise, in a flex-column parent, the root's content-based minimum would win\n// over its explicit height and the group would render 2px taller than a sibling control.\n// The explicit height also keeps the control from collapsing to the line-height in block\n// mode (flex-col + flex-none).\nconst inputGroupControlHeightBySize = cn(\n 'group-data-[size=sm]/input-group:h-[calc(var(--spacing-control-sm)-2px)]',\n 'group-data-[size=md]/input-group:h-[calc(var(--spacing-control-md)-2px)]',\n 'group-data-[size=lg]/input-group:h-[calc(var(--spacing-control-lg)-2px)]',\n);\n\n// eslint-disable-next-line react-refresh/only-export-components -- shared with InputNumber\nexport const inputGroupControlClassName = cn(\n 'min-w-0 flex-1 bg-transparent px-3 text-label text-foreground outline-hidden',\n inputGroupControlHeightBySize,\n 'placeholder:text-muted-foreground placeholder:transition-opacity placeholder:duration-normal',\n 'focus:placeholder:opacity-70',\n 'disabled:cursor-not-allowed',\n);\n\nexport type InputGroupInputProps = Omit<React.ComponentProps<'input'>, 'size'> & {\n testId?: string;\n /** @deprecated Wrap the group in `<Field invalid>`, or set `aria-invalid` on a control outside a `Field`. */\n error?: boolean;\n};\n\nfunction InputGroupInput({ className, testId, error, type = 'text', autoComplete, ...props }: InputGroupInputProps) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input-group-control\"\n data-testid={testId}\n className={cn(\n inputGroupControlClassName,\n // WebKit and Firefox use different selectors for native number spinners.\n '[&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none',\n '[&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none',\n '[&[type=number]]:[appearance:textfield]',\n // type=\"search\": drop WebKit's native clear button so it doesn't double up with a\n // custom clear control (e.g. the scorers toolbar's InputGroupButton).\n '[&::-webkit-search-cancel-button]:appearance-none',\n className,\n )}\n {...deprecatedErrorAria(error)}\n {...props}\n {...textFieldAutofillProps(autoComplete)}\n {...keepOwnAccessibleName(props)}\n />\n );\n}\n\nexport type InputGroupTextareaProps = React.ComponentProps<'textarea'> & {\n testId?: string;\n /** @deprecated Wrap the group in `<Field invalid>`, or set `aria-invalid` on a control outside a `Field`. */\n error?: boolean;\n};\n\nfunction InputGroupTextarea({ className, testId, error, ...props }: InputGroupTextareaProps) {\n return (\n <TextareaControl\n data-slot=\"input-group-control\"\n data-testid={testId}\n className={cn(\n 'min-h-15 min-w-0 flex-1 resize-y bg-transparent px-3 py-2 text-foreground outline-hidden',\n inputGroupControlTextBySize,\n 'placeholder:text-muted-foreground placeholder:transition-opacity placeholder:duration-normal',\n 'focus:placeholder:opacity-70',\n 'disabled:cursor-not-allowed',\n className,\n )}\n {...deprecatedErrorAria(error)}\n {...props}\n />\n );\n}\n\nexport type InputGroupTextProps = React.ComponentProps<'span'>;\n\nfunction InputGroupText({ className, ...props }: InputGroupTextProps) {\n return (\n <span\n className={cn(\n 'flex items-center gap-2 text-caption text-muted-foreground [&_svg]:pointer-events-none',\n \"[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport type InputGroupButtonProps = Omit<React.ComponentProps<typeof Button>, 'size' | 'variant'> & {\n size?: ButtonProps['size'];\n variant?: ButtonProps['variant'];\n};\n\nfunction InputGroupButton({ size = 'icon-sm', variant = 'ghost', type = 'button', ...props }: InputGroupButtonProps) {\n return <Button type={type} size={size} variant={variant} {...props} />;\n}\n\nexport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupTextarea, InputGroupText, InputGroupButton };\n"],"names":["cn","inputSurfaceAndFocusWithinStyle","fieldErrorRimWithin","React","ControlSizeContext","jsx","controlHeight","cva","InputPrimitive","deprecatedErrorAria","textFieldAutofillProps","keepOwnAccessibleName","TextareaControl","Button"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-group-DRXUthxe.cjs","sources":["../src/ds/components/InputGroup/input-group.tsx"],"sourcesContent":["import { Input as InputPrimitive } from '@base-ui/react/input';\nimport { cva } from 'class-variance-authority';\nimport type { VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { Button } from '@/ds/components/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { keepOwnAccessibleName } from '@/ds/components/Field/field-control-aria';\nimport { ControlSizeContext, controlHeight } from '@/ds/primitives/control-size';\nimport type { ControlSize } from '@/ds/primitives/control-size';\nimport {\n deprecatedErrorAria,\n fieldErrorRimWithin,\n inputSurfaceAndFocusWithinStyle,\n} from '@/ds/primitives/form-element';\nimport { textFieldAutofillProps } from '@/ds/primitives/password-manager-autofill';\nimport { TextareaControl } from '@/ds/primitives/textarea-control';\nimport { cn } from '@/lib/utils';\n\n// Size flows down as `data-size` on the named group root (`group/input-group`), read by the\n// control through `group-data-[size=…]` variants — no prop drilling. The one context read is\n// upward: a wrapper that owns the rung (ButtonsGroup) hands it to the field.\n\nconst inputGroupBaseClassName = cn(\n // `flex-1` (not `min-w-0`) lets the root fill a flex row while keeping its content-floor\n // so it never collapses to 0. `items-center` centres the control: it carries its own\n // h-form-* (2px taller than the root's content box), so stretch would push its text low\n // / overflow the bottom border, while centring overlaps the (transparent) borders cleanly.\n 'group/input-group relative flex w-full flex-1 items-center',\n // The wrapper owns its control's width — a bare control has no width of its own,\n // so the group is the one that decides the input fills the remaining space.\n '[&>[data-slot=input-group-control]]:min-w-0 [&>[data-slot=input-group-control]]:flex-1',\n 'text-foreground',\n 'has-[:disabled]:cursor-not-allowed has-[:disabled]:text-muted-foreground',\n // Height is on the root (border-box) so the group matches a same-size sibling control.\n // Auto height when vertical (block-* addon) or wrapping a textarea.\n 'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col',\n 'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col',\n 'has-[textarea]:h-auto',\n 'has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:pl-0',\n 'has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:pr-0',\n // In flex-col, flex-1 zeroes the control's height; force flex-none + w-full instead.\n 'has-[>[data-align=block-start]]:[&>[data-slot=input-group-control]]:w-full has-[>[data-align=block-start]]:[&>[data-slot=input-group-control]]:flex-none',\n 'has-[>[data-align=block-end]]:[&>[data-slot=input-group-control]]:w-full has-[>[data-align=block-end]]:[&>[data-slot=input-group-control]]:flex-none',\n);\n\nconst inputGroupRoundedTextareaClassName = cn(\n // Pill (rounded-full) only fits single-line inline shapes. Fall back to rounded-xl\n // whenever the group goes vertical (block-* addon) or wraps a textarea.\n 'has-[>[data-align=block-start]]:rounded-xl',\n 'has-[>[data-align=block-end]]:rounded-xl',\n 'has-[textarea]:rounded-xl',\n);\n\n// A group wears the field material — the same `bg-card` plus rim an Input wears — so a\n// group and a bare field beside it are one surface. Its states move the rim, and they\n// read the nested control's focus (`focus-within`) because the wrapper never takes focus\n// itself. There is no second look: a transparent `outline` group existed alongside this\n// one and only ever produced two boundary languages for the same control, which is why\n// four of its call sites had wrapped it in a hand-made `bg-card rounded-full` div to get\n// the material back.\n// eslint-disable-next-line react-refresh/only-export-components -- shared with InputNumber\nexport const inputGroupClassName = cn(\n inputGroupBaseClassName,\n 'rounded-full',\n inputSurfaceAndFocusWithinStyle,\n fieldErrorRimWithin,\n inputGroupRoundedTextareaClassName,\n);\n\nexport type InputGroupProps = React.ComponentProps<'div'> & {\n size?: ControlSize;\n};\n\nfunction InputGroup({ className, size, ...props }: InputGroupProps) {\n // A wrapper's rung wins over the field's own: inside a ButtonsGroup the group owns the\n // height of every segment, so a field that kept its own type scale would sit at one rung\n // and read at another.\n const groupSize = React.useContext(ControlSizeContext);\n const resolved = groupSize ?? size ?? 'md';\n return (\n <div\n role=\"group\"\n data-slot=\"input-group\"\n data-size={resolved}\n className={cn(inputGroupClassName, controlHeight[resolved], className)}\n {...props}\n />\n );\n}\n\nconst inputGroupControlTextBySize = cn(\n 'group-data-[size=sm]/input-group:text-caption',\n 'group-data-[size=md]/input-group:text-body-sm',\n 'group-data-[size=lg]/input-group:text-body',\n);\n\nconst inputGroupAddonVariants = cva(\n cn(\n 'flex items-center justify-center gap-2 text-muted-foreground select-none',\n inputGroupControlTextBySize,\n 'group-has-[:disabled]/input-group:text-muted-foreground',\n \"[&>svg:not([class*='size-'])]:size-4\",\n ),\n {\n variants: {\n variant: {\n default: '',\n flush: '',\n },\n align: {\n 'inline-start': 'order-first pr-1 pl-3 has-[>button]:pl-1',\n 'inline-end': 'order-last pr-3 pl-1 has-[>button]:pr-1',\n 'block-start': 'order-first w-full justify-start border-b border-border px-3 pt-2 pb-1',\n 'block-end': 'order-last w-full justify-start border-t border-border px-3 pt-1 pb-2',\n },\n },\n compoundVariants: [\n { variant: 'flush', align: ['inline-start', 'inline-end'], className: 'gap-0 [&>button]:mx-0' },\n { variant: 'flush', align: 'inline-start', className: 'pl-0 has-[>button]:pl-0' },\n { variant: 'flush', align: 'inline-end', className: 'pr-0 has-[>button]:pr-0' },\n ],\n defaultVariants: {\n variant: 'default',\n align: 'inline-start',\n },\n },\n);\n\nexport type InputGroupAddonProps = React.ComponentProps<'div'> &\n Omit<VariantProps<typeof inputGroupAddonVariants>, 'variant'> & {\n /** `flush` joins inline buttons without a gap or an inset from the field's outside edge. */\n variant?: VariantProps<typeof inputGroupAddonVariants>['variant'];\n };\n\nfunction InputGroupAddon({\n className,\n align = 'inline-start',\n variant = 'default',\n onClick,\n ...props\n}: InputGroupAddonProps) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n data-variant={variant}\n className={cn(inputGroupAddonVariants({ align, variant }), className)}\n onClick={event => {\n // Click on non-interactive addon area focuses the control inside the group.\n // Skip when a button/input handled the click itself.\n const target = event.target as HTMLElement;\n if (!target.closest('button, input, textarea, [role=\"button\"]')) {\n event.currentTarget.parentElement\n ?.querySelector<HTMLInputElement | HTMLTextAreaElement>('[data-slot=input-group-control]')\n ?.focus();\n }\n onClick?.(event);\n }}\n {...props}\n />\n );\n}\n\n// Size flows from the parent group's `data-size` (no React context). All four sizes are\n// written out so Tailwind's scanner emits them. The control is sized to the root's\n// content box (token height minus the 1px border on each side) so it never overflows the\n// root — otherwise, in a flex-column parent, the root's content-based minimum would win\n// over its explicit height and the group would render 2px taller than a sibling control.\n// The explicit height also keeps the control from collapsing to the line-height in block\n// mode (flex-col + flex-none).\nconst inputGroupControlHeightBySize = cn(\n 'group-data-[size=sm]/input-group:h-[calc(var(--spacing-control-sm)-2px)]',\n 'group-data-[size=md]/input-group:h-[calc(var(--spacing-control-md)-2px)]',\n 'group-data-[size=lg]/input-group:h-[calc(var(--spacing-control-lg)-2px)]',\n);\n\n// eslint-disable-next-line react-refresh/only-export-components -- shared with InputNumber\nexport const inputGroupControlClassName = cn(\n 'min-w-0 flex-1 bg-transparent px-3 text-label text-foreground outline-hidden',\n inputGroupControlHeightBySize,\n 'placeholder:text-muted-foreground placeholder:transition-opacity placeholder:duration-normal',\n 'focus:placeholder:opacity-70',\n 'disabled:cursor-not-allowed',\n);\n\nexport type InputGroupInputProps = Omit<React.ComponentProps<'input'>, 'size'> & {\n testId?: string;\n /** @deprecated Wrap the group in `<Field invalid>`, or set `aria-invalid` on a control outside a `Field`. */\n error?: boolean;\n};\n\nfunction InputGroupInput({ className, testId, error, type = 'text', autoComplete, ...props }: InputGroupInputProps) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input-group-control\"\n data-testid={testId}\n className={cn(\n inputGroupControlClassName,\n // WebKit and Firefox use different selectors for native number spinners.\n '[&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none',\n '[&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none',\n '[&[type=number]]:[appearance:textfield]',\n // type=\"search\": drop WebKit's native clear button so it doesn't double up with a\n // custom clear control (e.g. the scorers toolbar's InputGroupButton).\n '[&::-webkit-search-cancel-button]:appearance-none',\n className,\n )}\n {...deprecatedErrorAria(error)}\n {...props}\n {...textFieldAutofillProps(autoComplete)}\n {...keepOwnAccessibleName(props)}\n />\n );\n}\n\nexport type InputGroupTextareaProps = React.ComponentProps<'textarea'> & {\n testId?: string;\n /** @deprecated Wrap the group in `<Field invalid>`, or set `aria-invalid` on a control outside a `Field`. */\n error?: boolean;\n};\n\nfunction InputGroupTextarea({ className, testId, error, ...props }: InputGroupTextareaProps) {\n return (\n <TextareaControl\n data-slot=\"input-group-control\"\n data-testid={testId}\n className={cn(\n 'min-h-15 min-w-0 flex-1 resize-y bg-transparent px-3 py-2 text-foreground outline-hidden',\n inputGroupControlTextBySize,\n 'placeholder:text-muted-foreground placeholder:transition-opacity placeholder:duration-normal',\n 'focus:placeholder:opacity-70',\n 'disabled:cursor-not-allowed',\n className,\n )}\n {...deprecatedErrorAria(error)}\n {...props}\n />\n );\n}\n\nexport type InputGroupTextProps = React.ComponentProps<'span'>;\n\nfunction InputGroupText({ className, ...props }: InputGroupTextProps) {\n return (\n <span\n className={cn(\n 'flex items-center gap-2 text-caption text-muted-foreground [&_svg]:pointer-events-none',\n \"[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport type InputGroupButtonProps = Omit<React.ComponentProps<typeof Button>, 'size' | 'variant'> & {\n size?: ButtonProps['size'];\n variant?: ButtonProps['variant'];\n};\n\nfunction InputGroupButton({ size = 'icon-sm', variant = 'ghost', type = 'button', ...props }: InputGroupButtonProps) {\n return <Button type={type} size={size} variant={variant} {...props} />;\n}\n\nexport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupTextarea, InputGroupText, InputGroupButton };\n"],"names":["cn","inputSurfaceAndFocusWithinStyle","fieldErrorRimWithin","React","ControlSizeContext","jsx","controlHeight","cva","InputPrimitive","deprecatedErrorAria","textFieldAutofillProps","keepOwnAccessibleName","TextareaControl","Button"],"mappings":"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"}
|
|
@@ -74,7 +74,7 @@ const KEYBOARD_CONSUMER_SELECTOR = [
|
|
|
74
74
|
"[data-radix-popper-content-wrapper]"
|
|
75
75
|
].join(", ");
|
|
76
76
|
const isKeyboardConsumer = (target) => target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;
|
|
77
|
-
const isTypingInConsumer = (event) => !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);
|
|
77
|
+
const isTypingInConsumer = (event) => event.target !== event.currentTarget && !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);
|
|
78
78
|
const sameCombo = (a, b) => a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;
|
|
79
79
|
const hasPrefix = (steps, prefix) => steps.length > prefix.length && prefix.every((step, i) => steps[i] !== void 0 && sameCombo(steps[i], step));
|
|
80
80
|
const canonicalCombo = (combo) => `${combo.meta ? "meta+" : ""}${combo.ctrl ? "ctrl+" : ""}${combo.alt ? "alt+" : ""}${combo.shift ? "shift+" : ""}${combo.key}`;
|
|
@@ -110,15 +110,13 @@ const createKeyboardDispatcher = () => {
|
|
|
110
110
|
}
|
|
111
111
|
return [...resolved.values()];
|
|
112
112
|
};
|
|
113
|
-
const accepts = (layer, event) => !layer.shouldHandle || layer.shouldHandle(event);
|
|
113
|
+
const accepts = (layer, event) => (layer.insideFields === true || !isTypingInConsumer(event)) && (!layer.shouldHandle || layer.shouldHandle(event));
|
|
114
114
|
const handleKeydown = (event) => {
|
|
115
115
|
const isImeComposition = event.isComposing || event.keyCode === 229;
|
|
116
116
|
if (event.defaultPrevented || isImeComposition) {
|
|
117
117
|
reset();
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
const isAncestorShortcut = event.target !== event.currentTarget;
|
|
121
|
-
if (isAncestorShortcut && isTypingInConsumer(event)) return;
|
|
122
120
|
const bindings = resolveBindings();
|
|
123
121
|
const now = Date.now();
|
|
124
122
|
if (pending) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-dispatcher.cjs.js","sources":["../../src/lib/keyboard/keyboard-dispatcher.ts"],"sourcesContent":["/**\n * Map of key bindings to handlers.\n *\n * - Combos: `'cmd+k'`, `'ctrl+shift+p'`, `'mod+Home'`.\n * - Timed sequences: `'g$+a'` — press `g`, then `a` within 500ms.\n * Chain as many steps as needed (`'a$+b$+c'`); the last step has no `$`.\n * A sequence prefix takes precedence over a plain combo on the same key, and an\n * unexpected key resets the sequence before being evaluated normally.\n */\nexport type UseKeydownArgs = {\n [keySet: string]: () => void;\n};\n\nexport type ParsedKeyCombo = {\n meta: boolean;\n ctrl: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n};\n\nconst isMacPlatform = () =>\n typeof navigator !== 'undefined' && /mac/i.test(navigator.platform || navigator.userAgent || '');\n\nexport const parseKeyCombo = (combo: string): ParsedKeyCombo => {\n const parsed: ParsedKeyCombo = { meta: false, ctrl: false, shift: false, alt: false, key: '' };\n\n for (const token of combo.split('+')) {\n switch (token.toLowerCase()) {\n case 'cmd':\n case 'meta':\n parsed.meta = true;\n break;\n case 'ctrl':\n case 'control':\n parsed.ctrl = true;\n break;\n case 'shift':\n parsed.shift = true;\n break;\n case 'alt':\n case 'option':\n parsed.alt = true;\n break;\n case 'mod':\n if (isMacPlatform()) parsed.meta = true;\n else parsed.ctrl = true;\n break;\n default:\n parsed.key = token.toLowerCase();\n }\n }\n\n return parsed;\n};\n\nexport type KeyStep = ParsedKeyCombo;\n\n/** A binding is a sequence of steps; a plain combo is a sequence of length 1. */\nexport type ParsedKeyBinding = KeyStep[];\n\nconst SEQUENCE_TIMEOUT_MS = 500;\nconst SEQUENCE_TOKEN = /^(.+)\\$$/;\n\n/**\n * Parses `cmd+k` (single step) or `g$+a` (sequence: `g`, then `a` within 500ms).\n * A `key$` token closes a step; the modifiers before it belong to that step.\n */\nexport const parseKeyBinding = (binding: string): ParsedKeyBinding => {\n const steps: KeyStep[] = [];\n let tokens: string[] = [];\n\n for (const token of binding.split('+')) {\n const [, sequenceKey] = SEQUENCE_TOKEN.exec(token) ?? [];\n if (sequenceKey) {\n steps.push(parseKeyCombo([...tokens, sequenceKey].join('+')));\n tokens = [];\n } else {\n tokens.push(token);\n }\n }\n\n if (tokens.length === 0) {\n throw new Error(`Invalid key binding \"${binding}\": the last step cannot end with $`);\n }\n steps.push(parseKeyCombo(tokens.join('+')));\n\n for (const step of steps) {\n if (!step.key) throw new Error(`Invalid key binding \"${binding}\": every step needs a key`);\n }\n\n return steps;\n};\n\n/**\n * Printable symbols like `?`, `!` or `:` are typed with Shift on most layouts, and\n * `event.key` already reflects the resulting character. For those, the Shift state\n * is irrelevant unless the binding asks for it explicitly.\n */\nconst isShiftedSymbol = (key: string) => key.length === 1 && !/[a-z0-9]/i.test(key);\n\nexport const matchesCombo = (event: KeyboardEvent, combo: ParsedKeyCombo): boolean =>\n event.metaKey === combo.meta &&\n event.ctrlKey === combo.ctrl &&\n (event.shiftKey === combo.shift || (!combo.shift && isShiftedSymbol(combo.key))) &&\n event.altKey === combo.alt &&\n event.key.toLowerCase() === combo.key;\n\nconst KEYBOARD_CONSUMER_SELECTOR = [\n 'input',\n 'textarea',\n 'select',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\" i]',\n '[contenteditable=\"plaintext-only\" i]',\n '[role=\"combobox\"]',\n '[role=\"listbox\"]',\n '[role=\"menu\"]',\n '[role=\"menuitem\"]',\n '[role=\"option\"]',\n '[role=\"dialog\"]',\n '[role=\"alertdialog\"]',\n '[data-radix-popper-content-wrapper]',\n].join(', ');\n\nexport const isKeyboardConsumer = (target: EventTarget | null): boolean =>\n target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;\n\n/**\n * Keys without meta/ctrl/alt (`?`, `g`, `Escape`, arrows…) belong to the\n * focused field or widget, so they must keep typing/navigating there. Combos\n * like `mod+k` are safe to intercept from anywhere.\n */\nconst isTypingInConsumer = (event: KeyboardEvent) =>\n !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);\n\nconst sameCombo = (a: ParsedKeyCombo, b: ParsedKeyCombo) =>\n a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;\n\nconst hasPrefix = (steps: KeyStep[], prefix: KeyStep[]) =>\n steps.length > prefix.length && prefix.every((step, i) => steps[i] !== undefined && sameCombo(steps[i], step));\n\nconst canonicalCombo = (combo: ParsedKeyCombo) =>\n `${combo.meta ? 'meta+' : ''}${combo.ctrl ? 'ctrl+' : ''}${combo.alt ? 'alt+' : ''}${combo.shift ? 'shift+' : ''}${combo.key}`;\n\n/** Stable identity for a binding, so `cmd+k` and `meta+k` shadow each other. */\nconst canonicalBinding = (steps: KeyStep[]) => steps.map(canonicalCombo).join(' ');\n\n/**\n * A set of bindings registered by one `useKeydown` call. `depth` comes from the\n * nearest `KeyboardScope`; deeper layers shadow shallower ones binding by binding.\n */\nexport type KeyboardLayer = {\n depth: number;\n bindings: UseKeydownArgs;\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /** When `false`, auto-repeated keydowns from a held key don't fire handlers. */\n repeat?: boolean;\n};\n\ntype ResolvedBinding = {\n steps: KeyStep[];\n handler: () => void;\n layer: KeyboardLayer;\n};\n\ntype PendingSequence = {\n /** Steps already matched, as parsed combos (several bindings may share a prefix). */\n matched: KeyStep[];\n candidates: ResolvedBinding[];\n expiresAt: number;\n};\n\nexport type KeyboardDispatcher = {\n /** Registers a layer and returns its unregister function. */\n register: (layer: KeyboardLayer) => () => void;\n handleKeydown: (event: KeyboardEvent) => void;\n /** Forgets any armed sequence and clears its timer. */\n reset: () => void;\n};\n\n/**\n * Owns the layer registry and the single pending-sequence state for one event\n * target. Deeper layers win; on equal depth, the most recently registered wins.\n */\nexport const createKeyboardDispatcher = (): KeyboardDispatcher => {\n const layers = new Map<KeyboardLayer, number>();\n let nextOrder = 0;\n let pending: PendingSequence | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n\n const reset = () => {\n pending = undefined;\n if (expiryTimer !== undefined) {\n clearTimeout(expiryTimer);\n expiryTimer = undefined;\n }\n };\n\n const arm = (matched: KeyStep[], candidates: ResolvedBinding[], now: number) => {\n reset();\n pending = { matched, candidates, expiresAt: now + SEQUENCE_TIMEOUT_MS };\n expiryTimer = setTimeout(reset, SEQUENCE_TIMEOUT_MS);\n };\n\n const resolveBindings = (): ResolvedBinding[] => {\n const ranked = [...layers.entries()].sort(([a, orderA], [b, orderB]) =>\n b.depth !== a.depth ? b.depth - a.depth : orderB - orderA,\n );\n const resolved = new Map<string, ResolvedBinding>();\n for (const [layer] of ranked) {\n for (const [binding, handler] of Object.entries(layer.bindings)) {\n const steps = parseKeyBinding(binding);\n const key = canonicalBinding(steps);\n if (!resolved.has(key)) resolved.set(key, { steps, handler, layer });\n }\n }\n return [...resolved.values()];\n };\n\n const accepts = (layer: KeyboardLayer, event: KeyboardEvent) => !layer.shouldHandle || layer.shouldHandle(event);\n\n const handleKeydown = (event: KeyboardEvent) => {\n // IME boundary events can report 229 while isComposing is false.\n const isImeComposition = event.isComposing || event.keyCode === 229;\n if (event.defaultPrevented || isImeComposition) {\n reset();\n return;\n }\n const isAncestorShortcut = event.target !== event.currentTarget;\n if (isAncestorShortcut && isTypingInConsumer(event)) return;\n\n const bindings = resolveBindings();\n const now = Date.now();\n\n if (pending) {\n if (now < pending.expiresAt) {\n const stepIndex = pending.matched.length;\n const candidates = bindings.filter(binding =>\n pending?.candidates.some(\n candidate =>\n candidate.layer === binding.layer &&\n canonicalBinding(candidate.steps) === canonicalBinding(binding.steps),\n ),\n );\n for (const { steps, handler, layer } of candidates) {\n const step = steps[stepIndex];\n if (!step || !hasPrefix(steps, pending.matched) || !matchesCombo(event, step)) continue;\n if (!accepts(layer, event)) return;\n event.preventDefault();\n // A held key neither advances nor completes a `repeat: false` sequence.\n if (event.repeat && layer.repeat === false) return;\n if (stepIndex === steps.length - 1) {\n reset();\n handler();\n } else {\n arm([...pending.matched, step], candidates, now);\n }\n return;\n }\n }\n // Expired or unexpected key: reset and evaluate the event normally below.\n reset();\n }\n\n // Sequence prefixes win over plain combos on the same key.\n const candidates = bindings.filter(({ steps, layer }) => {\n const [first] = steps;\n return steps.length > 1 && first && matchesCombo(event, first) && accepts(layer, event);\n });\n const first = candidates[0]?.steps[0];\n if (first) {\n event.preventDefault();\n arm([first], candidates, now);\n return;\n }\n\n for (const { steps, handler, layer } of bindings) {\n const [first] = steps;\n if (steps.length === 1 && first && matchesCombo(event, first)) {\n if (!accepts(layer, event)) return;\n event.preventDefault();\n if (event.repeat && layer.repeat === false) return;\n handler();\n return;\n }\n }\n };\n\n const register = (layer: KeyboardLayer) => {\n layers.set(layer, nextOrder++);\n return () => {\n layers.delete(layer);\n if (pending) {\n pending.candidates = pending.candidates.filter(candidate => candidate.layer !== layer);\n if (pending.candidates.length === 0) reset();\n }\n };\n };\n\n return { register, handleKeydown, reset };\n};\n"],"names":["candidates","first"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keyboard-dispatcher.cjs.js","sources":["../../src/lib/keyboard/keyboard-dispatcher.ts"],"sourcesContent":["/**\n * Map of key bindings to handlers.\n *\n * - Combos: `'cmd+k'`, `'ctrl+shift+p'`, `'mod+Home'`.\n * - Timed sequences: `'g$+a'` — press `g`, then `a` within 500ms.\n * Chain as many steps as needed (`'a$+b$+c'`); the last step has no `$`.\n * A sequence prefix takes precedence over a plain combo on the same key, and an\n * unexpected key resets the sequence before being evaluated normally.\n */\nexport type UseKeydownArgs = {\n [keySet: string]: () => void;\n};\n\nexport type ParsedKeyCombo = {\n meta: boolean;\n ctrl: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n};\n\nconst isMacPlatform = () =>\n typeof navigator !== 'undefined' && /mac/i.test(navigator.platform || navigator.userAgent || '');\n\nexport const parseKeyCombo = (combo: string): ParsedKeyCombo => {\n const parsed: ParsedKeyCombo = { meta: false, ctrl: false, shift: false, alt: false, key: '' };\n\n for (const token of combo.split('+')) {\n switch (token.toLowerCase()) {\n case 'cmd':\n case 'meta':\n parsed.meta = true;\n break;\n case 'ctrl':\n case 'control':\n parsed.ctrl = true;\n break;\n case 'shift':\n parsed.shift = true;\n break;\n case 'alt':\n case 'option':\n parsed.alt = true;\n break;\n case 'mod':\n if (isMacPlatform()) parsed.meta = true;\n else parsed.ctrl = true;\n break;\n default:\n parsed.key = token.toLowerCase();\n }\n }\n\n return parsed;\n};\n\nexport type KeyStep = ParsedKeyCombo;\n\n/** A binding is a sequence of steps; a plain combo is a sequence of length 1. */\nexport type ParsedKeyBinding = KeyStep[];\n\nconst SEQUENCE_TIMEOUT_MS = 500;\nconst SEQUENCE_TOKEN = /^(.+)\\$$/;\n\n/**\n * Parses `cmd+k` (single step) or `g$+a` (sequence: `g`, then `a` within 500ms).\n * A `key$` token closes a step; the modifiers before it belong to that step.\n */\nexport const parseKeyBinding = (binding: string): ParsedKeyBinding => {\n const steps: KeyStep[] = [];\n let tokens: string[] = [];\n\n for (const token of binding.split('+')) {\n const [, sequenceKey] = SEQUENCE_TOKEN.exec(token) ?? [];\n if (sequenceKey) {\n steps.push(parseKeyCombo([...tokens, sequenceKey].join('+')));\n tokens = [];\n } else {\n tokens.push(token);\n }\n }\n\n if (tokens.length === 0) {\n throw new Error(`Invalid key binding \"${binding}\": the last step cannot end with $`);\n }\n steps.push(parseKeyCombo(tokens.join('+')));\n\n for (const step of steps) {\n if (!step.key) throw new Error(`Invalid key binding \"${binding}\": every step needs a key`);\n }\n\n return steps;\n};\n\n/**\n * Printable symbols like `?`, `!` or `:` are typed with Shift on most layouts, and\n * `event.key` already reflects the resulting character. For those, the Shift state\n * is irrelevant unless the binding asks for it explicitly.\n */\nconst isShiftedSymbol = (key: string) => key.length === 1 && !/[a-z0-9]/i.test(key);\n\nexport const matchesCombo = (event: KeyboardEvent, combo: ParsedKeyCombo): boolean =>\n event.metaKey === combo.meta &&\n event.ctrlKey === combo.ctrl &&\n (event.shiftKey === combo.shift || (!combo.shift && isShiftedSymbol(combo.key))) &&\n event.altKey === combo.alt &&\n event.key.toLowerCase() === combo.key;\n\nconst KEYBOARD_CONSUMER_SELECTOR = [\n 'input',\n 'textarea',\n 'select',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\" i]',\n '[contenteditable=\"plaintext-only\" i]',\n '[role=\"combobox\"]',\n '[role=\"listbox\"]',\n '[role=\"menu\"]',\n '[role=\"menuitem\"]',\n '[role=\"option\"]',\n '[role=\"dialog\"]',\n '[role=\"alertdialog\"]',\n '[data-radix-popper-content-wrapper]',\n].join(', ');\n\nexport const isKeyboardConsumer = (target: EventTarget | null): boolean =>\n target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;\n\n/**\n * Keys without meta/ctrl/alt (`?`, `g`, `Escape`, arrows…) belong to the\n * focused field or widget, so they must keep typing/navigating there. Combos\n * like `mod+k` are safe to intercept from anywhere.\n */\nconst isTypingInConsumer = (event: KeyboardEvent) =>\n event.target !== event.currentTarget &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n isKeyboardConsumer(event.target);\n\nconst sameCombo = (a: ParsedKeyCombo, b: ParsedKeyCombo) =>\n a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;\n\nconst hasPrefix = (steps: KeyStep[], prefix: KeyStep[]) =>\n steps.length > prefix.length && prefix.every((step, i) => steps[i] !== undefined && sameCombo(steps[i], step));\n\nconst canonicalCombo = (combo: ParsedKeyCombo) =>\n `${combo.meta ? 'meta+' : ''}${combo.ctrl ? 'ctrl+' : ''}${combo.alt ? 'alt+' : ''}${combo.shift ? 'shift+' : ''}${combo.key}`;\n\n/** Stable identity for a binding, so `cmd+k` and `meta+k` shadow each other. */\nconst canonicalBinding = (steps: KeyStep[]) => steps.map(canonicalCombo).join(' ');\n\n/**\n * A set of bindings registered by one `useKeydown` call. `depth` comes from the\n * nearest `KeyboardScope`; deeper layers shadow shallower ones binding by binding.\n */\nexport type KeyboardLayer = {\n depth: number;\n bindings: UseKeydownArgs;\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /** When `true`, unmodified keys fire even while focus is in a field or widget. */\n insideFields?: boolean;\n /** When `false`, auto-repeated keydowns from a held key don't fire handlers. */\n repeat?: boolean;\n};\n\ntype ResolvedBinding = {\n steps: KeyStep[];\n handler: () => void;\n layer: KeyboardLayer;\n};\n\ntype PendingSequence = {\n /** Steps already matched, as parsed combos (several bindings may share a prefix). */\n matched: KeyStep[];\n candidates: ResolvedBinding[];\n expiresAt: number;\n};\n\nexport type KeyboardDispatcher = {\n /** Registers a layer and returns its unregister function. */\n register: (layer: KeyboardLayer) => () => void;\n handleKeydown: (event: KeyboardEvent) => void;\n /** Forgets any armed sequence and clears its timer. */\n reset: () => void;\n};\n\n/**\n * Owns the layer registry and the single pending-sequence state for one event\n * target. Deeper layers win; on equal depth, the most recently registered wins.\n */\nexport const createKeyboardDispatcher = (): KeyboardDispatcher => {\n const layers = new Map<KeyboardLayer, number>();\n let nextOrder = 0;\n let pending: PendingSequence | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n\n const reset = () => {\n pending = undefined;\n if (expiryTimer !== undefined) {\n clearTimeout(expiryTimer);\n expiryTimer = undefined;\n }\n };\n\n const arm = (matched: KeyStep[], candidates: ResolvedBinding[], now: number) => {\n reset();\n pending = { matched, candidates, expiresAt: now + SEQUENCE_TIMEOUT_MS };\n expiryTimer = setTimeout(reset, SEQUENCE_TIMEOUT_MS);\n };\n\n const resolveBindings = (): ResolvedBinding[] => {\n const ranked = [...layers.entries()].sort(([a, orderA], [b, orderB]) =>\n b.depth !== a.depth ? b.depth - a.depth : orderB - orderA,\n );\n const resolved = new Map<string, ResolvedBinding>();\n for (const [layer] of ranked) {\n for (const [binding, handler] of Object.entries(layer.bindings)) {\n const steps = parseKeyBinding(binding);\n const key = canonicalBinding(steps);\n if (!resolved.has(key)) resolved.set(key, { steps, handler, layer });\n }\n }\n return [...resolved.values()];\n };\n\n const accepts = (layer: KeyboardLayer, event: KeyboardEvent) =>\n (layer.insideFields === true || !isTypingInConsumer(event)) && (!layer.shouldHandle || layer.shouldHandle(event));\n\n const handleKeydown = (event: KeyboardEvent) => {\n // IME boundary events can report 229 while isComposing is false.\n const isImeComposition = event.isComposing || event.keyCode === 229;\n if (event.defaultPrevented || isImeComposition) {\n reset();\n return;\n }\n\n const bindings = resolveBindings();\n const now = Date.now();\n\n if (pending) {\n if (now < pending.expiresAt) {\n const stepIndex = pending.matched.length;\n const candidates = bindings.filter(binding =>\n pending?.candidates.some(\n candidate =>\n candidate.layer === binding.layer &&\n canonicalBinding(candidate.steps) === canonicalBinding(binding.steps),\n ),\n );\n for (const { steps, handler, layer } of candidates) {\n const step = steps[stepIndex];\n if (!step || !hasPrefix(steps, pending.matched) || !matchesCombo(event, step)) continue;\n if (!accepts(layer, event)) return;\n event.preventDefault();\n // A held key neither advances nor completes a `repeat: false` sequence.\n if (event.repeat && layer.repeat === false) return;\n if (stepIndex === steps.length - 1) {\n reset();\n handler();\n } else {\n arm([...pending.matched, step], candidates, now);\n }\n return;\n }\n }\n // Expired or unexpected key: reset and evaluate the event normally below.\n reset();\n }\n\n // Sequence prefixes win over plain combos on the same key.\n const candidates = bindings.filter(({ steps, layer }) => {\n const [first] = steps;\n return steps.length > 1 && first && matchesCombo(event, first) && accepts(layer, event);\n });\n const first = candidates[0]?.steps[0];\n if (first) {\n event.preventDefault();\n arm([first], candidates, now);\n return;\n }\n\n for (const { steps, handler, layer } of bindings) {\n const [first] = steps;\n if (steps.length === 1 && first && matchesCombo(event, first)) {\n if (!accepts(layer, event)) return;\n event.preventDefault();\n if (event.repeat && layer.repeat === false) return;\n handler();\n return;\n }\n }\n };\n\n const register = (layer: KeyboardLayer) => {\n layers.set(layer, nextOrder++);\n return () => {\n layers.delete(layer);\n if (pending) {\n pending.candidates = pending.candidates.filter(candidate => candidate.layer !== layer);\n if (pending.candidates.length === 0) reset();\n }\n };\n };\n\n return { register, handleKeydown, reset };\n};\n"],"names":["candidates","first"],"mappings":"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"}
|
|
@@ -70,7 +70,7 @@ const KEYBOARD_CONSUMER_SELECTOR = [
|
|
|
70
70
|
"[data-radix-popper-content-wrapper]"
|
|
71
71
|
].join(", ");
|
|
72
72
|
const isKeyboardConsumer = (target) => target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;
|
|
73
|
-
const isTypingInConsumer = (event) => !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);
|
|
73
|
+
const isTypingInConsumer = (event) => event.target !== event.currentTarget && !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);
|
|
74
74
|
const sameCombo = (a, b) => a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;
|
|
75
75
|
const hasPrefix = (steps, prefix) => steps.length > prefix.length && prefix.every((step, i) => steps[i] !== void 0 && sameCombo(steps[i], step));
|
|
76
76
|
const canonicalCombo = (combo) => `${combo.meta ? "meta+" : ""}${combo.ctrl ? "ctrl+" : ""}${combo.alt ? "alt+" : ""}${combo.shift ? "shift+" : ""}${combo.key}`;
|
|
@@ -106,15 +106,13 @@ const createKeyboardDispatcher = () => {
|
|
|
106
106
|
}
|
|
107
107
|
return [...resolved.values()];
|
|
108
108
|
};
|
|
109
|
-
const accepts = (layer, event) => !layer.shouldHandle || layer.shouldHandle(event);
|
|
109
|
+
const accepts = (layer, event) => (layer.insideFields === true || !isTypingInConsumer(event)) && (!layer.shouldHandle || layer.shouldHandle(event));
|
|
110
110
|
const handleKeydown = (event) => {
|
|
111
111
|
const isImeComposition = event.isComposing || event.keyCode === 229;
|
|
112
112
|
if (event.defaultPrevented || isImeComposition) {
|
|
113
113
|
reset();
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
const isAncestorShortcut = event.target !== event.currentTarget;
|
|
117
|
-
if (isAncestorShortcut && isTypingInConsumer(event)) return;
|
|
118
116
|
const bindings = resolveBindings();
|
|
119
117
|
const now = Date.now();
|
|
120
118
|
if (pending) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-dispatcher.es.js","sources":["../../src/lib/keyboard/keyboard-dispatcher.ts"],"sourcesContent":["/**\n * Map of key bindings to handlers.\n *\n * - Combos: `'cmd+k'`, `'ctrl+shift+p'`, `'mod+Home'`.\n * - Timed sequences: `'g$+a'` — press `g`, then `a` within 500ms.\n * Chain as many steps as needed (`'a$+b$+c'`); the last step has no `$`.\n * A sequence prefix takes precedence over a plain combo on the same key, and an\n * unexpected key resets the sequence before being evaluated normally.\n */\nexport type UseKeydownArgs = {\n [keySet: string]: () => void;\n};\n\nexport type ParsedKeyCombo = {\n meta: boolean;\n ctrl: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n};\n\nconst isMacPlatform = () =>\n typeof navigator !== 'undefined' && /mac/i.test(navigator.platform || navigator.userAgent || '');\n\nexport const parseKeyCombo = (combo: string): ParsedKeyCombo => {\n const parsed: ParsedKeyCombo = { meta: false, ctrl: false, shift: false, alt: false, key: '' };\n\n for (const token of combo.split('+')) {\n switch (token.toLowerCase()) {\n case 'cmd':\n case 'meta':\n parsed.meta = true;\n break;\n case 'ctrl':\n case 'control':\n parsed.ctrl = true;\n break;\n case 'shift':\n parsed.shift = true;\n break;\n case 'alt':\n case 'option':\n parsed.alt = true;\n break;\n case 'mod':\n if (isMacPlatform()) parsed.meta = true;\n else parsed.ctrl = true;\n break;\n default:\n parsed.key = token.toLowerCase();\n }\n }\n\n return parsed;\n};\n\nexport type KeyStep = ParsedKeyCombo;\n\n/** A binding is a sequence of steps; a plain combo is a sequence of length 1. */\nexport type ParsedKeyBinding = KeyStep[];\n\nconst SEQUENCE_TIMEOUT_MS = 500;\nconst SEQUENCE_TOKEN = /^(.+)\\$$/;\n\n/**\n * Parses `cmd+k` (single step) or `g$+a` (sequence: `g`, then `a` within 500ms).\n * A `key$` token closes a step; the modifiers before it belong to that step.\n */\nexport const parseKeyBinding = (binding: string): ParsedKeyBinding => {\n const steps: KeyStep[] = [];\n let tokens: string[] = [];\n\n for (const token of binding.split('+')) {\n const [, sequenceKey] = SEQUENCE_TOKEN.exec(token) ?? [];\n if (sequenceKey) {\n steps.push(parseKeyCombo([...tokens, sequenceKey].join('+')));\n tokens = [];\n } else {\n tokens.push(token);\n }\n }\n\n if (tokens.length === 0) {\n throw new Error(`Invalid key binding \"${binding}\": the last step cannot end with $`);\n }\n steps.push(parseKeyCombo(tokens.join('+')));\n\n for (const step of steps) {\n if (!step.key) throw new Error(`Invalid key binding \"${binding}\": every step needs a key`);\n }\n\n return steps;\n};\n\n/**\n * Printable symbols like `?`, `!` or `:` are typed with Shift on most layouts, and\n * `event.key` already reflects the resulting character. For those, the Shift state\n * is irrelevant unless the binding asks for it explicitly.\n */\nconst isShiftedSymbol = (key: string) => key.length === 1 && !/[a-z0-9]/i.test(key);\n\nexport const matchesCombo = (event: KeyboardEvent, combo: ParsedKeyCombo): boolean =>\n event.metaKey === combo.meta &&\n event.ctrlKey === combo.ctrl &&\n (event.shiftKey === combo.shift || (!combo.shift && isShiftedSymbol(combo.key))) &&\n event.altKey === combo.alt &&\n event.key.toLowerCase() === combo.key;\n\nconst KEYBOARD_CONSUMER_SELECTOR = [\n 'input',\n 'textarea',\n 'select',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\" i]',\n '[contenteditable=\"plaintext-only\" i]',\n '[role=\"combobox\"]',\n '[role=\"listbox\"]',\n '[role=\"menu\"]',\n '[role=\"menuitem\"]',\n '[role=\"option\"]',\n '[role=\"dialog\"]',\n '[role=\"alertdialog\"]',\n '[data-radix-popper-content-wrapper]',\n].join(', ');\n\nexport const isKeyboardConsumer = (target: EventTarget | null): boolean =>\n target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;\n\n/**\n * Keys without meta/ctrl/alt (`?`, `g`, `Escape`, arrows…) belong to the\n * focused field or widget, so they must keep typing/navigating there. Combos\n * like `mod+k` are safe to intercept from anywhere.\n */\nconst isTypingInConsumer = (event: KeyboardEvent) =>\n !event.metaKey && !event.ctrlKey && !event.altKey && isKeyboardConsumer(event.target);\n\nconst sameCombo = (a: ParsedKeyCombo, b: ParsedKeyCombo) =>\n a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;\n\nconst hasPrefix = (steps: KeyStep[], prefix: KeyStep[]) =>\n steps.length > prefix.length && prefix.every((step, i) => steps[i] !== undefined && sameCombo(steps[i], step));\n\nconst canonicalCombo = (combo: ParsedKeyCombo) =>\n `${combo.meta ? 'meta+' : ''}${combo.ctrl ? 'ctrl+' : ''}${combo.alt ? 'alt+' : ''}${combo.shift ? 'shift+' : ''}${combo.key}`;\n\n/** Stable identity for a binding, so `cmd+k` and `meta+k` shadow each other. */\nconst canonicalBinding = (steps: KeyStep[]) => steps.map(canonicalCombo).join(' ');\n\n/**\n * A set of bindings registered by one `useKeydown` call. `depth` comes from the\n * nearest `KeyboardScope`; deeper layers shadow shallower ones binding by binding.\n */\nexport type KeyboardLayer = {\n depth: number;\n bindings: UseKeydownArgs;\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /** When `false`, auto-repeated keydowns from a held key don't fire handlers. */\n repeat?: boolean;\n};\n\ntype ResolvedBinding = {\n steps: KeyStep[];\n handler: () => void;\n layer: KeyboardLayer;\n};\n\ntype PendingSequence = {\n /** Steps already matched, as parsed combos (several bindings may share a prefix). */\n matched: KeyStep[];\n candidates: ResolvedBinding[];\n expiresAt: number;\n};\n\nexport type KeyboardDispatcher = {\n /** Registers a layer and returns its unregister function. */\n register: (layer: KeyboardLayer) => () => void;\n handleKeydown: (event: KeyboardEvent) => void;\n /** Forgets any armed sequence and clears its timer. */\n reset: () => void;\n};\n\n/**\n * Owns the layer registry and the single pending-sequence state for one event\n * target. Deeper layers win; on equal depth, the most recently registered wins.\n */\nexport const createKeyboardDispatcher = (): KeyboardDispatcher => {\n const layers = new Map<KeyboardLayer, number>();\n let nextOrder = 0;\n let pending: PendingSequence | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n\n const reset = () => {\n pending = undefined;\n if (expiryTimer !== undefined) {\n clearTimeout(expiryTimer);\n expiryTimer = undefined;\n }\n };\n\n const arm = (matched: KeyStep[], candidates: ResolvedBinding[], now: number) => {\n reset();\n pending = { matched, candidates, expiresAt: now + SEQUENCE_TIMEOUT_MS };\n expiryTimer = setTimeout(reset, SEQUENCE_TIMEOUT_MS);\n };\n\n const resolveBindings = (): ResolvedBinding[] => {\n const ranked = [...layers.entries()].sort(([a, orderA], [b, orderB]) =>\n b.depth !== a.depth ? b.depth - a.depth : orderB - orderA,\n );\n const resolved = new Map<string, ResolvedBinding>();\n for (const [layer] of ranked) {\n for (const [binding, handler] of Object.entries(layer.bindings)) {\n const steps = parseKeyBinding(binding);\n const key = canonicalBinding(steps);\n if (!resolved.has(key)) resolved.set(key, { steps, handler, layer });\n }\n }\n return [...resolved.values()];\n };\n\n const accepts = (layer: KeyboardLayer, event: KeyboardEvent) => !layer.shouldHandle || layer.shouldHandle(event);\n\n const handleKeydown = (event: KeyboardEvent) => {\n // IME boundary events can report 229 while isComposing is false.\n const isImeComposition = event.isComposing || event.keyCode === 229;\n if (event.defaultPrevented || isImeComposition) {\n reset();\n return;\n }\n const isAncestorShortcut = event.target !== event.currentTarget;\n if (isAncestorShortcut && isTypingInConsumer(event)) return;\n\n const bindings = resolveBindings();\n const now = Date.now();\n\n if (pending) {\n if (now < pending.expiresAt) {\n const stepIndex = pending.matched.length;\n const candidates = bindings.filter(binding =>\n pending?.candidates.some(\n candidate =>\n candidate.layer === binding.layer &&\n canonicalBinding(candidate.steps) === canonicalBinding(binding.steps),\n ),\n );\n for (const { steps, handler, layer } of candidates) {\n const step = steps[stepIndex];\n if (!step || !hasPrefix(steps, pending.matched) || !matchesCombo(event, step)) continue;\n if (!accepts(layer, event)) return;\n event.preventDefault();\n // A held key neither advances nor completes a `repeat: false` sequence.\n if (event.repeat && layer.repeat === false) return;\n if (stepIndex === steps.length - 1) {\n reset();\n handler();\n } else {\n arm([...pending.matched, step], candidates, now);\n }\n return;\n }\n }\n // Expired or unexpected key: reset and evaluate the event normally below.\n reset();\n }\n\n // Sequence prefixes win over plain combos on the same key.\n const candidates = bindings.filter(({ steps, layer }) => {\n const [first] = steps;\n return steps.length > 1 && first && matchesCombo(event, first) && accepts(layer, event);\n });\n const first = candidates[0]?.steps[0];\n if (first) {\n event.preventDefault();\n arm([first], candidates, now);\n return;\n }\n\n for (const { steps, handler, layer } of bindings) {\n const [first] = steps;\n if (steps.length === 1 && first && matchesCombo(event, first)) {\n if (!accepts(layer, event)) return;\n event.preventDefault();\n if (event.repeat && layer.repeat === false) return;\n handler();\n return;\n }\n }\n };\n\n const register = (layer: KeyboardLayer) => {\n layers.set(layer, nextOrder++);\n return () => {\n layers.delete(layer);\n if (pending) {\n pending.candidates = pending.candidates.filter(candidate => candidate.layer !== layer);\n if (pending.candidates.length === 0) reset();\n }\n };\n };\n\n return { register, handleKeydown, reset };\n};\n"],"names":["candidates","first"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keyboard-dispatcher.es.js","sources":["../../src/lib/keyboard/keyboard-dispatcher.ts"],"sourcesContent":["/**\n * Map of key bindings to handlers.\n *\n * - Combos: `'cmd+k'`, `'ctrl+shift+p'`, `'mod+Home'`.\n * - Timed sequences: `'g$+a'` — press `g`, then `a` within 500ms.\n * Chain as many steps as needed (`'a$+b$+c'`); the last step has no `$`.\n * A sequence prefix takes precedence over a plain combo on the same key, and an\n * unexpected key resets the sequence before being evaluated normally.\n */\nexport type UseKeydownArgs = {\n [keySet: string]: () => void;\n};\n\nexport type ParsedKeyCombo = {\n meta: boolean;\n ctrl: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n};\n\nconst isMacPlatform = () =>\n typeof navigator !== 'undefined' && /mac/i.test(navigator.platform || navigator.userAgent || '');\n\nexport const parseKeyCombo = (combo: string): ParsedKeyCombo => {\n const parsed: ParsedKeyCombo = { meta: false, ctrl: false, shift: false, alt: false, key: '' };\n\n for (const token of combo.split('+')) {\n switch (token.toLowerCase()) {\n case 'cmd':\n case 'meta':\n parsed.meta = true;\n break;\n case 'ctrl':\n case 'control':\n parsed.ctrl = true;\n break;\n case 'shift':\n parsed.shift = true;\n break;\n case 'alt':\n case 'option':\n parsed.alt = true;\n break;\n case 'mod':\n if (isMacPlatform()) parsed.meta = true;\n else parsed.ctrl = true;\n break;\n default:\n parsed.key = token.toLowerCase();\n }\n }\n\n return parsed;\n};\n\nexport type KeyStep = ParsedKeyCombo;\n\n/** A binding is a sequence of steps; a plain combo is a sequence of length 1. */\nexport type ParsedKeyBinding = KeyStep[];\n\nconst SEQUENCE_TIMEOUT_MS = 500;\nconst SEQUENCE_TOKEN = /^(.+)\\$$/;\n\n/**\n * Parses `cmd+k` (single step) or `g$+a` (sequence: `g`, then `a` within 500ms).\n * A `key$` token closes a step; the modifiers before it belong to that step.\n */\nexport const parseKeyBinding = (binding: string): ParsedKeyBinding => {\n const steps: KeyStep[] = [];\n let tokens: string[] = [];\n\n for (const token of binding.split('+')) {\n const [, sequenceKey] = SEQUENCE_TOKEN.exec(token) ?? [];\n if (sequenceKey) {\n steps.push(parseKeyCombo([...tokens, sequenceKey].join('+')));\n tokens = [];\n } else {\n tokens.push(token);\n }\n }\n\n if (tokens.length === 0) {\n throw new Error(`Invalid key binding \"${binding}\": the last step cannot end with $`);\n }\n steps.push(parseKeyCombo(tokens.join('+')));\n\n for (const step of steps) {\n if (!step.key) throw new Error(`Invalid key binding \"${binding}\": every step needs a key`);\n }\n\n return steps;\n};\n\n/**\n * Printable symbols like `?`, `!` or `:` are typed with Shift on most layouts, and\n * `event.key` already reflects the resulting character. For those, the Shift state\n * is irrelevant unless the binding asks for it explicitly.\n */\nconst isShiftedSymbol = (key: string) => key.length === 1 && !/[a-z0-9]/i.test(key);\n\nexport const matchesCombo = (event: KeyboardEvent, combo: ParsedKeyCombo): boolean =>\n event.metaKey === combo.meta &&\n event.ctrlKey === combo.ctrl &&\n (event.shiftKey === combo.shift || (!combo.shift && isShiftedSymbol(combo.key))) &&\n event.altKey === combo.alt &&\n event.key.toLowerCase() === combo.key;\n\nconst KEYBOARD_CONSUMER_SELECTOR = [\n 'input',\n 'textarea',\n 'select',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\" i]',\n '[contenteditable=\"plaintext-only\" i]',\n '[role=\"combobox\"]',\n '[role=\"listbox\"]',\n '[role=\"menu\"]',\n '[role=\"menuitem\"]',\n '[role=\"option\"]',\n '[role=\"dialog\"]',\n '[role=\"alertdialog\"]',\n '[data-radix-popper-content-wrapper]',\n].join(', ');\n\nexport const isKeyboardConsumer = (target: EventTarget | null): boolean =>\n target instanceof Element && target.closest(KEYBOARD_CONSUMER_SELECTOR) !== null;\n\n/**\n * Keys without meta/ctrl/alt (`?`, `g`, `Escape`, arrows…) belong to the\n * focused field or widget, so they must keep typing/navigating there. Combos\n * like `mod+k` are safe to intercept from anywhere.\n */\nconst isTypingInConsumer = (event: KeyboardEvent) =>\n event.target !== event.currentTarget &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n isKeyboardConsumer(event.target);\n\nconst sameCombo = (a: ParsedKeyCombo, b: ParsedKeyCombo) =>\n a.key === b.key && a.meta === b.meta && a.ctrl === b.ctrl && a.shift === b.shift && a.alt === b.alt;\n\nconst hasPrefix = (steps: KeyStep[], prefix: KeyStep[]) =>\n steps.length > prefix.length && prefix.every((step, i) => steps[i] !== undefined && sameCombo(steps[i], step));\n\nconst canonicalCombo = (combo: ParsedKeyCombo) =>\n `${combo.meta ? 'meta+' : ''}${combo.ctrl ? 'ctrl+' : ''}${combo.alt ? 'alt+' : ''}${combo.shift ? 'shift+' : ''}${combo.key}`;\n\n/** Stable identity for a binding, so `cmd+k` and `meta+k` shadow each other. */\nconst canonicalBinding = (steps: KeyStep[]) => steps.map(canonicalCombo).join(' ');\n\n/**\n * A set of bindings registered by one `useKeydown` call. `depth` comes from the\n * nearest `KeyboardScope`; deeper layers shadow shallower ones binding by binding.\n */\nexport type KeyboardLayer = {\n depth: number;\n bindings: UseKeydownArgs;\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /** When `true`, unmodified keys fire even while focus is in a field or widget. */\n insideFields?: boolean;\n /** When `false`, auto-repeated keydowns from a held key don't fire handlers. */\n repeat?: boolean;\n};\n\ntype ResolvedBinding = {\n steps: KeyStep[];\n handler: () => void;\n layer: KeyboardLayer;\n};\n\ntype PendingSequence = {\n /** Steps already matched, as parsed combos (several bindings may share a prefix). */\n matched: KeyStep[];\n candidates: ResolvedBinding[];\n expiresAt: number;\n};\n\nexport type KeyboardDispatcher = {\n /** Registers a layer and returns its unregister function. */\n register: (layer: KeyboardLayer) => () => void;\n handleKeydown: (event: KeyboardEvent) => void;\n /** Forgets any armed sequence and clears its timer. */\n reset: () => void;\n};\n\n/**\n * Owns the layer registry and the single pending-sequence state for one event\n * target. Deeper layers win; on equal depth, the most recently registered wins.\n */\nexport const createKeyboardDispatcher = (): KeyboardDispatcher => {\n const layers = new Map<KeyboardLayer, number>();\n let nextOrder = 0;\n let pending: PendingSequence | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n\n const reset = () => {\n pending = undefined;\n if (expiryTimer !== undefined) {\n clearTimeout(expiryTimer);\n expiryTimer = undefined;\n }\n };\n\n const arm = (matched: KeyStep[], candidates: ResolvedBinding[], now: number) => {\n reset();\n pending = { matched, candidates, expiresAt: now + SEQUENCE_TIMEOUT_MS };\n expiryTimer = setTimeout(reset, SEQUENCE_TIMEOUT_MS);\n };\n\n const resolveBindings = (): ResolvedBinding[] => {\n const ranked = [...layers.entries()].sort(([a, orderA], [b, orderB]) =>\n b.depth !== a.depth ? b.depth - a.depth : orderB - orderA,\n );\n const resolved = new Map<string, ResolvedBinding>();\n for (const [layer] of ranked) {\n for (const [binding, handler] of Object.entries(layer.bindings)) {\n const steps = parseKeyBinding(binding);\n const key = canonicalBinding(steps);\n if (!resolved.has(key)) resolved.set(key, { steps, handler, layer });\n }\n }\n return [...resolved.values()];\n };\n\n const accepts = (layer: KeyboardLayer, event: KeyboardEvent) =>\n (layer.insideFields === true || !isTypingInConsumer(event)) && (!layer.shouldHandle || layer.shouldHandle(event));\n\n const handleKeydown = (event: KeyboardEvent) => {\n // IME boundary events can report 229 while isComposing is false.\n const isImeComposition = event.isComposing || event.keyCode === 229;\n if (event.defaultPrevented || isImeComposition) {\n reset();\n return;\n }\n\n const bindings = resolveBindings();\n const now = Date.now();\n\n if (pending) {\n if (now < pending.expiresAt) {\n const stepIndex = pending.matched.length;\n const candidates = bindings.filter(binding =>\n pending?.candidates.some(\n candidate =>\n candidate.layer === binding.layer &&\n canonicalBinding(candidate.steps) === canonicalBinding(binding.steps),\n ),\n );\n for (const { steps, handler, layer } of candidates) {\n const step = steps[stepIndex];\n if (!step || !hasPrefix(steps, pending.matched) || !matchesCombo(event, step)) continue;\n if (!accepts(layer, event)) return;\n event.preventDefault();\n // A held key neither advances nor completes a `repeat: false` sequence.\n if (event.repeat && layer.repeat === false) return;\n if (stepIndex === steps.length - 1) {\n reset();\n handler();\n } else {\n arm([...pending.matched, step], candidates, now);\n }\n return;\n }\n }\n // Expired or unexpected key: reset and evaluate the event normally below.\n reset();\n }\n\n // Sequence prefixes win over plain combos on the same key.\n const candidates = bindings.filter(({ steps, layer }) => {\n const [first] = steps;\n return steps.length > 1 && first && matchesCombo(event, first) && accepts(layer, event);\n });\n const first = candidates[0]?.steps[0];\n if (first) {\n event.preventDefault();\n arm([first], candidates, now);\n return;\n }\n\n for (const { steps, handler, layer } of bindings) {\n const [first] = steps;\n if (steps.length === 1 && first && matchesCombo(event, first)) {\n if (!accepts(layer, event)) return;\n event.preventDefault();\n if (event.repeat && layer.repeat === false) return;\n handler();\n return;\n }\n }\n };\n\n const register = (layer: KeyboardLayer) => {\n layers.set(layer, nextOrder++);\n return () => {\n layers.delete(layer);\n if (pending) {\n pending.candidates = pending.candidates.filter(candidate => candidate.layer !== layer);\n if (pending.candidates.length === 0) reset();\n }\n };\n };\n\n return { register, handleKeydown, reset };\n};\n"],"names":["candidates","first"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-shortcuts-context.cjs.js","sources":["../../src/lib/keyboard/keyboard-shortcuts-context.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef
|
|
1
|
+
{"version":3,"file":"keyboard-shortcuts-context.cjs.js","sources":["../../src/lib/keyboard/keyboard-shortcuts-context.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { createKeyboardDispatcher } from './keyboard-dispatcher';\nimport type { KeyboardDispatcher } from './keyboard-dispatcher';\n\ntype KeyboardShortcutsContextValue = { status: 'missing' } | { status: 'ready'; dispatcher: KeyboardDispatcher };\n\nconst KeyboardShortcutsContext = createContext<KeyboardShortcutsContextValue>({ status: 'missing' });\nconst KeyboardScopeContext = createContext(0);\n\n/**\n * Hosts the single `window` keydown listener and the shared sequence state for\n * every `useKeydown` call in the tree. Mount once, at the root of the app.\n * Without it, each `useKeydown` listens on its own and no shadowing happens.\n */\nexport const KeyboardShortcutsProvider = ({ children }: { children: ReactNode }) => {\n const dispatcherRef = useRef<KeyboardDispatcher | undefined>(undefined);\n if (!dispatcherRef.current) dispatcherRef.current = createKeyboardDispatcher();\n const dispatcher = dispatcherRef.current;\n\n useEffect(() => {\n window.addEventListener('keydown', dispatcher.handleKeydown);\n return () => {\n window.removeEventListener('keydown', dispatcher.handleKeydown);\n dispatcher.reset();\n };\n }, [dispatcher]);\n\n const value = useMemo<KeyboardShortcutsContextValue>(() => ({ status: 'ready', dispatcher }), [dispatcher]);\n\n return (\n <KeyboardShortcutsContext.Provider value={value}>\n <KeyboardScopeContext.Provider value={0}>{children}</KeyboardScopeContext.Provider>\n </KeyboardShortcutsContext.Provider>\n );\n};\n\n/**\n * Marks a more specific keyboard context (a page, a panel). Shortcuts declared\n * inside shadow the same shortcuts declared outside, for as long as the scope\n * is mounted. Scopes nest: the deepest one wins.\n */\nexport const KeyboardScope = ({ children }: { children: ReactNode }) => {\n const depth = useContext(KeyboardScopeContext);\n return <KeyboardScopeContext.Provider value={depth + 1}>{children}</KeyboardScopeContext.Provider>;\n};\n\n// eslint-disable-next-line react-refresh/only-export-components -- provider and its hooks intentionally share this module\nexport const useKeyboardShortcutsContext = () => useContext(KeyboardShortcutsContext);\n// eslint-disable-next-line react-refresh/only-export-components -- provider and its hooks intentionally share this module\nexport const useKeyboardScopeDepth = () => useContext(KeyboardScopeContext);\n"],"names":["createContext","useRef","createKeyboardDispatcher","useEffect","useMemo","jsx","useContext"],"mappings":";;;;;;;;AAQA,MAAM,wBAAA,GAA2BA,mBAAA,CAA6C,EAAE,MAAA,EAAQ,WAAW,CAAA;AACnG,MAAM,oBAAA,GAAuBA,oBAAc,CAAC,CAAA;AAOrC,MAAM,yBAAA,GAA4B,CAAC,EAAE,QAAA,EAAS,KAA+B;AAClF,EAAA,MAAM,aAAA,GAAgBC,aAAuC,MAAS,CAAA;AACtE,EAAA,IAAI,CAAC,aAAA,CAAc,OAAA,EAAS,aAAA,CAAc,UAAUC,oDAAA,EAAyB;AAC7E,EAAA,MAAM,aAAa,aAAA,CAAc,OAAA;AAEjC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,UAAA,CAAW,aAAa,CAAA;AAC3D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,UAAA,CAAW,aAAa,CAAA;AAC9D,MAAA,UAAA,CAAW,KAAA,EAAM;AAAA,IACnB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,KAAA,GAAQC,aAAA,CAAuC,OAAO,EAAE,MAAA,EAAQ,SAAS,UAAA,EAAW,CAAA,EAAI,CAAC,UAAU,CAAC,CAAA;AAE1G,EAAA,uBACEC,cAAA,CAAC,wBAAA,CAAyB,QAAA,EAAzB,EAAkC,KAAA,EACjC,QAAA,kBAAAA,cAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,CAAA,EAAI,QAAA,EAAS,CAAA,EACrD,CAAA;AAEJ;AAOO,MAAM,aAAA,GAAgB,CAAC,EAAE,QAAA,EAAS,KAA+B;AACtE,EAAA,MAAM,KAAA,GAAQC,iBAAW,oBAAoB,CAAA;AAC7C,EAAA,sCAAQ,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,KAAA,GAAQ,GAAI,QAAA,EAAS,CAAA;AACpE;AAGO,MAAM,2BAAA,GAA8B,MAAMA,gBAAA,CAAW,wBAAwB;AAE7E,MAAM,qBAAA,GAAwB,MAAMA,gBAAA,CAAW,oBAAoB;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-shortcuts-context.es.js","sources":["../../src/lib/keyboard/keyboard-shortcuts-context.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef
|
|
1
|
+
{"version":3,"file":"keyboard-shortcuts-context.es.js","sources":["../../src/lib/keyboard/keyboard-shortcuts-context.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { createKeyboardDispatcher } from './keyboard-dispatcher';\nimport type { KeyboardDispatcher } from './keyboard-dispatcher';\n\ntype KeyboardShortcutsContextValue = { status: 'missing' } | { status: 'ready'; dispatcher: KeyboardDispatcher };\n\nconst KeyboardShortcutsContext = createContext<KeyboardShortcutsContextValue>({ status: 'missing' });\nconst KeyboardScopeContext = createContext(0);\n\n/**\n * Hosts the single `window` keydown listener and the shared sequence state for\n * every `useKeydown` call in the tree. Mount once, at the root of the app.\n * Without it, each `useKeydown` listens on its own and no shadowing happens.\n */\nexport const KeyboardShortcutsProvider = ({ children }: { children: ReactNode }) => {\n const dispatcherRef = useRef<KeyboardDispatcher | undefined>(undefined);\n if (!dispatcherRef.current) dispatcherRef.current = createKeyboardDispatcher();\n const dispatcher = dispatcherRef.current;\n\n useEffect(() => {\n window.addEventListener('keydown', dispatcher.handleKeydown);\n return () => {\n window.removeEventListener('keydown', dispatcher.handleKeydown);\n dispatcher.reset();\n };\n }, [dispatcher]);\n\n const value = useMemo<KeyboardShortcutsContextValue>(() => ({ status: 'ready', dispatcher }), [dispatcher]);\n\n return (\n <KeyboardShortcutsContext.Provider value={value}>\n <KeyboardScopeContext.Provider value={0}>{children}</KeyboardScopeContext.Provider>\n </KeyboardShortcutsContext.Provider>\n );\n};\n\n/**\n * Marks a more specific keyboard context (a page, a panel). Shortcuts declared\n * inside shadow the same shortcuts declared outside, for as long as the scope\n * is mounted. Scopes nest: the deepest one wins.\n */\nexport const KeyboardScope = ({ children }: { children: ReactNode }) => {\n const depth = useContext(KeyboardScopeContext);\n return <KeyboardScopeContext.Provider value={depth + 1}>{children}</KeyboardScopeContext.Provider>;\n};\n\n// eslint-disable-next-line react-refresh/only-export-components -- provider and its hooks intentionally share this module\nexport const useKeyboardShortcutsContext = () => useContext(KeyboardShortcutsContext);\n// eslint-disable-next-line react-refresh/only-export-components -- provider and its hooks intentionally share this module\nexport const useKeyboardScopeDepth = () => useContext(KeyboardScopeContext);\n"],"names":[],"mappings":";;;;AAQA,MAAM,wBAAA,GAA2B,aAAA,CAA6C,EAAE,MAAA,EAAQ,WAAW,CAAA;AACnG,MAAM,oBAAA,GAAuB,cAAc,CAAC,CAAA;AAOrC,MAAM,yBAAA,GAA4B,CAAC,EAAE,QAAA,EAAS,KAA+B;AAClF,EAAA,MAAM,aAAA,GAAgB,OAAuC,MAAS,CAAA;AACtE,EAAA,IAAI,CAAC,aAAA,CAAc,OAAA,EAAS,aAAA,CAAc,UAAU,wBAAA,EAAyB;AAC7E,EAAA,MAAM,aAAa,aAAA,CAAc,OAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,UAAA,CAAW,aAAa,CAAA;AAC3D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,UAAA,CAAW,aAAa,CAAA;AAC9D,MAAA,UAAA,CAAW,KAAA,EAAM;AAAA,IACnB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAuC,OAAO,EAAE,MAAA,EAAQ,SAAS,UAAA,EAAW,CAAA,EAAI,CAAC,UAAU,CAAC,CAAA;AAE1G,EAAA,uBACE,GAAA,CAAC,wBAAA,CAAyB,QAAA,EAAzB,EAAkC,KAAA,EACjC,QAAA,kBAAA,GAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,CAAA,EAAI,QAAA,EAAS,CAAA,EACrD,CAAA;AAEJ;AAOO,MAAM,aAAA,GAAgB,CAAC,EAAE,QAAA,EAAS,KAA+B;AACtE,EAAA,MAAM,KAAA,GAAQ,WAAW,oBAAoB,CAAA;AAC7C,EAAA,2BAAQ,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,KAAA,GAAQ,GAAI,QAAA,EAAS,CAAA;AACpE;AAGO,MAAM,2BAAA,GAA8B,MAAM,UAAA,CAAW,wBAAwB;AAE7E,MAAM,qBAAA,GAAwB,MAAM,UAAA,CAAW,oBAAoB;;;;"}
|
|
@@ -14,10 +14,12 @@ const useKeydown = (opts, options = {}) => {
|
|
|
14
14
|
depth,
|
|
15
15
|
bindings: opts,
|
|
16
16
|
shouldHandle: options.shouldHandle,
|
|
17
|
+
insideFields: options.insideFields,
|
|
17
18
|
repeat: options.repeat
|
|
18
19
|
});
|
|
19
20
|
layerRef.current.bindings = opts;
|
|
20
21
|
layerRef.current.shouldHandle = options.shouldHandle;
|
|
22
|
+
layerRef.current.insideFields = options.insideFields;
|
|
21
23
|
layerRef.current.repeat = options.repeat;
|
|
22
24
|
layerRef.current.depth = depth;
|
|
23
25
|
const shared = !target && shortcuts.status === "ready" ? shortcuts.dispatcher : void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-keydown.cjs.js","sources":["../../src/lib/keyboard/use-keydown.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from 'react';\n\nimport {\n createKeyboardDispatcher,\n isKeyboardConsumer,\n matchesCombo,\n parseKeyCombo,\n type KeyboardLayer,\n type ParsedKeyCombo,\n type UseKeydownArgs,\n} from './keyboard-dispatcher';\nimport { useKeyboardScopeDepth, useKeyboardShortcutsContext } from './keyboard-shortcuts-context';\n\nexport { parseKeyCombo, parseKeyBinding, matchesCombo } from './keyboard-dispatcher';\nexport type { UseKeydownArgs, KeyStep, ParsedKeyBinding } from './keyboard-dispatcher';\n\nexport type UseKeydownOptions = {\n /** Attach the listener to this element instead of `window`. */\n target?: RefObject<HTMLElement | null>;\n /** When `false`, no listener is attached. Defaults to `true`. */\n enabled?: boolean;\n /**\n * Called before any combo is matched. Return `false` to leave the event\n * untouched (no `preventDefault`, no handler). Runs on top of the built-in\n * rule that leaves unmodified keys to editable fields and keyboard widgets,\n * unless the listener targets that field directly.\n */\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /**\n * When `false`, holding a key runs its handler once instead of on every\n * auto-repeat (repeats are still default-prevented). Use it for toggles.\n * Defaults to `true`.\n */\n repeat?: boolean;\n};\n\n/**\n * Binds keyboard shortcuts (see `UseKeydownArgs` for the syntax).\n *\n * Inside a `KeyboardShortcutsProvider`, bindings join a shared registry: the\n * nearest `KeyboardScope` decides which declaration wins when several bind the\n * same keys, and bindings are dropped as soon as the component unmounts.\n * Without a provider, or with a `target`, the hook listens on its own and no\n * shadowing takes place.\n */\nexport const useKeydown = (opts: UseKeydownArgs, options: UseKeydownOptions = {}) => {\n const { enabled = true, target } = options;\n const shortcuts = useKeyboardShortcutsContext();\n const depth = useKeyboardScopeDepth();\n\n // Kept fresh on every render so the dispatcher always calls the latest handlers.\n const layerRef = useRef<KeyboardLayer>({\n depth,\n bindings: opts,\n shouldHandle: options.shouldHandle,\n repeat: options.repeat,\n });\n layerRef.current.bindings = opts;\n layerRef.current.shouldHandle = options.shouldHandle;\n layerRef.current.repeat = options.repeat;\n layerRef.current.depth = depth;\n\n const shared = !target && shortcuts.status === 'ready' ? shortcuts.dispatcher : undefined;\n\n useEffect(() => {\n if (!enabled) return;\n if (shared) return shared.register(layerRef.current);\n\n const element: HTMLElement | Window | null = target ? (target.current ?? null) : window;\n if (!element) return;\n\n const dispatcher = createKeyboardDispatcher();\n const unregister = dispatcher.register(layerRef.current);\n const handleKeyDown = (event: Event) => {\n if (event instanceof KeyboardEvent) dispatcher.handleKeydown(event);\n };\n\n element.addEventListener('keydown', handleKeyDown);\n return () => {\n element.removeEventListener('keydown', handleKeyDown);\n unregister();\n dispatcher.reset();\n };\n }, [enabled, target, shared]);\n};\n\nexport type UseTableKeydownArgs = {\n /** Number of rows in the table. */\n count: number;\n /** The scroll/list container; keyboard shortcuts only fire when focus is inside it. */\n containerRef: RefObject<HTMLElement | null>;\n /** Rows moved by PageUp/PageDown. Defaults to 10. */\n pageSize?: number;\n /** Initially active row index. Defaults to 0. */\n initialIndex?: number;\n /** Called when a row should be activated (for non-interactive rows). */\n onActivate?: (index: number) => void;\n /** Called with the next index before focus moves (e.g. virtualizer.scrollToIndex). */\n onNavigate?: (index: number) => void;\n /**\n * Also listen for ArrowUp/ArrowDown/PageUp/PageDown on `document`, so the\n * list can be navigated before any row has focus. Keys are ignored when the\n * event originates from an editable field, a keyboard widget (combobox, menu,\n * listbox…) or an open dialog/popover. Enable on at most one list per page.\n */\n global?: boolean;\n};\n\nexport const useTableKeydown = ({\n count,\n containerRef,\n pageSize = 10,\n initialIndex = 0,\n onActivate,\n onNavigate,\n global = false,\n}: UseTableKeydownArgs) => {\n const [activeIndex, setActiveIndex] = useState(initialIndex);\n\n const clamp = (index: number) => Math.min(Math.max(index, 0), Math.max(count - 1, 0));\n\n const navigateTo = (index: number) => {\n const next = clamp(index);\n setActiveIndex(next);\n onNavigate?.(next);\n\n const rowElement = containerRef.current?.querySelector<HTMLElement>(`[data-row-index=\"${next}\"]`);\n if (rowElement) {\n rowElement.focus();\n rowElement.scrollIntoView?.({ block: 'nearest' });\n }\n };\n\n const combos: Array<[ParsedKeyCombo, () => void]> = [\n [parseKeyCombo('mod+Home'), () => navigateTo(0)],\n [parseKeyCombo('mod+End'), () => navigateTo(count - 1)],\n [parseKeyCombo('ArrowUp'), () => navigateTo(activeIndex - 1)],\n [parseKeyCombo('ArrowDown'), () => navigateTo(activeIndex + 1)],\n [parseKeyCombo('PageUp'), () => navigateTo(activeIndex - pageSize)],\n [parseKeyCombo('PageDown'), () => navigateTo(activeIndex + pageSize)],\n [parseKeyCombo('Home'), () => navigateTo(0)],\n [parseKeyCombo('End'), () => navigateTo(count - 1)],\n ];\n\n // Handled at row level (not via a container listener) so keyboard nav works\n // even when the list mounts after the hook, e.g. inside a tab panel.\n const handleRowKeyDown = (event: { nativeEvent: KeyboardEvent; preventDefault: () => void }) => {\n for (const [combo, handler] of combos) {\n if (matchesCombo(event.nativeEvent, combo)) {\n event.preventDefault();\n handler();\n return;\n }\n }\n };\n\n // When focus is outside the list, the first ArrowUp/ArrowDown press lands on\n // the current row instead of skipping past it.\n const focusIsInList = () => containerRef.current?.contains(document.activeElement) ?? false;\n const step = (delta: number) => navigateTo(focusIsInList() ? activeIndex + delta : activeIndex);\n\n useKeydown(\n {\n ArrowUp: () => step(-1),\n ArrowDown: () => step(1),\n PageUp: () => navigateTo(activeIndex - pageSize),\n PageDown: () => navigateTo(activeIndex + pageSize),\n },\n {\n enabled: global,\n shouldHandle: event => !event.defaultPrevented && count > 0 && !isKeyboardConsumer(event.target),\n },\n );\n\n useEffect(() => {\n if (activeIndex >= count) {\n setActiveIndex(Math.max(count - 1, 0));\n }\n }, [activeIndex, count]);\n\n const getRowProps = (index: number) => ({\n tabIndex: index === activeIndex ? 0 : -1,\n 'data-row-index': index,\n onFocus: () => setActiveIndex(index),\n onKeyDown: handleRowKeyDown,\n });\n\n const getContainerProps = () => ({});\n\n return {\n activeIndex,\n setActiveIndex,\n activate: (index: number) => onActivate?.(index),\n getRowProps,\n getContainerProps,\n };\n};\n"],"names":["useKeyboardShortcutsContext","useKeyboardScopeDepth","useRef","useEffect","createKeyboardDispatcher","useState","parseKeyCombo","matchesCombo","isKeyboardConsumer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-keydown.cjs.js","sources":["../../src/lib/keyboard/use-keydown.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\n\nimport { createKeyboardDispatcher, isKeyboardConsumer, matchesCombo, parseKeyCombo } from './keyboard-dispatcher';\nimport type { KeyboardLayer, ParsedKeyCombo, UseKeydownArgs } from './keyboard-dispatcher';\nimport { useKeyboardScopeDepth, useKeyboardShortcutsContext } from './keyboard-shortcuts-context';\n\nexport { parseKeyCombo, parseKeyBinding, matchesCombo } from './keyboard-dispatcher';\nexport type { UseKeydownArgs, KeyStep, ParsedKeyBinding } from './keyboard-dispatcher';\n\nexport type UseKeydownOptions = {\n /** Attach the listener to this element instead of `window`. */\n target?: RefObject<HTMLElement | null>;\n /** When `false`, no listener is attached. Defaults to `true`. */\n enabled?: boolean;\n /**\n * Called before any combo is matched. Return `false` to leave the event\n * untouched (no `preventDefault`, no handler). Runs on top of the built-in\n * rule that leaves unmodified keys to editable fields and keyboard widgets,\n * unless the listener targets that field directly or `insideFields` is set.\n */\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /**\n * When `true`, unmodified keys also fire while focus is inside an editable\n * field or keyboard widget, e.g. Escape closing a panel from its comment box.\n * Keys a widget already handled (default-prevented) are still skipped.\n * Defaults to `false`.\n */\n insideFields?: boolean;\n /**\n * When `false`, holding a key runs its handler once instead of on every\n * auto-repeat (repeats are still default-prevented). Use it for toggles.\n * Defaults to `true`.\n */\n repeat?: boolean;\n};\n\n/**\n * Binds keyboard shortcuts (see `UseKeydownArgs` for the syntax).\n *\n * Inside a `KeyboardShortcutsProvider`, bindings join a shared registry: the\n * nearest `KeyboardScope` decides which declaration wins when several bind the\n * same keys, and bindings are dropped as soon as the component unmounts.\n * Without a provider, or with a `target`, the hook listens on its own and no\n * shadowing takes place.\n */\nexport const useKeydown = (opts: UseKeydownArgs, options: UseKeydownOptions = {}) => {\n const { enabled = true, target } = options;\n const shortcuts = useKeyboardShortcutsContext();\n const depth = useKeyboardScopeDepth();\n\n // Kept fresh on every render so the dispatcher always calls the latest handlers.\n const layerRef = useRef<KeyboardLayer>({\n depth,\n bindings: opts,\n shouldHandle: options.shouldHandle,\n insideFields: options.insideFields,\n repeat: options.repeat,\n });\n layerRef.current.bindings = opts;\n layerRef.current.shouldHandle = options.shouldHandle;\n layerRef.current.insideFields = options.insideFields;\n layerRef.current.repeat = options.repeat;\n layerRef.current.depth = depth;\n\n const shared = !target && shortcuts.status === 'ready' ? shortcuts.dispatcher : undefined;\n\n useEffect(() => {\n if (!enabled) return;\n if (shared) return shared.register(layerRef.current);\n\n const element: HTMLElement | Window | null = target ? (target.current ?? null) : window;\n if (!element) return;\n\n const dispatcher = createKeyboardDispatcher();\n const unregister = dispatcher.register(layerRef.current);\n const handleKeyDown = (event: Event) => {\n if (event instanceof KeyboardEvent) dispatcher.handleKeydown(event);\n };\n\n element.addEventListener('keydown', handleKeyDown);\n return () => {\n element.removeEventListener('keydown', handleKeyDown);\n unregister();\n dispatcher.reset();\n };\n }, [enabled, target, shared]);\n};\n\nexport type UseTableKeydownArgs = {\n /** Number of rows in the table. */\n count: number;\n /** The scroll/list container; keyboard shortcuts only fire when focus is inside it. */\n containerRef: RefObject<HTMLElement | null>;\n /** Rows moved by PageUp/PageDown. Defaults to 10. */\n pageSize?: number;\n /** Initially active row index. Defaults to 0. */\n initialIndex?: number;\n /** Called when a row should be activated (for non-interactive rows). */\n onActivate?: (index: number) => void;\n /** Called with the next index before focus moves (e.g. virtualizer.scrollToIndex). */\n onNavigate?: (index: number) => void;\n /**\n * Also listen for ArrowUp/ArrowDown/PageUp/PageDown on `document`, so the\n * list can be navigated before any row has focus. Keys are ignored when the\n * event originates from an editable field, a keyboard widget (combobox, menu,\n * listbox…) or an open dialog/popover. Enable on at most one list per page.\n */\n global?: boolean;\n};\n\nexport const useTableKeydown = ({\n count,\n containerRef,\n pageSize = 10,\n initialIndex = 0,\n onActivate,\n onNavigate,\n global = false,\n}: UseTableKeydownArgs) => {\n const [activeIndex, setActiveIndex] = useState(initialIndex);\n\n const clamp = (index: number) => Math.min(Math.max(index, 0), Math.max(count - 1, 0));\n\n const navigateTo = (index: number) => {\n const next = clamp(index);\n setActiveIndex(next);\n onNavigate?.(next);\n\n const rowElement = containerRef.current?.querySelector<HTMLElement>(`[data-row-index=\"${next}\"]`);\n if (rowElement) {\n rowElement.focus();\n rowElement.scrollIntoView?.({ block: 'nearest' });\n }\n };\n\n const combos: Array<[ParsedKeyCombo, () => void]> = [\n [parseKeyCombo('mod+Home'), () => navigateTo(0)],\n [parseKeyCombo('mod+End'), () => navigateTo(count - 1)],\n [parseKeyCombo('ArrowUp'), () => navigateTo(activeIndex - 1)],\n [parseKeyCombo('ArrowDown'), () => navigateTo(activeIndex + 1)],\n [parseKeyCombo('PageUp'), () => navigateTo(activeIndex - pageSize)],\n [parseKeyCombo('PageDown'), () => navigateTo(activeIndex + pageSize)],\n [parseKeyCombo('Home'), () => navigateTo(0)],\n [parseKeyCombo('End'), () => navigateTo(count - 1)],\n ];\n\n // Handled at row level (not via a container listener) so keyboard nav works\n // even when the list mounts after the hook, e.g. inside a tab panel.\n const handleRowKeyDown = (event: { nativeEvent: KeyboardEvent; preventDefault: () => void }) => {\n for (const [combo, handler] of combos) {\n if (matchesCombo(event.nativeEvent, combo)) {\n event.preventDefault();\n handler();\n return;\n }\n }\n };\n\n // When focus is outside the list, the first ArrowUp/ArrowDown press lands on\n // the current row instead of skipping past it.\n const focusIsInList = () => containerRef.current?.contains(document.activeElement) ?? false;\n const step = (delta: number) => navigateTo(focusIsInList() ? activeIndex + delta : activeIndex);\n\n useKeydown(\n {\n ArrowUp: () => step(-1),\n ArrowDown: () => step(1),\n PageUp: () => navigateTo(activeIndex - pageSize),\n PageDown: () => navigateTo(activeIndex + pageSize),\n },\n {\n enabled: global,\n shouldHandle: event => !event.defaultPrevented && count > 0 && !isKeyboardConsumer(event.target),\n },\n );\n\n useEffect(() => {\n if (activeIndex >= count) {\n setActiveIndex(Math.max(count - 1, 0));\n }\n }, [activeIndex, count]);\n\n const getRowProps = (index: number) => ({\n tabIndex: index === activeIndex ? 0 : -1,\n 'data-row-index': index,\n onFocus: () => setActiveIndex(index),\n onKeyDown: handleRowKeyDown,\n });\n\n const getContainerProps = () => ({});\n\n return {\n activeIndex,\n setActiveIndex,\n activate: (index: number) => onActivate?.(index),\n getRowProps,\n getContainerProps,\n };\n};\n"],"names":["useKeyboardShortcutsContext","useKeyboardScopeDepth","useRef","useEffect","createKeyboardDispatcher","useState","parseKeyCombo","matchesCombo","isKeyboardConsumer"],"mappings":"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"}
|
|
@@ -11,10 +11,12 @@ const useKeydown = (opts, options = {}) => {
|
|
|
11
11
|
depth,
|
|
12
12
|
bindings: opts,
|
|
13
13
|
shouldHandle: options.shouldHandle,
|
|
14
|
+
insideFields: options.insideFields,
|
|
14
15
|
repeat: options.repeat
|
|
15
16
|
});
|
|
16
17
|
layerRef.current.bindings = opts;
|
|
17
18
|
layerRef.current.shouldHandle = options.shouldHandle;
|
|
19
|
+
layerRef.current.insideFields = options.insideFields;
|
|
18
20
|
layerRef.current.repeat = options.repeat;
|
|
19
21
|
layerRef.current.depth = depth;
|
|
20
22
|
const shared = !target && shortcuts.status === "ready" ? shortcuts.dispatcher : void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-keydown.es.js","sources":["../../src/lib/keyboard/use-keydown.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from 'react';\n\nimport {\n createKeyboardDispatcher,\n isKeyboardConsumer,\n matchesCombo,\n parseKeyCombo,\n type KeyboardLayer,\n type ParsedKeyCombo,\n type UseKeydownArgs,\n} from './keyboard-dispatcher';\nimport { useKeyboardScopeDepth, useKeyboardShortcutsContext } from './keyboard-shortcuts-context';\n\nexport { parseKeyCombo, parseKeyBinding, matchesCombo } from './keyboard-dispatcher';\nexport type { UseKeydownArgs, KeyStep, ParsedKeyBinding } from './keyboard-dispatcher';\n\nexport type UseKeydownOptions = {\n /** Attach the listener to this element instead of `window`. */\n target?: RefObject<HTMLElement | null>;\n /** When `false`, no listener is attached. Defaults to `true`. */\n enabled?: boolean;\n /**\n * Called before any combo is matched. Return `false` to leave the event\n * untouched (no `preventDefault`, no handler). Runs on top of the built-in\n * rule that leaves unmodified keys to editable fields and keyboard widgets,\n * unless the listener targets that field directly.\n */\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /**\n * When `false`, holding a key runs its handler once instead of on every\n * auto-repeat (repeats are still default-prevented). Use it for toggles.\n * Defaults to `true`.\n */\n repeat?: boolean;\n};\n\n/**\n * Binds keyboard shortcuts (see `UseKeydownArgs` for the syntax).\n *\n * Inside a `KeyboardShortcutsProvider`, bindings join a shared registry: the\n * nearest `KeyboardScope` decides which declaration wins when several bind the\n * same keys, and bindings are dropped as soon as the component unmounts.\n * Without a provider, or with a `target`, the hook listens on its own and no\n * shadowing takes place.\n */\nexport const useKeydown = (opts: UseKeydownArgs, options: UseKeydownOptions = {}) => {\n const { enabled = true, target } = options;\n const shortcuts = useKeyboardShortcutsContext();\n const depth = useKeyboardScopeDepth();\n\n // Kept fresh on every render so the dispatcher always calls the latest handlers.\n const layerRef = useRef<KeyboardLayer>({\n depth,\n bindings: opts,\n shouldHandle: options.shouldHandle,\n repeat: options.repeat,\n });\n layerRef.current.bindings = opts;\n layerRef.current.shouldHandle = options.shouldHandle;\n layerRef.current.repeat = options.repeat;\n layerRef.current.depth = depth;\n\n const shared = !target && shortcuts.status === 'ready' ? shortcuts.dispatcher : undefined;\n\n useEffect(() => {\n if (!enabled) return;\n if (shared) return shared.register(layerRef.current);\n\n const element: HTMLElement | Window | null = target ? (target.current ?? null) : window;\n if (!element) return;\n\n const dispatcher = createKeyboardDispatcher();\n const unregister = dispatcher.register(layerRef.current);\n const handleKeyDown = (event: Event) => {\n if (event instanceof KeyboardEvent) dispatcher.handleKeydown(event);\n };\n\n element.addEventListener('keydown', handleKeyDown);\n return () => {\n element.removeEventListener('keydown', handleKeyDown);\n unregister();\n dispatcher.reset();\n };\n }, [enabled, target, shared]);\n};\n\nexport type UseTableKeydownArgs = {\n /** Number of rows in the table. */\n count: number;\n /** The scroll/list container; keyboard shortcuts only fire when focus is inside it. */\n containerRef: RefObject<HTMLElement | null>;\n /** Rows moved by PageUp/PageDown. Defaults to 10. */\n pageSize?: number;\n /** Initially active row index. Defaults to 0. */\n initialIndex?: number;\n /** Called when a row should be activated (for non-interactive rows). */\n onActivate?: (index: number) => void;\n /** Called with the next index before focus moves (e.g. virtualizer.scrollToIndex). */\n onNavigate?: (index: number) => void;\n /**\n * Also listen for ArrowUp/ArrowDown/PageUp/PageDown on `document`, so the\n * list can be navigated before any row has focus. Keys are ignored when the\n * event originates from an editable field, a keyboard widget (combobox, menu,\n * listbox…) or an open dialog/popover. Enable on at most one list per page.\n */\n global?: boolean;\n};\n\nexport const useTableKeydown = ({\n count,\n containerRef,\n pageSize = 10,\n initialIndex = 0,\n onActivate,\n onNavigate,\n global = false,\n}: UseTableKeydownArgs) => {\n const [activeIndex, setActiveIndex] = useState(initialIndex);\n\n const clamp = (index: number) => Math.min(Math.max(index, 0), Math.max(count - 1, 0));\n\n const navigateTo = (index: number) => {\n const next = clamp(index);\n setActiveIndex(next);\n onNavigate?.(next);\n\n const rowElement = containerRef.current?.querySelector<HTMLElement>(`[data-row-index=\"${next}\"]`);\n if (rowElement) {\n rowElement.focus();\n rowElement.scrollIntoView?.({ block: 'nearest' });\n }\n };\n\n const combos: Array<[ParsedKeyCombo, () => void]> = [\n [parseKeyCombo('mod+Home'), () => navigateTo(0)],\n [parseKeyCombo('mod+End'), () => navigateTo(count - 1)],\n [parseKeyCombo('ArrowUp'), () => navigateTo(activeIndex - 1)],\n [parseKeyCombo('ArrowDown'), () => navigateTo(activeIndex + 1)],\n [parseKeyCombo('PageUp'), () => navigateTo(activeIndex - pageSize)],\n [parseKeyCombo('PageDown'), () => navigateTo(activeIndex + pageSize)],\n [parseKeyCombo('Home'), () => navigateTo(0)],\n [parseKeyCombo('End'), () => navigateTo(count - 1)],\n ];\n\n // Handled at row level (not via a container listener) so keyboard nav works\n // even when the list mounts after the hook, e.g. inside a tab panel.\n const handleRowKeyDown = (event: { nativeEvent: KeyboardEvent; preventDefault: () => void }) => {\n for (const [combo, handler] of combos) {\n if (matchesCombo(event.nativeEvent, combo)) {\n event.preventDefault();\n handler();\n return;\n }\n }\n };\n\n // When focus is outside the list, the first ArrowUp/ArrowDown press lands on\n // the current row instead of skipping past it.\n const focusIsInList = () => containerRef.current?.contains(document.activeElement) ?? false;\n const step = (delta: number) => navigateTo(focusIsInList() ? activeIndex + delta : activeIndex);\n\n useKeydown(\n {\n ArrowUp: () => step(-1),\n ArrowDown: () => step(1),\n PageUp: () => navigateTo(activeIndex - pageSize),\n PageDown: () => navigateTo(activeIndex + pageSize),\n },\n {\n enabled: global,\n shouldHandle: event => !event.defaultPrevented && count > 0 && !isKeyboardConsumer(event.target),\n },\n );\n\n useEffect(() => {\n if (activeIndex >= count) {\n setActiveIndex(Math.max(count - 1, 0));\n }\n }, [activeIndex, count]);\n\n const getRowProps = (index: number) => ({\n tabIndex: index === activeIndex ? 0 : -1,\n 'data-row-index': index,\n onFocus: () => setActiveIndex(index),\n onKeyDown: handleRowKeyDown,\n });\n\n const getContainerProps = () => ({});\n\n return {\n activeIndex,\n setActiveIndex,\n activate: (index: number) => onActivate?.(index),\n getRowProps,\n getContainerProps,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-keydown.es.js","sources":["../../src/lib/keyboard/use-keydown.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\n\nimport { createKeyboardDispatcher, isKeyboardConsumer, matchesCombo, parseKeyCombo } from './keyboard-dispatcher';\nimport type { KeyboardLayer, ParsedKeyCombo, UseKeydownArgs } from './keyboard-dispatcher';\nimport { useKeyboardScopeDepth, useKeyboardShortcutsContext } from './keyboard-shortcuts-context';\n\nexport { parseKeyCombo, parseKeyBinding, matchesCombo } from './keyboard-dispatcher';\nexport type { UseKeydownArgs, KeyStep, ParsedKeyBinding } from './keyboard-dispatcher';\n\nexport type UseKeydownOptions = {\n /** Attach the listener to this element instead of `window`. */\n target?: RefObject<HTMLElement | null>;\n /** When `false`, no listener is attached. Defaults to `true`. */\n enabled?: boolean;\n /**\n * Called before any combo is matched. Return `false` to leave the event\n * untouched (no `preventDefault`, no handler). Runs on top of the built-in\n * rule that leaves unmodified keys to editable fields and keyboard widgets,\n * unless the listener targets that field directly or `insideFields` is set.\n */\n shouldHandle?: (event: KeyboardEvent) => boolean;\n /**\n * When `true`, unmodified keys also fire while focus is inside an editable\n * field or keyboard widget, e.g. Escape closing a panel from its comment box.\n * Keys a widget already handled (default-prevented) are still skipped.\n * Defaults to `false`.\n */\n insideFields?: boolean;\n /**\n * When `false`, holding a key runs its handler once instead of on every\n * auto-repeat (repeats are still default-prevented). Use it for toggles.\n * Defaults to `true`.\n */\n repeat?: boolean;\n};\n\n/**\n * Binds keyboard shortcuts (see `UseKeydownArgs` for the syntax).\n *\n * Inside a `KeyboardShortcutsProvider`, bindings join a shared registry: the\n * nearest `KeyboardScope` decides which declaration wins when several bind the\n * same keys, and bindings are dropped as soon as the component unmounts.\n * Without a provider, or with a `target`, the hook listens on its own and no\n * shadowing takes place.\n */\nexport const useKeydown = (opts: UseKeydownArgs, options: UseKeydownOptions = {}) => {\n const { enabled = true, target } = options;\n const shortcuts = useKeyboardShortcutsContext();\n const depth = useKeyboardScopeDepth();\n\n // Kept fresh on every render so the dispatcher always calls the latest handlers.\n const layerRef = useRef<KeyboardLayer>({\n depth,\n bindings: opts,\n shouldHandle: options.shouldHandle,\n insideFields: options.insideFields,\n repeat: options.repeat,\n });\n layerRef.current.bindings = opts;\n layerRef.current.shouldHandle = options.shouldHandle;\n layerRef.current.insideFields = options.insideFields;\n layerRef.current.repeat = options.repeat;\n layerRef.current.depth = depth;\n\n const shared = !target && shortcuts.status === 'ready' ? shortcuts.dispatcher : undefined;\n\n useEffect(() => {\n if (!enabled) return;\n if (shared) return shared.register(layerRef.current);\n\n const element: HTMLElement | Window | null = target ? (target.current ?? null) : window;\n if (!element) return;\n\n const dispatcher = createKeyboardDispatcher();\n const unregister = dispatcher.register(layerRef.current);\n const handleKeyDown = (event: Event) => {\n if (event instanceof KeyboardEvent) dispatcher.handleKeydown(event);\n };\n\n element.addEventListener('keydown', handleKeyDown);\n return () => {\n element.removeEventListener('keydown', handleKeyDown);\n unregister();\n dispatcher.reset();\n };\n }, [enabled, target, shared]);\n};\n\nexport type UseTableKeydownArgs = {\n /** Number of rows in the table. */\n count: number;\n /** The scroll/list container; keyboard shortcuts only fire when focus is inside it. */\n containerRef: RefObject<HTMLElement | null>;\n /** Rows moved by PageUp/PageDown. Defaults to 10. */\n pageSize?: number;\n /** Initially active row index. Defaults to 0. */\n initialIndex?: number;\n /** Called when a row should be activated (for non-interactive rows). */\n onActivate?: (index: number) => void;\n /** Called with the next index before focus moves (e.g. virtualizer.scrollToIndex). */\n onNavigate?: (index: number) => void;\n /**\n * Also listen for ArrowUp/ArrowDown/PageUp/PageDown on `document`, so the\n * list can be navigated before any row has focus. Keys are ignored when the\n * event originates from an editable field, a keyboard widget (combobox, menu,\n * listbox…) or an open dialog/popover. Enable on at most one list per page.\n */\n global?: boolean;\n};\n\nexport const useTableKeydown = ({\n count,\n containerRef,\n pageSize = 10,\n initialIndex = 0,\n onActivate,\n onNavigate,\n global = false,\n}: UseTableKeydownArgs) => {\n const [activeIndex, setActiveIndex] = useState(initialIndex);\n\n const clamp = (index: number) => Math.min(Math.max(index, 0), Math.max(count - 1, 0));\n\n const navigateTo = (index: number) => {\n const next = clamp(index);\n setActiveIndex(next);\n onNavigate?.(next);\n\n const rowElement = containerRef.current?.querySelector<HTMLElement>(`[data-row-index=\"${next}\"]`);\n if (rowElement) {\n rowElement.focus();\n rowElement.scrollIntoView?.({ block: 'nearest' });\n }\n };\n\n const combos: Array<[ParsedKeyCombo, () => void]> = [\n [parseKeyCombo('mod+Home'), () => navigateTo(0)],\n [parseKeyCombo('mod+End'), () => navigateTo(count - 1)],\n [parseKeyCombo('ArrowUp'), () => navigateTo(activeIndex - 1)],\n [parseKeyCombo('ArrowDown'), () => navigateTo(activeIndex + 1)],\n [parseKeyCombo('PageUp'), () => navigateTo(activeIndex - pageSize)],\n [parseKeyCombo('PageDown'), () => navigateTo(activeIndex + pageSize)],\n [parseKeyCombo('Home'), () => navigateTo(0)],\n [parseKeyCombo('End'), () => navigateTo(count - 1)],\n ];\n\n // Handled at row level (not via a container listener) so keyboard nav works\n // even when the list mounts after the hook, e.g. inside a tab panel.\n const handleRowKeyDown = (event: { nativeEvent: KeyboardEvent; preventDefault: () => void }) => {\n for (const [combo, handler] of combos) {\n if (matchesCombo(event.nativeEvent, combo)) {\n event.preventDefault();\n handler();\n return;\n }\n }\n };\n\n // When focus is outside the list, the first ArrowUp/ArrowDown press lands on\n // the current row instead of skipping past it.\n const focusIsInList = () => containerRef.current?.contains(document.activeElement) ?? false;\n const step = (delta: number) => navigateTo(focusIsInList() ? activeIndex + delta : activeIndex);\n\n useKeydown(\n {\n ArrowUp: () => step(-1),\n ArrowDown: () => step(1),\n PageUp: () => navigateTo(activeIndex - pageSize),\n PageDown: () => navigateTo(activeIndex + pageSize),\n },\n {\n enabled: global,\n shouldHandle: event => !event.defaultPrevented && count > 0 && !isKeyboardConsumer(event.target),\n },\n );\n\n useEffect(() => {\n if (activeIndex >= count) {\n setActiveIndex(Math.max(count - 1, 0));\n }\n }, [activeIndex, count]);\n\n const getRowProps = (index: number) => ({\n tabIndex: index === activeIndex ? 0 : -1,\n 'data-row-index': index,\n onFocus: () => setActiveIndex(index),\n onKeyDown: handleRowKeyDown,\n });\n\n const getContainerProps = () => ({});\n\n return {\n activeIndex,\n setActiveIndex,\n activate: (index: number) => onActivate?.(index),\n getRowProps,\n getContainerProps,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -5,14 +5,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
require('../tabbed-container.css');const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const lucideReact = require('lucide-react');
|
|
7
7
|
const React = require('react');
|
|
8
|
-
const combobox = require('../combobox-
|
|
9
|
-
const dataList = require('../data-list-
|
|
10
|
-
const listSearch = require('../list-search-
|
|
8
|
+
const combobox = require('../combobox-DbZAWh8q.cjs');
|
|
9
|
+
const dataList = require('../data-list-DlXU1PLQ.cjs');
|
|
10
|
+
const listSearch = require('../list-search-DNJVeHmK.cjs');
|
|
11
11
|
const tabsContent = require('../tabs-content-B16298Ur.cjs');
|
|
12
12
|
const tabsContext = require('../tabs-context-pnspPkI-.cjs');
|
|
13
13
|
const tabsList = require('../tabs-list-BTRYiT_o.cjs');
|
|
14
14
|
const tabsRoot = require('../tabs-root-sOhEgFZ-.cjs');
|
|
15
|
-
const tabsTab = require('../tabs-tab-
|
|
15
|
+
const tabsTab = require('../tabs-tab-B0W25Dm2.cjs');
|
|
16
16
|
const tooltip = require('../tooltip-BppwIf6Y.cjs');
|
|
17
17
|
const Txt = require('../Txt-CIS2G5Jx.cjs');
|
|
18
18
|
const utils_cn = require('../cn-DlOJCxrS.cjs');
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { ListFilterIcon } from 'lucide-react';
|
|
3
3
|
import { Children, isValidElement, useContext } from 'react';
|
|
4
|
-
import { C as Combobox } from '../combobox-
|
|
5
|
-
import {
|
|
6
|
-
import { L as ListSearch } from '../list-search-
|
|
4
|
+
import { C as Combobox } from '../combobox-BCoCVZHs.js';
|
|
5
|
+
import { e as DataList } from '../data-list-Tor18oy5.js';
|
|
6
|
+
import { L as ListSearch } from '../list-search-ByJdIxIh.js';
|
|
7
7
|
import { T as TabContent } from '../tabs-content-DEnFKGyJ.js';
|
|
8
8
|
import { T as TabsContext } from '../tabs-context-Cbuw7i0u.js';
|
|
9
9
|
import { T as TabList } from '../tabs-list-BCnrYcX1.js';
|
|
10
10
|
import { T as Tabs } from '../tabs-root-CI7WQrJF.js';
|
|
11
|
-
import { T as Tab } from '../tabs-tab-
|
|
11
|
+
import { T as Tab } from '../tabs-tab-CkLyKrL0.js';
|
|
12
12
|
import { b as TooltipProvider, T as Tooltip, c as TooltipTrigger, a as TooltipContent } from '../tooltip-DrsXZDAj.js';
|
|
13
13
|
import { T as Txt } from '../Txt-BtIGLRk1.js';
|
|
14
14
|
import { c as cn } from '../cn-CQUhN5Jx.js';
|
|
@@ -9,7 +9,7 @@ const reactHookForm = require('react-hook-form');
|
|
|
9
9
|
const lib_form_fieldContext = require('../field-context.cjs.js');
|
|
10
10
|
const lib_form_useSectionDisclosure = require('../use-section-disclosure.cjs.js');
|
|
11
11
|
const lib_form_utils = require('../utils.cjs.js');
|
|
12
|
-
const Button = require('../../../Button-
|
|
12
|
+
const Button = require('../../../Button-C4I05uT4.cjs');
|
|
13
13
|
const collapsible = require('../../../collapsible-pzbQxp_4.cjs');
|
|
14
14
|
const disclosureChevron = require('../../../disclosure-chevron-D0KwJ8Zc.cjs');
|
|
15
15
|
const Txt = require('../../../Txt-CIS2G5Jx.cjs');
|
|
@@ -5,7 +5,7 @@ import { useFormContext, useWatch } from 'react-hook-form';
|
|
|
5
5
|
import { FieldPathContext, FormReadOnlyContext, ArrayAddButtonContext } from '../field-context.es.js';
|
|
6
6
|
import { useSectionDisclosure } from '../use-section-disclosure.es.js';
|
|
7
7
|
import { isPlainObject } from '../utils.es.js';
|
|
8
|
-
import { B as Button } from '../../../Button-
|
|
8
|
+
import { B as Button } from '../../../Button-D8a5EWJ5.js';
|
|
9
9
|
import { C as Collapsible, b as CollapsibleTrigger, a as CollapsibleContent } from '../../../collapsible-BqerB7is.js';
|
|
10
10
|
import { D as DisclosureChevron } from '../../../disclosure-chevron-qzDAjl55.js';
|
|
11
11
|
import { T as Txt } from '../../../Txt-BtIGLRk1.js';
|
|
@@ -6,7 +6,7 @@ const jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
const lucideReact = require('lucide-react');
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const lib_form_fieldContext = require('../field-context.cjs.js');
|
|
9
|
-
const Button = require('../../../Button-
|
|
9
|
+
const Button = require('../../../Button-C4I05uT4.cjs');
|
|
10
10
|
const Txt = require('../../../Txt-CIS2G5Jx.cjs');
|
|
11
11
|
|
|
12
12
|
function ArrayWrapper({ label, children, onAddItem }) {
|