@mastra/playground-ui 64.0.1-alpha.0 → 65.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +10 -2
  2. package/components.css +340 -0
  3. package/dist/code-DJReJPSX.cjs.map +1 -1
  4. package/dist/code-DLuATvYu.js.map +1 -1
  5. package/dist/components/Breadcrumb.cjs.js +4 -2
  6. package/dist/components/Breadcrumb.cjs.js.map +1 -1
  7. package/dist/components/Breadcrumb.es.js +5 -3
  8. package/dist/components/Breadcrumb.es.js.map +1 -1
  9. package/dist/components/ChatShell.cjs.js +2 -2
  10. package/dist/components/ChatShell.cjs.js.map +1 -1
  11. package/dist/components/ChatShell.es.js +2 -2
  12. package/dist/components/ChatShell.es.js.map +1 -1
  13. package/dist/components/Composer.cjs.js +1 -1
  14. package/dist/components/Composer.cjs.js.map +1 -1
  15. package/dist/components/Composer.es.js +1 -1
  16. package/dist/components/Composer.es.js.map +1 -1
  17. package/dist/components/DataList.cjs.js +5 -5
  18. package/dist/components/DataList.es.js +5 -5
  19. package/dist/components/EnvironmentVariablesEditor.cjs.js +1 -1
  20. package/dist/components/EnvironmentVariablesEditor.es.js +1 -1
  21. package/dist/components/LogsDataList.cjs.js +2 -2
  22. package/dist/components/LogsDataList.es.js +2 -2
  23. package/dist/components/MessageScroller.cjs.js +1 -1
  24. package/dist/components/MessageScroller.es.js +1 -1
  25. package/dist/components/SavedViews.cjs.js +0 -1
  26. package/dist/components/SavedViews.cjs.js.map +1 -1
  27. package/dist/components/SavedViews.es.js +0 -1
  28. package/dist/components/SavedViews.es.js.map +1 -1
  29. package/dist/components/fluid-hover-highlight.cjs.js +7 -1
  30. package/dist/components/fluid-hover-highlight.cjs.js.map +1 -1
  31. package/dist/components/fluid-hover-highlight.es.js +7 -1
  32. package/dist/components/fluid-hover-highlight.es.js.map +1 -1
  33. package/dist/{data-list-DUfXIhyC.cjs → data-list-CmjTe8xE.cjs} +3 -3
  34. package/dist/{data-list-DUfXIhyC.cjs.map → data-list-CmjTe8xE.cjs.map} +1 -1
  35. package/dist/{data-list-DXQY_iQW.js → data-list-DT1LVR29.js} +3 -3
  36. package/dist/{data-list-DXQY_iQW.js.map → data-list-DT1LVR29.js.map} +1 -1
  37. package/dist/{data-list-skeleton-B_SXAeE0.js → data-list-skeleton-bNfITSHs.js} +2 -2
  38. package/dist/{data-list-skeleton-B_SXAeE0.js.map → data-list-skeleton-bNfITSHs.js.map} +1 -1
  39. package/dist/{data-list-skeleton-BqC9Gggi.cjs → data-list-skeleton-sdcaabdX.cjs} +2 -2
  40. package/dist/{data-list-skeleton-BqC9Gggi.cjs.map → data-list-skeleton-sdcaabdX.cjs.map} +1 -1
  41. package/dist/{data-list-spacer-tQaBaum4.cjs → data-list-spacer-CdlT6bDd.cjs} +2 -2
  42. package/dist/{data-list-spacer-tQaBaum4.cjs.map → data-list-spacer-CdlT6bDd.cjs.map} +1 -1
  43. package/dist/{data-list-spacer-ByA4ce2a.js → data-list-spacer-D--gDmOm.js} +2 -2
  44. package/dist/{data-list-spacer-ByA4ce2a.js.map → data-list-spacer-D--gDmOm.js.map} +1 -1
  45. package/dist/{data-list-top-ByT2Mo77.cjs → data-list-top-DJh08vFA.cjs} +2 -9
  46. package/dist/data-list-top-DJh08vFA.cjs.map +1 -0
  47. package/dist/{data-list-top-DSr_ocKA.js → data-list-top-T-mtdIUp.js} +2 -9
  48. package/dist/data-list-top-T-mtdIUp.js.map +1 -0
  49. package/dist/domains/datasets/components/save-as-dataset-item-dialog.cjs.js +104 -92
  50. package/dist/domains/datasets/components/save-as-dataset-item-dialog.cjs.js.map +1 -1
  51. package/dist/domains/datasets/components/save-as-dataset-item-dialog.es.js +105 -93
  52. package/dist/domains/datasets/components/save-as-dataset-item-dialog.es.js.map +1 -1
  53. package/dist/domains/logs/components/logs-list-view.cjs.js +2 -2
  54. package/dist/domains/logs/components/logs-list-view.es.js +2 -2
  55. package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.cjs.js +3 -3
  56. package/dist/domains/observability/components/add-trace-mocks-to-item-dialog.es.js +3 -3
  57. package/dist/domains/observability/components/trace-as-item-dialog.cjs.js +6 -10
  58. package/dist/domains/observability/components/trace-as-item-dialog.cjs.js.map +1 -1
  59. package/dist/domains/observability/components/trace-as-item-dialog.es.js +7 -11
  60. package/dist/domains/observability/components/trace-as-item-dialog.es.js.map +1 -1
  61. package/dist/domains/scores/components/score-as-item-dialog.cjs.js +3 -9
  62. package/dist/domains/scores/components/score-as-item-dialog.cjs.js.map +1 -1
  63. package/dist/domains/scores/components/score-as-item-dialog.es.js +4 -10
  64. package/dist/domains/scores/components/score-as-item-dialog.es.js.map +1 -1
  65. package/dist/domains/scores/components/score-data-panel.cjs.js +9 -1
  66. package/dist/domains/scores/components/score-data-panel.cjs.js.map +1 -1
  67. package/dist/domains/scores/components/score-data-panel.es.js +9 -1
  68. package/dist/domains/scores/components/score-data-panel.es.js.map +1 -1
  69. package/dist/domains/scores/components/trace-scores-tab.cjs.js +1 -1
  70. package/dist/domains/scores/components/trace-scores-tab.es.js +1 -1
  71. package/dist/domains/traces/components/format-hierarchical-spans.cjs.js +12 -13
  72. package/dist/domains/traces/components/format-hierarchical-spans.cjs.js.map +1 -1
  73. package/dist/domains/traces/components/format-hierarchical-spans.es.js +12 -13
  74. package/dist/domains/traces/components/format-hierarchical-spans.es.js.map +1 -1
  75. package/dist/domains/traces/components/span-rows.cjs.js +2 -1
  76. package/dist/domains/traces/components/span-rows.cjs.js.map +1 -1
  77. package/dist/domains/traces/components/span-rows.es.js +2 -1
  78. package/dist/domains/traces/components/span-rows.es.js.map +1 -1
  79. package/dist/domains/traces/components/thread-trace/thread-trace-list.cjs.js +1 -1
  80. package/dist/domains/traces/components/thread-trace/thread-trace-list.es.js +1 -1
  81. package/dist/domains/traces/components/thread-trace/thread-trace-root.cjs.js +1 -1
  82. package/dist/domains/traces/components/thread-trace/thread-trace-root.es.js +1 -1
  83. package/dist/domains/traces/components/thread-trace/thread-trace-row.cjs.js +1 -1
  84. package/dist/domains/traces/components/thread-trace/thread-trace-row.es.js +1 -1
  85. package/dist/domains/traces/components/trace-span-timeline.cjs.js +2 -1
  86. package/dist/domains/traces/components/trace-span-timeline.cjs.js.map +1 -1
  87. package/dist/domains/traces/components/trace-span-timeline.es.js +2 -1
  88. package/dist/domains/traces/components/trace-span-timeline.es.js.map +1 -1
  89. package/dist/domains/traces/components/traces-list-view.cjs.js +4 -4
  90. package/dist/domains/traces/components/traces-list-view.es.js +4 -4
  91. package/dist/domains/traces/components/traces-page-skeleton.cjs.js +1 -1
  92. package/dist/domains/traces/components/traces-page-skeleton.es.js +1 -1
  93. package/dist/domains/traces/utils/span-timing.cjs.js +10 -0
  94. package/dist/domains/traces/utils/span-timing.cjs.js.map +1 -1
  95. package/dist/domains/traces/utils/span-timing.es.js +10 -1
  96. package/dist/domains/traces/utils/span-timing.es.js.map +1 -1
  97. package/dist/domains/workflows/components/workflows-list/workflows-list.cjs.js +2 -2
  98. package/dist/domains/workflows/components/workflows-list/workflows-list.es.js +2 -2
  99. package/dist/ee/signals/components/entity-index-list.cjs.js +1 -1
  100. package/dist/ee/signals/components/entity-index-list.es.js +1 -1
  101. package/dist/ee/signals/components/trace-intelligence-entity-index.cjs.js +1 -1
  102. package/dist/ee/signals/components/trace-intelligence-entity-index.es.js +1 -1
  103. package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +1 -1
  104. package/dist/ee/topics/components/topic-trace-summary-list.es.js +1 -1
  105. package/dist/hooks/use-fluid-hover.cjs.js +3 -2
  106. package/dist/hooks/use-fluid-hover.cjs.js.map +1 -1
  107. package/dist/hooks/use-fluid-hover.es.js +3 -2
  108. package/dist/hooks/use-fluid-hover.es.js.map +1 -1
  109. package/dist/layout/tabbed-container.cjs.js +1 -1
  110. package/dist/layout/tabbed-container.es.js +1 -1
  111. package/dist/{logs-data-list-CoER2Hst.js → logs-data-list-Cb85LPcT.js} +3 -3
  112. package/dist/{logs-data-list-CoER2Hst.js.map → logs-data-list-Cb85LPcT.js.map} +1 -1
  113. package/dist/{logs-data-list-DRR6cMgl.cjs → logs-data-list-DlQxxrNw.cjs} +3 -3
  114. package/dist/{logs-data-list-DRR6cMgl.cjs.map → logs-data-list-DlQxxrNw.cjs.map} +1 -1
  115. package/dist/{message-scroller-CS1KxKn6.js → message-scroller-C6gXU5d5.js} +2 -2
  116. package/dist/{message-scroller-CS1KxKn6.js.map → message-scroller-C6gXU5d5.js.map} +1 -1
  117. package/dist/{message-scroller-C4fH6uJg.cjs → message-scroller-fjucuCuw.cjs} +2 -2
  118. package/dist/{message-scroller-C4fH6uJg.cjs.map → message-scroller-fjucuCuw.cjs.map} +1 -1
  119. package/dist/primitives/raised-surface.cjs.js.map +1 -1
  120. package/dist/primitives/raised-surface.es.js.map +1 -1
  121. package/dist/scroll-area-CAY0DNQj.cjs.map +1 -1
  122. package/dist/scroll-area-MaMqo4l8.js.map +1 -1
  123. package/dist/src/domains/datasets/components/index.d.ts +1 -1
  124. package/dist/src/domains/datasets/components/save-as-dataset-item-dialog.d.ts +14 -3
  125. package/dist/src/domains/observability/components/trace-as-item-dialog.d.ts +5 -3
  126. package/dist/src/domains/scores/components/score-as-item-dialog.d.ts +3 -3
  127. package/dist/src/domains/traces/utils/span-timing.d.ts +2 -0
  128. package/dist/src/ds/components/Breadcrumb/Breadcrumb.d.ts +2 -2
  129. package/dist/src/ds/components/ChatShell/chat-shell.d.ts +3 -2
  130. package/dist/src/ds/components/Code/code.d.ts +1 -1
  131. package/dist/src/ds/components/ScrollArea/scroll-area.d.ts +4 -0
  132. package/dist/src/ds/primitives/raised-surface.d.ts +1 -1
  133. package/dist/src/hooks/use-fluid-hover.d.ts +1 -0
  134. package/dist/style.css +32 -31
  135. package/dist/toast.css +1 -1
  136. package/dist/tokens.cjs.js.map +1 -1
  137. package/dist/tokens.es.js.map +1 -1
  138. package/dist/{traces-data-list-BgjeB-BF.cjs → traces-data-list-Bhhg9drs.cjs} +4 -4
  139. package/dist/{traces-data-list-BgjeB-BF.cjs.map → traces-data-list-Bhhg9drs.cjs.map} +1 -1
  140. package/dist/{traces-data-list-Zoai0OW_.js → traces-data-list-DMWPJFBc.js} +4 -4
  141. package/dist/{traces-data-list-Zoai0OW_.js.map → traces-data-list-DMWPJFBc.js.map} +1 -1
  142. package/dist/use-text-highlight.css +4 -4
  143. package/package.json +15 -11
  144. package/sources.css +1 -0
  145. package/theme/code.css +17 -0
  146. package/theme/surfaces.css +2 -2
  147. package/theme.css +2 -0
  148. package/dist/data-list-top-ByT2Mo77.cjs.map +0 -1
  149. package/dist/data-list-top-DSr_ocKA.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ChatShell.cjs.js","sources":["../../src/ds/components/ChatShell/chat-shell.tsx","../../src/ds/components/ChatShell/index.ts"],"sourcesContent":["import type { ComponentProps, ComponentPropsWithoutRef } from 'react';\n\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from '../MessageScroller';\nimport type {\n MessageScrollerButtonProps,\n MessageScrollerContentProps,\n MessageScrollerProviderProps,\n MessageScrollerViewportProps,\n} from '../MessageScroller';\n\nimport { cn } from '@/lib/utils';\n\nexport type ChatShellProps = ComponentPropsWithoutRef<'div'> & {\n scroller?: Omit<MessageScrollerProviderProps, 'children'>;\n};\n\n/**\n * A chat page frame with exactly one scroll container. Bars sit above it, the\n * composer docks inside it, every region shares one column.\n *\n * Tuned through custom properties, all defaulted here: `--chat-column` (column\n * width), `--chat-surface` (the colour the composer veil ramps to — the shell\n * paints no fill of its own and inherits whatever surface hosts it, so this has\n * to name that same surface), `--chat-fade` (the band the veil ramps in\n * across, above the composer), `--chat-veil` (strongest it gets, opaque by\n * default so nothing reads under the composer), `--chat-gutter` (room below the\n * composer), `--chat-edge` (room on both sides, so the scrollbar never overlaps\n * the composer), `--chat-inset-end` (room an overlay panel claims on the end edge).\n */\nexport function ChatShellRoot({ className, scroller, ...props }: ChatShellProps) {\n return (\n <MessageScrollerProvider {...scroller}>\n <div\n data-slot=\"chat-shell\"\n className={cn(\n '@container relative isolate flex min-h-0 min-w-0 flex-col',\n '[--chat-column:48rem] [--chat-edge:0.5rem] [--chat-fade:2rem] [--chat-gutter:0.75rem] [--chat-inset-end:0px]',\n '[--chat-surface:var(--color-background)] [--chat-veil:100%]',\n className,\n )}\n {...props}\n />\n </MessageScrollerProvider>\n );\n}\n\n/**\n * Full-width row above the scroller (session header, goal bar). No end inset: the\n * overlay panel it would dodge floats inside the stage, below the bars.\n */\nexport function ChatShellBar({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <div data-slot=\"chat-shell-bar\" className={cn('min-w-0 shrink-0', className)} {...props} />;\n}\n\n/** Positioned region holding the scroller plus anything overlaying it. */\nexport function ChatShellStage({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <MessageScroller className={cn('h-auto min-h-0 flex-1', className)} {...props} />;\n}\n\n/**\n * The one scroll container. It takes the end inset itself — on an ancestor the\n * same room would drag the scrollbar inward, off the true edge. No overscroll\n * bounce on either axis: the dock is sticky inside this box, so the rubber band\n * would carry the composer off its edge along with the transcript.\n *\n * The same edge room on both sides keeps the scrollbar clear of the composer and\n * the column centred, with a matching gutter for classic scrollbars.\n */\nexport function ChatShellViewport({ className, children, ...props }: MessageScrollerViewportProps) {\n return (\n <MessageScrollerViewport\n className={cn(\n 'h-auto min-h-0 flex-1 overscroll-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]',\n '[scrollbar-gutter:stable_both-edges]',\n 'transition-[padding] duration-360 ease-out-custom motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {/* Sticky against the scroller itself is clamped to its box, not the\n scrolled height, and strands the dock mid-transcript. */}\n <div data-slot=\"chat-shell-track\" className=\"relative flex min-h-full min-w-0 flex-col\">\n {children}\n </div>\n </MessageScrollerViewport>\n );\n}\n\n/** Scrolling content. The air above the composer belongs to the dock's fade band. */\nexport function ChatShellContent({ className, ...props }: MessageScrollerContentProps) {\n return <MessageScrollerContent className={cn('flex-1', className)} {...props} />;\n}\n\n/** The shared reading column. Every chat region must go through it. */\nexport function ChatShellColumn({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-column\"\n className={cn('mx-auto flex w-full max-w-(--chat-column) min-w-0 flex-col px-3 md:px-4', className)}\n {...props}\n />\n );\n}\n\nexport interface ChatShellTurnProps extends ComponentPropsWithoutRef<'div'> {\n /** Opened by a user message: the turn reserves room and releases it through a slow drift. */\n opensTurn?: boolean;\n /** Holds the reply's share of the screen open under the live turn while the run answers. */\n holdsRoom?: boolean;\n /** Restored mid-run: the room is already due, so it opens with no transition. */\n restored?: boolean;\n}\n\n/**\n * One user turn and the reply under it. The room is the answer's share of the\n * screen: the scroller parks the sent message exactly one room above the end of\n * the box, so wherever the composer ends the message rests with this much space\n * under it, and the scroller has nothing to follow until the answer outgrows it.\n * A full screen parked the message against the very top; 70 leaves it breathing.\n * Opening must outrun the scroller's trip; closing is the conversation settling.\n */\nexport function ChatShellTurn({ opensTurn, holdsRoom, restored, className, ...props }: ChatShellTurnProps) {\n return (\n <div\n data-slot=\"chat-shell-turn\"\n data-opens-turn={opensTurn ? 'true' : undefined}\n data-holds-room={holdsRoom ? 'true' : undefined}\n className={cn(\n 'flex flex-col',\n opensTurn &&\n 'min-h-0 transition-[min-height] duration-[1500ms] ease-[cubic-bezier(0.3,0,0.2,1)] motion-reduce:transition-none',\n holdsRoom && 'min-h-[70cqh] duration-[440ms] ease-[cubic-bezier(0.2,0,0.2,1)] starting:min-h-0',\n holdsRoom && restored && 'transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Composer region, sticky but left in flow: its own height reserves the room the\n * transcript scrolls behind, so nothing measures it and a composer growing under\n * the cursor resizes no box the scroller watches.\n *\n * Behind it, one sheet of the page masked in over `--chat-fade` of air, reaching\n * `--chat-veil` at the dock's top edge. The transcript fades out above the\n * composer and nothing shows through around or under the card.\n */\nexport function ChatShellDock({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-dock\"\n className={cn(\n 'sticky bottom-0 z-10 mt-(--chat-fade) shrink-0 pb-(--chat-gutter)',\n 'before:pointer-events-none before:absolute before:inset-x-0 before:-top-(--chat-fade) before:bottom-0 before:-z-10',\n 'before:bg-(--chat-surface) before:[mask-image:linear-gradient(to_bottom,transparent,rgb(0_0_0/var(--chat-veil))_var(--chat-fade))]',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Jump-to-latest, floating just above the dock. It belongs inside the dock:\n * anywhere else it centres on a box the scrollbar has not narrowed, landing off\n * the composer's axis.\n */\nexport function ChatShellScrollButton({ className, ...props }: MessageScrollerButtonProps) {\n return (\n <div\n data-slot=\"chat-shell-scroll-button\"\n className=\"pointer-events-none absolute inset-x-0 bottom-[calc(100%+0.5rem)] flex\"\n >\n <ChatShellColumn className=\"flex-row justify-center\">\n <MessageScrollerButton\n className={cn('pointer-events-auto static translate-x-0 rtl:translate-x-0', className)}\n {...props}\n />\n </ChatShellColumn>\n </div>\n );\n}\n","import {\n ChatShellBar,\n ChatShellColumn,\n ChatShellContent,\n ChatShellDock,\n ChatShellRoot,\n ChatShellScrollButton,\n ChatShellStage,\n ChatShellTurn,\n ChatShellViewport,\n} from './chat-shell';\n\nexport type { ChatShellProps, ChatShellTurnProps } from './chat-shell';\n\nexport const ChatShell = Object.assign(ChatShellRoot, {\n Bar: ChatShellBar,\n Column: ChatShellColumn,\n Content: ChatShellContent,\n Dock: ChatShellDock,\n ScrollButton: ChatShellScrollButton,\n Stage: ChatShellStage,\n Turn: ChatShellTurn,\n Viewport: ChatShellViewport,\n});\n"],"names":["jsx","MessageScrollerProvider","cn","MessageScroller","MessageScrollerViewport","MessageScrollerContent","MessageScrollerButton"],"mappings":"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"}
1
+ {"version":3,"file":"ChatShell.cjs.js","sources":["../../src/ds/components/ChatShell/chat-shell.tsx","../../src/ds/components/ChatShell/index.ts"],"sourcesContent":["import type { ComponentProps, ComponentPropsWithoutRef } from 'react';\n\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from '../MessageScroller';\nimport type {\n MessageScrollerButtonProps,\n MessageScrollerContentProps,\n MessageScrollerProviderProps,\n MessageScrollerViewportProps,\n} from '../MessageScroller';\n\nimport { cn } from '@/lib/utils';\n\nexport type ChatShellProps = ComponentPropsWithoutRef<'div'> & {\n scroller?: Omit<MessageScrollerProviderProps, 'children'>;\n};\n\n/**\n * A chat page frame with exactly one scroll container. Bars sit above it, the\n * composer docks inside it, every region shares one column.\n *\n * Tuned through custom properties, all defaulted here: `--chat-column` (column\n * width), `--chat-surface` (the colour the composer veil ramps to — the shell\n * paints no fill of its own and inherits whatever surface hosts it, so this has\n * to name that same surface), `--chat-fade` (the band the veil ramps in\n * across, above the composer), `--chat-veil` (strongest it gets, opaque by\n * default so nothing reads under the composer), `--chat-gutter` (room below the\n * composer), `--chat-edge` (room on both sides, so the scrollbar never overlaps\n * the composer), `--chat-inset-end` (room an overlay panel claims on the end edge).\n */\nexport function ChatShellRoot({ className, scroller, ...props }: ChatShellProps) {\n return (\n <MessageScrollerProvider {...scroller}>\n <div\n data-slot=\"chat-shell\"\n className={cn(\n '@container relative isolate flex min-h-0 min-w-0 flex-col',\n '[--chat-column:48rem] [--chat-edge:0.5rem] [--chat-fade:2rem] [--chat-gutter:0.75rem] [--chat-inset-end:0px]',\n '[--chat-surface:var(--color-background)] [--chat-veil:100%]',\n className,\n )}\n {...props}\n />\n </MessageScrollerProvider>\n );\n}\n\n/**\n * Full-width row above the scroller (session header, goal bar). No end inset: the\n * overlay panel it would dodge floats inside the stage, below the bars.\n */\nexport function ChatShellBar({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <div data-slot=\"chat-shell-bar\" className={cn('min-w-0 shrink-0', className)} {...props} />;\n}\n\n/** Positioned region holding the scroller plus anything overlaying it. */\nexport function ChatShellStage({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <MessageScroller className={cn('h-auto min-h-0 flex-1', className)} {...props} />;\n}\n\n/**\n * The one scroll container. It takes the end inset itself — on an ancestor the\n * same room would drag the scrollbar inward, off the true edge. No overscroll\n * bounce vertically: the dock is sticky inside this box, so the rubber band\n * would carry the composer off its edge along with the transcript. Horizontal\n * overscroll stays native so trackpad swipes can navigate browser history.\n *\n * The same edge room on both sides keeps the scrollbar clear of the composer and\n * the column centred, with a matching gutter for classic scrollbars.\n */\nexport function ChatShellViewport({ className, children, ...props }: MessageScrollerViewportProps) {\n return (\n <MessageScrollerViewport\n className={cn(\n 'h-auto min-h-0 flex-1 overscroll-y-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]',\n '[scrollbar-gutter:stable_both-edges]',\n 'transition-[padding] duration-360 ease-out-custom motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {/* Sticky against the scroller itself is clamped to its box, not the\n scrolled height, and strands the dock mid-transcript. */}\n <div data-slot=\"chat-shell-track\" className=\"relative flex min-h-full min-w-0 flex-col\">\n {children}\n </div>\n </MessageScrollerViewport>\n );\n}\n\n/** Scrolling content. The air above the composer belongs to the dock's fade band. */\nexport function ChatShellContent({ className, ...props }: MessageScrollerContentProps) {\n return <MessageScrollerContent className={cn('flex-1', className)} {...props} />;\n}\n\n/** The shared reading column. Every chat region must go through it. */\nexport function ChatShellColumn({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-column\"\n className={cn('mx-auto flex w-full max-w-(--chat-column) min-w-0 flex-col px-3 md:px-4', className)}\n {...props}\n />\n );\n}\n\nexport interface ChatShellTurnProps extends ComponentPropsWithoutRef<'div'> {\n /** Opened by a user message: the turn reserves room and releases it through a slow drift. */\n opensTurn?: boolean;\n /** Holds the reply's share of the screen open under the live turn while the run answers. */\n holdsRoom?: boolean;\n /** Restored mid-run: the room is already due, so it opens with no transition. */\n restored?: boolean;\n}\n\n/**\n * One user turn and the reply under it. The room is the answer's share of the\n * screen: the scroller parks the sent message exactly one room above the end of\n * the box, so wherever the composer ends the message rests with this much space\n * under it, and the scroller has nothing to follow until the answer outgrows it.\n * A full screen parked the message against the very top; 70 leaves it breathing.\n * Opening must outrun the scroller's trip; closing is the conversation settling.\n */\nexport function ChatShellTurn({ opensTurn, holdsRoom, restored, className, ...props }: ChatShellTurnProps) {\n return (\n <div\n data-slot=\"chat-shell-turn\"\n data-opens-turn={opensTurn ? 'true' : undefined}\n data-holds-room={holdsRoom ? 'true' : undefined}\n className={cn(\n 'flex flex-col',\n opensTurn &&\n 'min-h-0 transition-[min-height] duration-[1500ms] ease-[cubic-bezier(0.3,0,0.2,1)] motion-reduce:transition-none',\n holdsRoom && 'min-h-[70cqh] duration-[440ms] ease-[cubic-bezier(0.2,0,0.2,1)] starting:min-h-0',\n holdsRoom && restored && 'transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Composer region, sticky but left in flow: its own height reserves the room the\n * transcript scrolls behind, so nothing measures it and a composer growing under\n * the cursor resizes no box the scroller watches.\n *\n * Behind it, one sheet of the page masked in over `--chat-fade` of air, reaching\n * `--chat-veil` at the dock's top edge. The transcript fades out above the\n * composer and nothing shows through around or under the card.\n */\nexport function ChatShellDock({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-dock\"\n className={cn(\n 'sticky bottom-0 z-10 mt-(--chat-fade) shrink-0 pb-(--chat-gutter)',\n 'before:pointer-events-none before:absolute before:inset-x-0 before:-top-(--chat-fade) before:bottom-0 before:-z-10',\n 'before:bg-(--chat-surface) before:[mask-image:linear-gradient(to_bottom,transparent,rgb(0_0_0/var(--chat-veil))_var(--chat-fade))]',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Jump-to-latest, floating just above the dock. It belongs inside the dock:\n * anywhere else it centres on a box the scrollbar has not narrowed, landing off\n * the composer's axis.\n */\nexport function ChatShellScrollButton({ className, ...props }: MessageScrollerButtonProps) {\n return (\n <div\n data-slot=\"chat-shell-scroll-button\"\n className=\"pointer-events-none absolute inset-x-0 bottom-[calc(100%+0.5rem)] flex\"\n >\n <ChatShellColumn className=\"flex-row justify-center\">\n <MessageScrollerButton\n className={cn('pointer-events-auto static translate-x-0 rtl:translate-x-0', className)}\n {...props}\n />\n </ChatShellColumn>\n </div>\n );\n}\n","import {\n ChatShellBar,\n ChatShellColumn,\n ChatShellContent,\n ChatShellDock,\n ChatShellRoot,\n ChatShellScrollButton,\n ChatShellStage,\n ChatShellTurn,\n ChatShellViewport,\n} from './chat-shell';\n\nexport type { ChatShellProps, ChatShellTurnProps } from './chat-shell';\n\nexport const ChatShell = Object.assign(ChatShellRoot, {\n Bar: ChatShellBar,\n Column: ChatShellColumn,\n Content: ChatShellContent,\n Dock: ChatShellDock,\n ScrollButton: ChatShellScrollButton,\n Stage: ChatShellStage,\n Turn: ChatShellTurn,\n Viewport: ChatShellViewport,\n});\n"],"names":["jsx","MessageScrollerProvider","cn","MessageScroller","MessageScrollerViewport","MessageScrollerContent","MessageScrollerButton"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { d as MessageScrollerProvider, e as MessageScrollerViewport, M as MessageScroller, a as MessageScrollerButton, b as MessageScrollerContent } from '../message-scroller-CS1KxKn6.js';
2
+ import { d as MessageScrollerProvider, e as MessageScrollerViewport, M as MessageScroller, a as MessageScrollerButton, b as MessageScrollerContent } from '../message-scroller-C6gXU5d5.js';
3
3
  import { c as cn } from '../cn-CQUhN5Jx.js';
4
4
 
5
5
  function ChatShellRoot({ className, scroller, ...props }) {
@@ -28,7 +28,7 @@ function ChatShellViewport({ className, children, ...props }) {
28
28
  MessageScrollerViewport,
29
29
  {
30
30
  className: cn(
31
- "h-auto min-h-0 flex-1 overscroll-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]",
31
+ "h-auto min-h-0 flex-1 overscroll-y-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]",
32
32
  "[scrollbar-gutter:stable_both-edges]",
33
33
  "transition-[padding] duration-360 ease-out-custom motion-reduce:transition-none",
34
34
  className
@@ -1 +1 @@
1
- {"version":3,"file":"ChatShell.es.js","sources":["../../src/ds/components/ChatShell/chat-shell.tsx","../../src/ds/components/ChatShell/index.ts"],"sourcesContent":["import type { ComponentProps, ComponentPropsWithoutRef } from 'react';\n\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from '../MessageScroller';\nimport type {\n MessageScrollerButtonProps,\n MessageScrollerContentProps,\n MessageScrollerProviderProps,\n MessageScrollerViewportProps,\n} from '../MessageScroller';\n\nimport { cn } from '@/lib/utils';\n\nexport type ChatShellProps = ComponentPropsWithoutRef<'div'> & {\n scroller?: Omit<MessageScrollerProviderProps, 'children'>;\n};\n\n/**\n * A chat page frame with exactly one scroll container. Bars sit above it, the\n * composer docks inside it, every region shares one column.\n *\n * Tuned through custom properties, all defaulted here: `--chat-column` (column\n * width), `--chat-surface` (the colour the composer veil ramps to — the shell\n * paints no fill of its own and inherits whatever surface hosts it, so this has\n * to name that same surface), `--chat-fade` (the band the veil ramps in\n * across, above the composer), `--chat-veil` (strongest it gets, opaque by\n * default so nothing reads under the composer), `--chat-gutter` (room below the\n * composer), `--chat-edge` (room on both sides, so the scrollbar never overlaps\n * the composer), `--chat-inset-end` (room an overlay panel claims on the end edge).\n */\nexport function ChatShellRoot({ className, scroller, ...props }: ChatShellProps) {\n return (\n <MessageScrollerProvider {...scroller}>\n <div\n data-slot=\"chat-shell\"\n className={cn(\n '@container relative isolate flex min-h-0 min-w-0 flex-col',\n '[--chat-column:48rem] [--chat-edge:0.5rem] [--chat-fade:2rem] [--chat-gutter:0.75rem] [--chat-inset-end:0px]',\n '[--chat-surface:var(--color-background)] [--chat-veil:100%]',\n className,\n )}\n {...props}\n />\n </MessageScrollerProvider>\n );\n}\n\n/**\n * Full-width row above the scroller (session header, goal bar). No end inset: the\n * overlay panel it would dodge floats inside the stage, below the bars.\n */\nexport function ChatShellBar({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <div data-slot=\"chat-shell-bar\" className={cn('min-w-0 shrink-0', className)} {...props} />;\n}\n\n/** Positioned region holding the scroller plus anything overlaying it. */\nexport function ChatShellStage({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <MessageScroller className={cn('h-auto min-h-0 flex-1', className)} {...props} />;\n}\n\n/**\n * The one scroll container. It takes the end inset itself — on an ancestor the\n * same room would drag the scrollbar inward, off the true edge. No overscroll\n * bounce on either axis: the dock is sticky inside this box, so the rubber band\n * would carry the composer off its edge along with the transcript.\n *\n * The same edge room on both sides keeps the scrollbar clear of the composer and\n * the column centred, with a matching gutter for classic scrollbars.\n */\nexport function ChatShellViewport({ className, children, ...props }: MessageScrollerViewportProps) {\n return (\n <MessageScrollerViewport\n className={cn(\n 'h-auto min-h-0 flex-1 overscroll-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]',\n '[scrollbar-gutter:stable_both-edges]',\n 'transition-[padding] duration-360 ease-out-custom motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {/* Sticky against the scroller itself is clamped to its box, not the\n scrolled height, and strands the dock mid-transcript. */}\n <div data-slot=\"chat-shell-track\" className=\"relative flex min-h-full min-w-0 flex-col\">\n {children}\n </div>\n </MessageScrollerViewport>\n );\n}\n\n/** Scrolling content. The air above the composer belongs to the dock's fade band. */\nexport function ChatShellContent({ className, ...props }: MessageScrollerContentProps) {\n return <MessageScrollerContent className={cn('flex-1', className)} {...props} />;\n}\n\n/** The shared reading column. Every chat region must go through it. */\nexport function ChatShellColumn({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-column\"\n className={cn('mx-auto flex w-full max-w-(--chat-column) min-w-0 flex-col px-3 md:px-4', className)}\n {...props}\n />\n );\n}\n\nexport interface ChatShellTurnProps extends ComponentPropsWithoutRef<'div'> {\n /** Opened by a user message: the turn reserves room and releases it through a slow drift. */\n opensTurn?: boolean;\n /** Holds the reply's share of the screen open under the live turn while the run answers. */\n holdsRoom?: boolean;\n /** Restored mid-run: the room is already due, so it opens with no transition. */\n restored?: boolean;\n}\n\n/**\n * One user turn and the reply under it. The room is the answer's share of the\n * screen: the scroller parks the sent message exactly one room above the end of\n * the box, so wherever the composer ends the message rests with this much space\n * under it, and the scroller has nothing to follow until the answer outgrows it.\n * A full screen parked the message against the very top; 70 leaves it breathing.\n * Opening must outrun the scroller's trip; closing is the conversation settling.\n */\nexport function ChatShellTurn({ opensTurn, holdsRoom, restored, className, ...props }: ChatShellTurnProps) {\n return (\n <div\n data-slot=\"chat-shell-turn\"\n data-opens-turn={opensTurn ? 'true' : undefined}\n data-holds-room={holdsRoom ? 'true' : undefined}\n className={cn(\n 'flex flex-col',\n opensTurn &&\n 'min-h-0 transition-[min-height] duration-[1500ms] ease-[cubic-bezier(0.3,0,0.2,1)] motion-reduce:transition-none',\n holdsRoom && 'min-h-[70cqh] duration-[440ms] ease-[cubic-bezier(0.2,0,0.2,1)] starting:min-h-0',\n holdsRoom && restored && 'transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Composer region, sticky but left in flow: its own height reserves the room the\n * transcript scrolls behind, so nothing measures it and a composer growing under\n * the cursor resizes no box the scroller watches.\n *\n * Behind it, one sheet of the page masked in over `--chat-fade` of air, reaching\n * `--chat-veil` at the dock's top edge. The transcript fades out above the\n * composer and nothing shows through around or under the card.\n */\nexport function ChatShellDock({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-dock\"\n className={cn(\n 'sticky bottom-0 z-10 mt-(--chat-fade) shrink-0 pb-(--chat-gutter)',\n 'before:pointer-events-none before:absolute before:inset-x-0 before:-top-(--chat-fade) before:bottom-0 before:-z-10',\n 'before:bg-(--chat-surface) before:[mask-image:linear-gradient(to_bottom,transparent,rgb(0_0_0/var(--chat-veil))_var(--chat-fade))]',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Jump-to-latest, floating just above the dock. It belongs inside the dock:\n * anywhere else it centres on a box the scrollbar has not narrowed, landing off\n * the composer's axis.\n */\nexport function ChatShellScrollButton({ className, ...props }: MessageScrollerButtonProps) {\n return (\n <div\n data-slot=\"chat-shell-scroll-button\"\n className=\"pointer-events-none absolute inset-x-0 bottom-[calc(100%+0.5rem)] flex\"\n >\n <ChatShellColumn className=\"flex-row justify-center\">\n <MessageScrollerButton\n className={cn('pointer-events-auto static translate-x-0 rtl:translate-x-0', className)}\n {...props}\n />\n </ChatShellColumn>\n </div>\n );\n}\n","import {\n ChatShellBar,\n ChatShellColumn,\n ChatShellContent,\n ChatShellDock,\n ChatShellRoot,\n ChatShellScrollButton,\n ChatShellStage,\n ChatShellTurn,\n ChatShellViewport,\n} from './chat-shell';\n\nexport type { ChatShellProps, ChatShellTurnProps } from './chat-shell';\n\nexport const ChatShell = Object.assign(ChatShellRoot, {\n Bar: ChatShellBar,\n Column: ChatShellColumn,\n Content: ChatShellContent,\n Dock: ChatShellDock,\n ScrollButton: ChatShellScrollButton,\n Stage: ChatShellStage,\n Turn: ChatShellTurn,\n Viewport: ChatShellViewport,\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatShell.es.js","sources":["../../src/ds/components/ChatShell/chat-shell.tsx","../../src/ds/components/ChatShell/index.ts"],"sourcesContent":["import type { ComponentProps, ComponentPropsWithoutRef } from 'react';\n\nimport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerProvider,\n MessageScrollerViewport,\n} from '../MessageScroller';\nimport type {\n MessageScrollerButtonProps,\n MessageScrollerContentProps,\n MessageScrollerProviderProps,\n MessageScrollerViewportProps,\n} from '../MessageScroller';\n\nimport { cn } from '@/lib/utils';\n\nexport type ChatShellProps = ComponentPropsWithoutRef<'div'> & {\n scroller?: Omit<MessageScrollerProviderProps, 'children'>;\n};\n\n/**\n * A chat page frame with exactly one scroll container. Bars sit above it, the\n * composer docks inside it, every region shares one column.\n *\n * Tuned through custom properties, all defaulted here: `--chat-column` (column\n * width), `--chat-surface` (the colour the composer veil ramps to — the shell\n * paints no fill of its own and inherits whatever surface hosts it, so this has\n * to name that same surface), `--chat-fade` (the band the veil ramps in\n * across, above the composer), `--chat-veil` (strongest it gets, opaque by\n * default so nothing reads under the composer), `--chat-gutter` (room below the\n * composer), `--chat-edge` (room on both sides, so the scrollbar never overlaps\n * the composer), `--chat-inset-end` (room an overlay panel claims on the end edge).\n */\nexport function ChatShellRoot({ className, scroller, ...props }: ChatShellProps) {\n return (\n <MessageScrollerProvider {...scroller}>\n <div\n data-slot=\"chat-shell\"\n className={cn(\n '@container relative isolate flex min-h-0 min-w-0 flex-col',\n '[--chat-column:48rem] [--chat-edge:0.5rem] [--chat-fade:2rem] [--chat-gutter:0.75rem] [--chat-inset-end:0px]',\n '[--chat-surface:var(--color-background)] [--chat-veil:100%]',\n className,\n )}\n {...props}\n />\n </MessageScrollerProvider>\n );\n}\n\n/**\n * Full-width row above the scroller (session header, goal bar). No end inset: the\n * overlay panel it would dodge floats inside the stage, below the bars.\n */\nexport function ChatShellBar({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <div data-slot=\"chat-shell-bar\" className={cn('min-w-0 shrink-0', className)} {...props} />;\n}\n\n/** Positioned region holding the scroller plus anything overlaying it. */\nexport function ChatShellStage({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return <MessageScroller className={cn('h-auto min-h-0 flex-1', className)} {...props} />;\n}\n\n/**\n * The one scroll container. It takes the end inset itself — on an ancestor the\n * same room would drag the scrollbar inward, off the true edge. No overscroll\n * bounce vertically: the dock is sticky inside this box, so the rubber band\n * would carry the composer off its edge along with the transcript. Horizontal\n * overscroll stays native so trackpad swipes can navigate browser history.\n *\n * The same edge room on both sides keeps the scrollbar clear of the composer and\n * the column centred, with a matching gutter for classic scrollbars.\n */\nexport function ChatShellViewport({ className, children, ...props }: MessageScrollerViewportProps) {\n return (\n <MessageScrollerViewport\n className={cn(\n 'h-auto min-h-0 flex-1 overscroll-y-none ps-(--chat-edge) pe-[calc(var(--chat-edge)+var(--chat-inset-end))]',\n '[scrollbar-gutter:stable_both-edges]',\n 'transition-[padding] duration-360 ease-out-custom motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {/* Sticky against the scroller itself is clamped to its box, not the\n scrolled height, and strands the dock mid-transcript. */}\n <div data-slot=\"chat-shell-track\" className=\"relative flex min-h-full min-w-0 flex-col\">\n {children}\n </div>\n </MessageScrollerViewport>\n );\n}\n\n/** Scrolling content. The air above the composer belongs to the dock's fade band. */\nexport function ChatShellContent({ className, ...props }: MessageScrollerContentProps) {\n return <MessageScrollerContent className={cn('flex-1', className)} {...props} />;\n}\n\n/** The shared reading column. Every chat region must go through it. */\nexport function ChatShellColumn({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-column\"\n className={cn('mx-auto flex w-full max-w-(--chat-column) min-w-0 flex-col px-3 md:px-4', className)}\n {...props}\n />\n );\n}\n\nexport interface ChatShellTurnProps extends ComponentPropsWithoutRef<'div'> {\n /** Opened by a user message: the turn reserves room and releases it through a slow drift. */\n opensTurn?: boolean;\n /** Holds the reply's share of the screen open under the live turn while the run answers. */\n holdsRoom?: boolean;\n /** Restored mid-run: the room is already due, so it opens with no transition. */\n restored?: boolean;\n}\n\n/**\n * One user turn and the reply under it. The room is the answer's share of the\n * screen: the scroller parks the sent message exactly one room above the end of\n * the box, so wherever the composer ends the message rests with this much space\n * under it, and the scroller has nothing to follow until the answer outgrows it.\n * A full screen parked the message against the very top; 70 leaves it breathing.\n * Opening must outrun the scroller's trip; closing is the conversation settling.\n */\nexport function ChatShellTurn({ opensTurn, holdsRoom, restored, className, ...props }: ChatShellTurnProps) {\n return (\n <div\n data-slot=\"chat-shell-turn\"\n data-opens-turn={opensTurn ? 'true' : undefined}\n data-holds-room={holdsRoom ? 'true' : undefined}\n className={cn(\n 'flex flex-col',\n opensTurn &&\n 'min-h-0 transition-[min-height] duration-[1500ms] ease-[cubic-bezier(0.3,0,0.2,1)] motion-reduce:transition-none',\n holdsRoom && 'min-h-[70cqh] duration-[440ms] ease-[cubic-bezier(0.2,0,0.2,1)] starting:min-h-0',\n holdsRoom && restored && 'transition-none',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Composer region, sticky but left in flow: its own height reserves the room the\n * transcript scrolls behind, so nothing measures it and a composer growing under\n * the cursor resizes no box the scroller watches.\n *\n * Behind it, one sheet of the page masked in over `--chat-fade` of air, reaching\n * `--chat-veil` at the dock's top edge. The transcript fades out above the\n * composer and nothing shows through around or under the card.\n */\nexport function ChatShellDock({ className, ...props }: ComponentPropsWithoutRef<'div'>) {\n return (\n <div\n data-slot=\"chat-shell-dock\"\n className={cn(\n 'sticky bottom-0 z-10 mt-(--chat-fade) shrink-0 pb-(--chat-gutter)',\n 'before:pointer-events-none before:absolute before:inset-x-0 before:-top-(--chat-fade) before:bottom-0 before:-z-10',\n 'before:bg-(--chat-surface) before:[mask-image:linear-gradient(to_bottom,transparent,rgb(0_0_0/var(--chat-veil))_var(--chat-fade))]',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Jump-to-latest, floating just above the dock. It belongs inside the dock:\n * anywhere else it centres on a box the scrollbar has not narrowed, landing off\n * the composer's axis.\n */\nexport function ChatShellScrollButton({ className, ...props }: MessageScrollerButtonProps) {\n return (\n <div\n data-slot=\"chat-shell-scroll-button\"\n className=\"pointer-events-none absolute inset-x-0 bottom-[calc(100%+0.5rem)] flex\"\n >\n <ChatShellColumn className=\"flex-row justify-center\">\n <MessageScrollerButton\n className={cn('pointer-events-auto static translate-x-0 rtl:translate-x-0', className)}\n {...props}\n />\n </ChatShellColumn>\n </div>\n );\n}\n","import {\n ChatShellBar,\n ChatShellColumn,\n ChatShellContent,\n ChatShellDock,\n ChatShellRoot,\n ChatShellScrollButton,\n ChatShellStage,\n ChatShellTurn,\n ChatShellViewport,\n} from './chat-shell';\n\nexport type { ChatShellProps, ChatShellTurnProps } from './chat-shell';\n\nexport const ChatShell = Object.assign(ChatShellRoot, {\n Bar: ChatShellBar,\n Column: ChatShellColumn,\n Content: ChatShellContent,\n Dock: ChatShellDock,\n ScrollButton: ChatShellScrollButton,\n Stage: ChatShellStage,\n Turn: ChatShellTurn,\n Viewport: ChatShellViewport,\n});\n"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@ function ComposerSuggestions({
40
40
  ]
41
41
  }
42
42
  ) }),
43
- /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollArea, { maxHeight: "min(22rem, 50dvh)", children: /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollAreaViewport, { className: "overscroll-contain", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id, role: "listbox", "aria-label": label, className: "flex flex-col gap-px p-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
43
+ /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollArea, { maxHeight: "min(22rem, 50dvh)", children: /* @__PURE__ */ jsxRuntime.jsx(scrollArea.ScrollAreaViewport, { className: "overscroll-y-contain", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id, role: "listbox", "aria-label": label, className: "flex flex-col gap-px p-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
44
44
  "button",
45
45
  {
46
46
  ref: index === activeIndex ? activeOption : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Composer.cjs.js","sources":["../../src/ds/components/Composer/commands/composer-suggestions.tsx","../../src/ds/components/Composer/commands/command-matches.ts","../../src/ds/components/Composer/commands/use-composer-commands.ts"],"sourcesContent":["import { Collapsible } from '@base-ui/react/collapsible';\nimport { ArrowLeft, Check } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { ScrollArea, ScrollAreaViewport } from '../../ScrollArea';\nimport { cn } from '@/lib/utils';\n\nexport interface ComposerSuggestionItem {\n id: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerSuggestionsProps {\n id: string;\n items: readonly ComposerSuggestionItem[];\n activeIndex: number;\n contextLabel?: string;\n onBack?: () => void;\n onSelect: (index: number) => void;\n}\n\nexport function ComposerSuggestions({\n id,\n items,\n activeIndex,\n contextLabel,\n onBack,\n onSelect,\n}: ComposerSuggestionsProps) {\n const activeOption = useRef<HTMLButtonElement>(null);\n const activeItemId = items[activeIndex]?.id;\n const label = contextLabel ? `${contextLabel} options` : 'Slash commands';\n\n useEffect(() => {\n activeOption.current?.scrollIntoView({ block: 'nearest' });\n }, [activeItemId]);\n\n return (\n <Collapsible.Root open={items.length > 0}>\n <Collapsible.Panel className=\"h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-normal ease-out-custom data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none\">\n <div className=\"border-b border-border\" role=\"region\" aria-label={label}>\n {contextLabel && onBack && (\n <div className=\"border-b border-border px-1.5 py-1\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 rounded-xl px-2 py-1.5 text-caption text-muted-foreground transition-colors duration-normal ease-out-custom hover:bg-fill-subtle hover:text-foreground motion-reduce:transition-none\"\n aria-label=\"Back to slash commands\"\n onMouseDown={event => event.preventDefault()}\n onClick={onBack}\n >\n <ArrowLeft size={14} aria-hidden />\n <span>{contextLabel}</span>\n </button>\n </div>\n )}\n <ScrollArea maxHeight=\"min(22rem, 50dvh)\">\n <ScrollAreaViewport className=\"overscroll-contain\">\n <div id={id} role=\"listbox\" aria-label={label} className=\"flex flex-col gap-px p-1.5\">\n {items.map((item, index) => (\n <button\n ref={index === activeIndex ? activeOption : undefined}\n id={item.id}\n key={item.id}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n aria-selected={index === activeIndex}\n aria-current={item.active ? 'true' : undefined}\n className={cn(\n 'flex w-full cursor-pointer items-center justify-between gap-4 rounded-2xl px-2 py-1.5 text-left text-caption transition-colors duration-normal ease-out-custom motion-reduce:transition-none',\n index === activeIndex\n ? 'bg-fill-subtle text-foreground'\n : 'text-muted-foreground hover:bg-fill-subtle hover:text-foreground',\n )}\n onMouseDown={event => event.preventDefault()}\n onClick={() => onSelect(index)}\n >\n <span className=\"max-w-[60%] min-w-0 shrink-0 truncate\" title={item.label}>\n {item.label}\n </span>\n {(item.description || item.active) && (\n <span className=\"flex min-w-0 items-center gap-1.5 text-right\">\n {item.description && (\n <span className=\"truncate\" title={item.description}>\n {item.description}\n </span>\n )}\n {item.active && (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Check size={13} aria-hidden />\n Current\n </span>\n )}\n </span>\n )}\n </button>\n ))}\n </div>\n </ScrollAreaViewport>\n </ScrollArea>\n </div>\n </Collapsible.Panel>\n </Collapsible.Root>\n );\n}\n","export interface ComposerCommandOption {\n value: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerCommand {\n name: string;\n description: string;\n options?: readonly ComposerCommandOption[];\n}\n\nexport function matchCommands<T extends Pick<ComposerCommand, 'name'>>(commands: readonly T[], draft: string): T[] {\n if (!draft.startsWith('/')) return [];\n const query = draft.slice(1).toLowerCase();\n if (/\\s/.test(query)) return [];\n return commands.filter(command => command.name.toLowerCase().startsWith(query));\n}\n\nexport function matchCommandOptions<T extends ComposerCommand>(commands: readonly T[], draft: string) {\n if (!draft.startsWith('/')) return undefined;\n const firstWhitespace = draft.search(/\\s/);\n if (firstWhitespace === -1) return undefined;\n const command = commands.find(candidate => candidate.name === draft.slice(1, firstWhitespace));\n if (!command?.options) return undefined;\n const query = draft.slice(firstWhitespace).trim().toLowerCase();\n if (/\\s/.test(query)) return undefined;\n const options = command.options.filter(option => option.value.toLowerCase().startsWith(query));\n return options.length > 0 ? { command, options } : undefined;\n}\n","import type { ChangeEvent, ComponentPropsWithoutRef, RefObject } from 'react';\nimport { useId, useState } from 'react';\nimport type { ComposerCommand, ComposerCommandOption } from './command-matches';\nimport { matchCommandOptions, matchCommands } from './command-matches';\nimport type { ComposerSuggestionItem, ComposerSuggestionsProps } from './composer-suggestions';\nimport { useKeydown } from '@/lib/keyboard/use-keydown';\n\nfunction createSuggestionItems(\n listId: string,\n commands: readonly ComposerCommand[],\n options?: readonly ComposerCommandOption[],\n): ComposerSuggestionItem[] {\n if (options)\n return options.map(option => ({ ...option, id: `${listId}-option-${encodeURIComponent(option.value)}` }));\n return commands.map(command => ({\n id: `${listId}-command-${encodeURIComponent(command.name)}`,\n label: `/${command.name}`,\n description: command.description,\n }));\n}\n\nexport interface UseComposerCommandsProps {\n commands: readonly ComposerCommand[];\n value: string;\n onValueChange: (value: string) => void;\n onSubmit: (value: string) => void;\n inputRef: RefObject<HTMLTextAreaElement | null>;\n enabled?: boolean;\n}\n\nexport function useComposerCommands({\n commands,\n value,\n onValueChange,\n onSubmit,\n inputRef,\n enabled = true,\n}: UseComposerCommandsProps) {\n const listId = useId();\n const [navigation, setNavigation] = useState({ value: '', index: 0 });\n const optionMatch = enabled ? matchCommandOptions(commands, value) : undefined;\n const matchingCommands = enabled && !optionMatch ? matchCommands(commands, value) : [];\n const items = createSuggestionItems(listId, matchingCommands, optionMatch?.options);\n const boundedIndex = Math.min(navigation.index, Math.max(0, items.length - 1));\n const activeIndex = navigation.value === value ? boundedIndex : 0;\n\n function updateValue(nextValue: string) {\n setNavigation({ value: nextValue, index: 0 });\n onValueChange(nextValue);\n }\n\n function returnToCommands() {\n updateValue(optionMatch ? `/${optionMatch.command.name}` : '');\n inputRef.current?.focus();\n }\n\n function selectSuggestion(index: number) {\n inputRef.current?.focus();\n if (optionMatch) {\n const option = optionMatch.options[index];\n if (option) onSubmit(`/${optionMatch.command.name} ${option.value}`);\n return;\n }\n const command = matchingCommands[index];\n if (command) updateValue(`/${command.name} `);\n }\n\n function moveSelection(direction: number) {\n setNavigation({ value, index: (activeIndex + direction + items.length) % items.length });\n }\n\n function shouldHandleCommandKey(event: KeyboardEvent) {\n const command = matchingCommands[activeIndex];\n const submitExactCommand =\n matchingCommands.length === 1 && value.toLowerCase() === `/${command?.name}` && !command?.options?.length;\n return event.key !== 'Enter' || !submitExactCommand;\n }\n\n useKeydown(\n {\n ArrowDown: () => moveSelection(1),\n ArrowUp: () => moveSelection(-1),\n Escape: returnToCommands,\n Tab: () => selectSuggestion(activeIndex),\n Enter: () => selectSuggestion(activeIndex),\n },\n {\n target: inputRef,\n enabled: items.length > 0,\n shouldHandle: shouldHandleCommandKey,\n },\n );\n\n const inputProps = {\n value,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => updateValue(event.target.value),\n 'aria-autocomplete': 'list',\n 'aria-controls': items.length > 0 ? listId : undefined,\n 'aria-activedescendant': items[activeIndex]?.id,\n } satisfies ComponentPropsWithoutRef<'textarea'>;\n\n const suggestionsProps: ComposerSuggestionsProps = {\n id: listId,\n items,\n activeIndex,\n contextLabel: optionMatch ? `/${optionMatch.command.name}` : undefined,\n onBack: optionMatch ? returnToCommands : undefined,\n onSelect: selectSuggestion,\n };\n\n return { inputProps, suggestionsProps };\n}\n"],"names":["useRef","useEffect","jsx","Collapsible","jsxs","ArrowLeft","ScrollArea","ScrollAreaViewport","cn","Check","useId","useState","useKeydown"],"mappings":"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"}
1
+ {"version":3,"file":"Composer.cjs.js","sources":["../../src/ds/components/Composer/commands/composer-suggestions.tsx","../../src/ds/components/Composer/commands/command-matches.ts","../../src/ds/components/Composer/commands/use-composer-commands.ts"],"sourcesContent":["import { Collapsible } from '@base-ui/react/collapsible';\nimport { ArrowLeft, Check } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { ScrollArea, ScrollAreaViewport } from '../../ScrollArea';\nimport { cn } from '@/lib/utils';\n\nexport interface ComposerSuggestionItem {\n id: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerSuggestionsProps {\n id: string;\n items: readonly ComposerSuggestionItem[];\n activeIndex: number;\n contextLabel?: string;\n onBack?: () => void;\n onSelect: (index: number) => void;\n}\n\nexport function ComposerSuggestions({\n id,\n items,\n activeIndex,\n contextLabel,\n onBack,\n onSelect,\n}: ComposerSuggestionsProps) {\n const activeOption = useRef<HTMLButtonElement>(null);\n const activeItemId = items[activeIndex]?.id;\n const label = contextLabel ? `${contextLabel} options` : 'Slash commands';\n\n useEffect(() => {\n activeOption.current?.scrollIntoView({ block: 'nearest' });\n }, [activeItemId]);\n\n return (\n <Collapsible.Root open={items.length > 0}>\n <Collapsible.Panel className=\"h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-normal ease-out-custom data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none\">\n <div className=\"border-b border-border\" role=\"region\" aria-label={label}>\n {contextLabel && onBack && (\n <div className=\"border-b border-border px-1.5 py-1\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 rounded-xl px-2 py-1.5 text-caption text-muted-foreground transition-colors duration-normal ease-out-custom hover:bg-fill-subtle hover:text-foreground motion-reduce:transition-none\"\n aria-label=\"Back to slash commands\"\n onMouseDown={event => event.preventDefault()}\n onClick={onBack}\n >\n <ArrowLeft size={14} aria-hidden />\n <span>{contextLabel}</span>\n </button>\n </div>\n )}\n <ScrollArea maxHeight=\"min(22rem, 50dvh)\">\n <ScrollAreaViewport className=\"overscroll-y-contain\">\n <div id={id} role=\"listbox\" aria-label={label} className=\"flex flex-col gap-px p-1.5\">\n {items.map((item, index) => (\n <button\n ref={index === activeIndex ? activeOption : undefined}\n id={item.id}\n key={item.id}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n aria-selected={index === activeIndex}\n aria-current={item.active ? 'true' : undefined}\n className={cn(\n 'flex w-full cursor-pointer items-center justify-between gap-4 rounded-2xl px-2 py-1.5 text-left text-caption transition-colors duration-normal ease-out-custom motion-reduce:transition-none',\n index === activeIndex\n ? 'bg-fill-subtle text-foreground'\n : 'text-muted-foreground hover:bg-fill-subtle hover:text-foreground',\n )}\n onMouseDown={event => event.preventDefault()}\n onClick={() => onSelect(index)}\n >\n <span className=\"max-w-[60%] min-w-0 shrink-0 truncate\" title={item.label}>\n {item.label}\n </span>\n {(item.description || item.active) && (\n <span className=\"flex min-w-0 items-center gap-1.5 text-right\">\n {item.description && (\n <span className=\"truncate\" title={item.description}>\n {item.description}\n </span>\n )}\n {item.active && (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Check size={13} aria-hidden />\n Current\n </span>\n )}\n </span>\n )}\n </button>\n ))}\n </div>\n </ScrollAreaViewport>\n </ScrollArea>\n </div>\n </Collapsible.Panel>\n </Collapsible.Root>\n );\n}\n","export interface ComposerCommandOption {\n value: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerCommand {\n name: string;\n description: string;\n options?: readonly ComposerCommandOption[];\n}\n\nexport function matchCommands<T extends Pick<ComposerCommand, 'name'>>(commands: readonly T[], draft: string): T[] {\n if (!draft.startsWith('/')) return [];\n const query = draft.slice(1).toLowerCase();\n if (/\\s/.test(query)) return [];\n return commands.filter(command => command.name.toLowerCase().startsWith(query));\n}\n\nexport function matchCommandOptions<T extends ComposerCommand>(commands: readonly T[], draft: string) {\n if (!draft.startsWith('/')) return undefined;\n const firstWhitespace = draft.search(/\\s/);\n if (firstWhitespace === -1) return undefined;\n const command = commands.find(candidate => candidate.name === draft.slice(1, firstWhitespace));\n if (!command?.options) return undefined;\n const query = draft.slice(firstWhitespace).trim().toLowerCase();\n if (/\\s/.test(query)) return undefined;\n const options = command.options.filter(option => option.value.toLowerCase().startsWith(query));\n return options.length > 0 ? { command, options } : undefined;\n}\n","import type { ChangeEvent, ComponentPropsWithoutRef, RefObject } from 'react';\nimport { useId, useState } from 'react';\nimport type { ComposerCommand, ComposerCommandOption } from './command-matches';\nimport { matchCommandOptions, matchCommands } from './command-matches';\nimport type { ComposerSuggestionItem, ComposerSuggestionsProps } from './composer-suggestions';\nimport { useKeydown } from '@/lib/keyboard/use-keydown';\n\nfunction createSuggestionItems(\n listId: string,\n commands: readonly ComposerCommand[],\n options?: readonly ComposerCommandOption[],\n): ComposerSuggestionItem[] {\n if (options)\n return options.map(option => ({ ...option, id: `${listId}-option-${encodeURIComponent(option.value)}` }));\n return commands.map(command => ({\n id: `${listId}-command-${encodeURIComponent(command.name)}`,\n label: `/${command.name}`,\n description: command.description,\n }));\n}\n\nexport interface UseComposerCommandsProps {\n commands: readonly ComposerCommand[];\n value: string;\n onValueChange: (value: string) => void;\n onSubmit: (value: string) => void;\n inputRef: RefObject<HTMLTextAreaElement | null>;\n enabled?: boolean;\n}\n\nexport function useComposerCommands({\n commands,\n value,\n onValueChange,\n onSubmit,\n inputRef,\n enabled = true,\n}: UseComposerCommandsProps) {\n const listId = useId();\n const [navigation, setNavigation] = useState({ value: '', index: 0 });\n const optionMatch = enabled ? matchCommandOptions(commands, value) : undefined;\n const matchingCommands = enabled && !optionMatch ? matchCommands(commands, value) : [];\n const items = createSuggestionItems(listId, matchingCommands, optionMatch?.options);\n const boundedIndex = Math.min(navigation.index, Math.max(0, items.length - 1));\n const activeIndex = navigation.value === value ? boundedIndex : 0;\n\n function updateValue(nextValue: string) {\n setNavigation({ value: nextValue, index: 0 });\n onValueChange(nextValue);\n }\n\n function returnToCommands() {\n updateValue(optionMatch ? `/${optionMatch.command.name}` : '');\n inputRef.current?.focus();\n }\n\n function selectSuggestion(index: number) {\n inputRef.current?.focus();\n if (optionMatch) {\n const option = optionMatch.options[index];\n if (option) onSubmit(`/${optionMatch.command.name} ${option.value}`);\n return;\n }\n const command = matchingCommands[index];\n if (command) updateValue(`/${command.name} `);\n }\n\n function moveSelection(direction: number) {\n setNavigation({ value, index: (activeIndex + direction + items.length) % items.length });\n }\n\n function shouldHandleCommandKey(event: KeyboardEvent) {\n const command = matchingCommands[activeIndex];\n const submitExactCommand =\n matchingCommands.length === 1 && value.toLowerCase() === `/${command?.name}` && !command?.options?.length;\n return event.key !== 'Enter' || !submitExactCommand;\n }\n\n useKeydown(\n {\n ArrowDown: () => moveSelection(1),\n ArrowUp: () => moveSelection(-1),\n Escape: returnToCommands,\n Tab: () => selectSuggestion(activeIndex),\n Enter: () => selectSuggestion(activeIndex),\n },\n {\n target: inputRef,\n enabled: items.length > 0,\n shouldHandle: shouldHandleCommandKey,\n },\n );\n\n const inputProps = {\n value,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => updateValue(event.target.value),\n 'aria-autocomplete': 'list',\n 'aria-controls': items.length > 0 ? listId : undefined,\n 'aria-activedescendant': items[activeIndex]?.id,\n } satisfies ComponentPropsWithoutRef<'textarea'>;\n\n const suggestionsProps: ComposerSuggestionsProps = {\n id: listId,\n items,\n activeIndex,\n contextLabel: optionMatch ? `/${optionMatch.command.name}` : undefined,\n onBack: optionMatch ? returnToCommands : undefined,\n onSelect: selectSuggestion,\n };\n\n return { inputProps, suggestionsProps };\n}\n"],"names":["useRef","useEffect","jsx","Collapsible","jsxs","ArrowLeft","ScrollArea","ScrollAreaViewport","cn","Check","useId","useState","useKeydown"],"mappings":"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"}
@@ -36,7 +36,7 @@ function ComposerSuggestions({
36
36
  ]
37
37
  }
38
38
  ) }),
39
- /* @__PURE__ */ jsx(ScrollArea, { maxHeight: "min(22rem, 50dvh)", children: /* @__PURE__ */ jsx(ScrollAreaViewport, { className: "overscroll-contain", children: /* @__PURE__ */ jsx("div", { id, role: "listbox", "aria-label": label, className: "flex flex-col gap-px p-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxs(
39
+ /* @__PURE__ */ jsx(ScrollArea, { maxHeight: "min(22rem, 50dvh)", children: /* @__PURE__ */ jsx(ScrollAreaViewport, { className: "overscroll-y-contain", children: /* @__PURE__ */ jsx("div", { id, role: "listbox", "aria-label": label, className: "flex flex-col gap-px p-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxs(
40
40
  "button",
41
41
  {
42
42
  ref: index === activeIndex ? activeOption : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Composer.es.js","sources":["../../src/ds/components/Composer/commands/composer-suggestions.tsx","../../src/ds/components/Composer/commands/command-matches.ts","../../src/ds/components/Composer/commands/use-composer-commands.ts"],"sourcesContent":["import { Collapsible } from '@base-ui/react/collapsible';\nimport { ArrowLeft, Check } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { ScrollArea, ScrollAreaViewport } from '../../ScrollArea';\nimport { cn } from '@/lib/utils';\n\nexport interface ComposerSuggestionItem {\n id: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerSuggestionsProps {\n id: string;\n items: readonly ComposerSuggestionItem[];\n activeIndex: number;\n contextLabel?: string;\n onBack?: () => void;\n onSelect: (index: number) => void;\n}\n\nexport function ComposerSuggestions({\n id,\n items,\n activeIndex,\n contextLabel,\n onBack,\n onSelect,\n}: ComposerSuggestionsProps) {\n const activeOption = useRef<HTMLButtonElement>(null);\n const activeItemId = items[activeIndex]?.id;\n const label = contextLabel ? `${contextLabel} options` : 'Slash commands';\n\n useEffect(() => {\n activeOption.current?.scrollIntoView({ block: 'nearest' });\n }, [activeItemId]);\n\n return (\n <Collapsible.Root open={items.length > 0}>\n <Collapsible.Panel className=\"h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-normal ease-out-custom data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none\">\n <div className=\"border-b border-border\" role=\"region\" aria-label={label}>\n {contextLabel && onBack && (\n <div className=\"border-b border-border px-1.5 py-1\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 rounded-xl px-2 py-1.5 text-caption text-muted-foreground transition-colors duration-normal ease-out-custom hover:bg-fill-subtle hover:text-foreground motion-reduce:transition-none\"\n aria-label=\"Back to slash commands\"\n onMouseDown={event => event.preventDefault()}\n onClick={onBack}\n >\n <ArrowLeft size={14} aria-hidden />\n <span>{contextLabel}</span>\n </button>\n </div>\n )}\n <ScrollArea maxHeight=\"min(22rem, 50dvh)\">\n <ScrollAreaViewport className=\"overscroll-contain\">\n <div id={id} role=\"listbox\" aria-label={label} className=\"flex flex-col gap-px p-1.5\">\n {items.map((item, index) => (\n <button\n ref={index === activeIndex ? activeOption : undefined}\n id={item.id}\n key={item.id}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n aria-selected={index === activeIndex}\n aria-current={item.active ? 'true' : undefined}\n className={cn(\n 'flex w-full cursor-pointer items-center justify-between gap-4 rounded-2xl px-2 py-1.5 text-left text-caption transition-colors duration-normal ease-out-custom motion-reduce:transition-none',\n index === activeIndex\n ? 'bg-fill-subtle text-foreground'\n : 'text-muted-foreground hover:bg-fill-subtle hover:text-foreground',\n )}\n onMouseDown={event => event.preventDefault()}\n onClick={() => onSelect(index)}\n >\n <span className=\"max-w-[60%] min-w-0 shrink-0 truncate\" title={item.label}>\n {item.label}\n </span>\n {(item.description || item.active) && (\n <span className=\"flex min-w-0 items-center gap-1.5 text-right\">\n {item.description && (\n <span className=\"truncate\" title={item.description}>\n {item.description}\n </span>\n )}\n {item.active && (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Check size={13} aria-hidden />\n Current\n </span>\n )}\n </span>\n )}\n </button>\n ))}\n </div>\n </ScrollAreaViewport>\n </ScrollArea>\n </div>\n </Collapsible.Panel>\n </Collapsible.Root>\n );\n}\n","export interface ComposerCommandOption {\n value: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerCommand {\n name: string;\n description: string;\n options?: readonly ComposerCommandOption[];\n}\n\nexport function matchCommands<T extends Pick<ComposerCommand, 'name'>>(commands: readonly T[], draft: string): T[] {\n if (!draft.startsWith('/')) return [];\n const query = draft.slice(1).toLowerCase();\n if (/\\s/.test(query)) return [];\n return commands.filter(command => command.name.toLowerCase().startsWith(query));\n}\n\nexport function matchCommandOptions<T extends ComposerCommand>(commands: readonly T[], draft: string) {\n if (!draft.startsWith('/')) return undefined;\n const firstWhitespace = draft.search(/\\s/);\n if (firstWhitespace === -1) return undefined;\n const command = commands.find(candidate => candidate.name === draft.slice(1, firstWhitespace));\n if (!command?.options) return undefined;\n const query = draft.slice(firstWhitespace).trim().toLowerCase();\n if (/\\s/.test(query)) return undefined;\n const options = command.options.filter(option => option.value.toLowerCase().startsWith(query));\n return options.length > 0 ? { command, options } : undefined;\n}\n","import type { ChangeEvent, ComponentPropsWithoutRef, RefObject } from 'react';\nimport { useId, useState } from 'react';\nimport type { ComposerCommand, ComposerCommandOption } from './command-matches';\nimport { matchCommandOptions, matchCommands } from './command-matches';\nimport type { ComposerSuggestionItem, ComposerSuggestionsProps } from './composer-suggestions';\nimport { useKeydown } from '@/lib/keyboard/use-keydown';\n\nfunction createSuggestionItems(\n listId: string,\n commands: readonly ComposerCommand[],\n options?: readonly ComposerCommandOption[],\n): ComposerSuggestionItem[] {\n if (options)\n return options.map(option => ({ ...option, id: `${listId}-option-${encodeURIComponent(option.value)}` }));\n return commands.map(command => ({\n id: `${listId}-command-${encodeURIComponent(command.name)}`,\n label: `/${command.name}`,\n description: command.description,\n }));\n}\n\nexport interface UseComposerCommandsProps {\n commands: readonly ComposerCommand[];\n value: string;\n onValueChange: (value: string) => void;\n onSubmit: (value: string) => void;\n inputRef: RefObject<HTMLTextAreaElement | null>;\n enabled?: boolean;\n}\n\nexport function useComposerCommands({\n commands,\n value,\n onValueChange,\n onSubmit,\n inputRef,\n enabled = true,\n}: UseComposerCommandsProps) {\n const listId = useId();\n const [navigation, setNavigation] = useState({ value: '', index: 0 });\n const optionMatch = enabled ? matchCommandOptions(commands, value) : undefined;\n const matchingCommands = enabled && !optionMatch ? matchCommands(commands, value) : [];\n const items = createSuggestionItems(listId, matchingCommands, optionMatch?.options);\n const boundedIndex = Math.min(navigation.index, Math.max(0, items.length - 1));\n const activeIndex = navigation.value === value ? boundedIndex : 0;\n\n function updateValue(nextValue: string) {\n setNavigation({ value: nextValue, index: 0 });\n onValueChange(nextValue);\n }\n\n function returnToCommands() {\n updateValue(optionMatch ? `/${optionMatch.command.name}` : '');\n inputRef.current?.focus();\n }\n\n function selectSuggestion(index: number) {\n inputRef.current?.focus();\n if (optionMatch) {\n const option = optionMatch.options[index];\n if (option) onSubmit(`/${optionMatch.command.name} ${option.value}`);\n return;\n }\n const command = matchingCommands[index];\n if (command) updateValue(`/${command.name} `);\n }\n\n function moveSelection(direction: number) {\n setNavigation({ value, index: (activeIndex + direction + items.length) % items.length });\n }\n\n function shouldHandleCommandKey(event: KeyboardEvent) {\n const command = matchingCommands[activeIndex];\n const submitExactCommand =\n matchingCommands.length === 1 && value.toLowerCase() === `/${command?.name}` && !command?.options?.length;\n return event.key !== 'Enter' || !submitExactCommand;\n }\n\n useKeydown(\n {\n ArrowDown: () => moveSelection(1),\n ArrowUp: () => moveSelection(-1),\n Escape: returnToCommands,\n Tab: () => selectSuggestion(activeIndex),\n Enter: () => selectSuggestion(activeIndex),\n },\n {\n target: inputRef,\n enabled: items.length > 0,\n shouldHandle: shouldHandleCommandKey,\n },\n );\n\n const inputProps = {\n value,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => updateValue(event.target.value),\n 'aria-autocomplete': 'list',\n 'aria-controls': items.length > 0 ? listId : undefined,\n 'aria-activedescendant': items[activeIndex]?.id,\n } satisfies ComponentPropsWithoutRef<'textarea'>;\n\n const suggestionsProps: ComposerSuggestionsProps = {\n id: listId,\n items,\n activeIndex,\n contextLabel: optionMatch ? `/${optionMatch.command.name}` : undefined,\n onBack: optionMatch ? returnToCommands : undefined,\n onSelect: selectSuggestion,\n };\n\n return { inputProps, suggestionsProps };\n}\n"],"names":[],"mappings":";;;;;;;;;AAsBO,SAAS,mBAAA,CAAoB;AAAA,EAClC,EAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAA6B;AAC3B,EAAA,MAAM,YAAA,GAAe,OAA0B,IAAI,CAAA;AACnD,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,WAAW,CAAA,EAAG,EAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,YAAA,GAAe,CAAA,EAAG,YAAY,CAAA,QAAA,CAAA,GAAa,gBAAA;AAEzD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,YAAA,CAAa,OAAA,EAAS,cAAA,CAAe,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,EAC3D,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,EAAA,uBACE,GAAA,CAAC,YAAY,IAAA,EAAZ,EAAiB,MAAM,KAAA,CAAM,MAAA,GAAS,GACrC,QAAA,kBAAA,GAAA,CAAC,WAAA,CAAY,OAAZ,EAAkB,SAAA,EAAU,2LAC3B,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wBAAA,EAAyB,IAAA,EAAK,QAAA,EAAS,YAAA,EAAY,KAAA,EAC/D,QAAA,EAAA;AAAA,IAAA,YAAA,IAAgB,MAAA,oBACf,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,kBAAA,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,gNAAA;AAAA,QACV,YAAA,EAAW,wBAAA;AAAA,QACX,WAAA,EAAa,CAAA,KAAA,KAAS,KAAA,CAAM,cAAA,EAAe;AAAA,QAC3C,OAAA,EAAS,MAAA;AAAA,QAET,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAM,EAAA,EAAI,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,0BACjC,GAAA,CAAC,UAAM,QAAA,EAAA,YAAA,EAAa;AAAA;AAAA;AAAA,KACtB,EACF,CAAA;AAAA,oBAEF,GAAA,CAAC,cAAW,SAAA,EAAU,mBAAA,EACpB,8BAAC,kBAAA,EAAA,EAAmB,SAAA,EAAU,sBAC5B,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,IAAQ,IAAA,EAAK,SAAA,EAAU,cAAY,KAAA,EAAO,SAAA,EAAU,8BACtD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBAChB,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,KAAA,KAAU,WAAA,GAAc,YAAA,GAAe,MAAA;AAAA,QAC5C,IAAI,IAAA,CAAK,EAAA;AAAA,QAET,IAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,QAAA,EAAU,EAAA;AAAA,QACV,iBAAe,KAAA,KAAU,WAAA;AAAA,QACzB,cAAA,EAAc,IAAA,CAAK,MAAA,GAAS,MAAA,GAAS,MAAA;AAAA,QACrC,SAAA,EAAW,EAAA;AAAA,UACT,8LAAA;AAAA,UACA,KAAA,KAAU,cACN,gCAAA,GACA;AAAA,SACN;AAAA,QACA,WAAA,EAAa,CAAA,KAAA,KAAS,KAAA,CAAM,cAAA,EAAe;AAAA,QAC3C,OAAA,EAAS,MAAM,QAAA,CAAS,KAAK,CAAA;AAAA,QAE7B,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAK,SAAA,EAAU,uCAAA,EAAwC,OAAO,IAAA,CAAK,KAAA,EACjE,eAAK,KAAA,EACR,CAAA;AAAA,UAAA,CACE,KAAK,WAAA,IAAe,IAAA,CAAK,2BACzB,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,8CAAA,EACb,QAAA,EAAA;AAAA,YAAA,IAAA,CAAK,WAAA,wBACH,MAAA,EAAA,EAAK,SAAA,EAAU,YAAW,KAAA,EAAO,IAAA,CAAK,WAAA,EACpC,QAAA,EAAA,IAAA,CAAK,WAAA,EACR,CAAA;AAAA,YAED,IAAA,CAAK,MAAA,oBACJ,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,kCAAA,EACd,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,EAAA,EAAI,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,cAAE;AAAA,aAAA,EAEjC;AAAA,WAAA,EAEJ;AAAA;AAAA,OAAA;AAAA,MA/BG,IAAA,CAAK;AAAA,KAkCb,CAAA,EACH,CAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,GACF,CAAA,EACF,CAAA;AAEJ;;AC5FO,SAAS,aAAA,CAAuD,UAAwB,KAAA,EAAoB;AACjH,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,SAAU,EAAC;AACpC,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAC,EAAE,WAAA,EAAY;AACzC,EAAA,IAAI,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,SAAU,EAAC;AAC9B,EAAA,OAAO,QAAA,CAAS,OAAO,CAAA,OAAA,KAAW,OAAA,CAAQ,KAAK,WAAA,EAAY,CAAE,UAAA,CAAW,KAAK,CAAC,CAAA;AAChF;AAEO,SAAS,mBAAA,CAA+C,UAAwB,KAAA,EAAe;AACpG,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,GAAG,GAAG,OAAO,MAAA;AACnC,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AACzC,EAAA,IAAI,eAAA,KAAoB,IAAI,OAAO,MAAA;AACnC,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,CAAA,SAAA,KAAa,SAAA,CAAU,SAAS,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,eAAe,CAAC,CAAA;AAC7F,EAAA,IAAI,CAAC,OAAA,EAAS,OAAA,EAAS,OAAO,MAAA;AAC9B,EAAA,MAAM,QAAQ,KAAA,CAAM,KAAA,CAAM,eAAe,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AAC9D,EAAA,IAAI,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,EAAG,OAAO,MAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,MAAA,CAAO,CAAA,MAAA,KAAU,MAAA,CAAO,KAAA,CAAM,WAAA,EAAY,CAAE,UAAA,CAAW,KAAK,CAAC,CAAA;AAC7F,EAAA,OAAO,QAAQ,MAAA,GAAS,CAAA,GAAI,EAAE,OAAA,EAAS,SAAQ,GAAI,MAAA;AACrD;;ACvBA,SAAS,qBAAA,CACP,MAAA,EACA,QAAA,EACA,OAAA,EAC0B;AAC1B,EAAA,IAAI,OAAA;AACF,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,MAAW,EAAE,GAAG,MAAA,EAAQ,EAAA,EAAI,CAAA,EAAG,MAAM,WAAW,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAC,IAAG,CAAE,CAAA;AAC1G,EAAA,OAAO,QAAA,CAAS,IAAI,CAAA,OAAA,MAAY;AAAA,IAC9B,IAAI,CAAA,EAAG,MAAM,YAAY,kBAAA,CAAmB,OAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;AAAA,IACzD,KAAA,EAAO,CAAA,CAAA,EAAI,OAAA,CAAQ,IAAI,CAAA,CAAA;AAAA,IACvB,aAAa,OAAA,CAAQ;AAAA,GACvB,CAAE,CAAA;AACJ;AAWO,SAAS,mBAAA,CAAoB;AAAA,EAClC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA,GAAU;AACZ,CAAA,EAA6B;AAC3B,EAAA,MAAM,SAAS,KAAA,EAAM;AACrB,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA,CAAS,EAAE,KAAA,EAAO,EAAA,EAAI,KAAA,EAAO,CAAA,EAAG,CAAA;AACpE,EAAA,MAAM,WAAA,GAAc,OAAA,GAAU,mBAAA,CAAoB,QAAA,EAAU,KAAK,CAAA,GAAI,MAAA;AACrE,EAAA,MAAM,gBAAA,GAAmB,WAAW,CAAC,WAAA,GAAc,cAAc,QAAA,EAAU,KAAK,IAAI,EAAC;AACrF,EAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,MAAA,EAAQ,gBAAA,EAAkB,aAAa,OAAO,CAAA;AAClF,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,MAAA,GAAS,CAAC,CAAC,CAAA;AAC7E,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,KAAA,KAAU,KAAA,GAAQ,YAAA,GAAe,CAAA;AAEhE,EAAA,SAAS,YAAY,SAAA,EAAmB;AACtC,IAAA,aAAA,CAAc,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,GAAG,CAAA;AAC5C,IAAA,aAAA,CAAc,SAAS,CAAA;AAAA,EACzB;AAEA,EAAA,SAAS,gBAAA,GAAmB;AAC1B,IAAA,WAAA,CAAY,cAAc,CAAA,CAAA,EAAI,WAAA,CAAY,OAAA,CAAQ,IAAI,KAAK,EAAE,CAAA;AAC7D,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,EAC1B;AAEA,EAAA,SAAS,iBAAiB,KAAA,EAAe;AACvC,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACxC,MAAA,IAAI,MAAA,WAAiB,CAAA,CAAA,EAAI,WAAA,CAAY,QAAQ,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AACnE,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,iBAAiB,KAAK,CAAA;AACtC,IAAA,IAAI,OAAA,EAAS,WAAA,CAAY,CAAA,CAAA,EAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EAC9C;AAEA,EAAA,SAAS,cAAc,SAAA,EAAmB;AACxC,IAAA,aAAA,CAAc,EAAE,OAAO,KAAA,EAAA,CAAQ,WAAA,GAAc,YAAY,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,MAAA,EAAQ,CAAA;AAAA,EACzF;AAEA,EAAA,SAAS,uBAAuB,KAAA,EAAsB;AACpD,IAAA,MAAM,OAAA,GAAU,iBAAiB,WAAW,CAAA;AAC5C,IAAA,MAAM,kBAAA,GACJ,gBAAA,CAAiB,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,WAAA,EAAY,KAAM,CAAA,CAAA,EAAI,OAAA,EAAS,IAAI,CAAA,CAAA,IAAM,CAAC,SAAS,OAAA,EAAS,MAAA;AACrG,IAAA,OAAO,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,CAAC,kBAAA;AAAA,EACnC;AAEA,EAAA,UAAA;AAAA,IACE;AAAA,MACE,SAAA,EAAW,MAAM,aAAA,CAAc,CAAC,CAAA;AAAA,MAChC,OAAA,EAAS,MAAM,aAAA,CAAc,EAAE,CAAA;AAAA,MAC/B,MAAA,EAAQ,gBAAA;AAAA,MACR,GAAA,EAAK,MAAM,gBAAA,CAAiB,WAAW,CAAA;AAAA,MACvC,KAAA,EAAO,MAAM,gBAAA,CAAiB,WAAW;AAAA,KAC3C;AAAA,IACA;AAAA,MACE,MAAA,EAAQ,QAAA;AAAA,MACR,OAAA,EAAS,MAAM,MAAA,GAAS,CAAA;AAAA,MACxB,YAAA,EAAc;AAAA;AAChB,GACF;AAEA,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,KAAA;AAAA,IACA,UAAU,CAAC,KAAA,KAA4C,WAAA,CAAY,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,IACrF,mBAAA,EAAqB,MAAA;AAAA,IACrB,eAAA,EAAiB,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,MAAA;AAAA,IAC7C,uBAAA,EAAyB,KAAA,CAAM,WAAW,CAAA,EAAG;AAAA,GAC/C;AAEA,EAAA,MAAM,gBAAA,GAA6C;AAAA,IACjD,EAAA,EAAI,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAc,WAAA,GAAc,CAAA,CAAA,EAAI,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAA,CAAA,GAAK,MAAA;AAAA,IAC7D,MAAA,EAAQ,cAAc,gBAAA,GAAmB,MAAA;AAAA,IACzC,QAAA,EAAU;AAAA,GACZ;AAEA,EAAA,OAAO,EAAE,YAAY,gBAAA,EAAiB;AACxC;;;;"}
1
+ {"version":3,"file":"Composer.es.js","sources":["../../src/ds/components/Composer/commands/composer-suggestions.tsx","../../src/ds/components/Composer/commands/command-matches.ts","../../src/ds/components/Composer/commands/use-composer-commands.ts"],"sourcesContent":["import { Collapsible } from '@base-ui/react/collapsible';\nimport { ArrowLeft, Check } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { ScrollArea, ScrollAreaViewport } from '../../ScrollArea';\nimport { cn } from '@/lib/utils';\n\nexport interface ComposerSuggestionItem {\n id: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerSuggestionsProps {\n id: string;\n items: readonly ComposerSuggestionItem[];\n activeIndex: number;\n contextLabel?: string;\n onBack?: () => void;\n onSelect: (index: number) => void;\n}\n\nexport function ComposerSuggestions({\n id,\n items,\n activeIndex,\n contextLabel,\n onBack,\n onSelect,\n}: ComposerSuggestionsProps) {\n const activeOption = useRef<HTMLButtonElement>(null);\n const activeItemId = items[activeIndex]?.id;\n const label = contextLabel ? `${contextLabel} options` : 'Slash commands';\n\n useEffect(() => {\n activeOption.current?.scrollIntoView({ block: 'nearest' });\n }, [activeItemId]);\n\n return (\n <Collapsible.Root open={items.length > 0}>\n <Collapsible.Panel className=\"h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-normal ease-out-custom data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none\">\n <div className=\"border-b border-border\" role=\"region\" aria-label={label}>\n {contextLabel && onBack && (\n <div className=\"border-b border-border px-1.5 py-1\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 rounded-xl px-2 py-1.5 text-caption text-muted-foreground transition-colors duration-normal ease-out-custom hover:bg-fill-subtle hover:text-foreground motion-reduce:transition-none\"\n aria-label=\"Back to slash commands\"\n onMouseDown={event => event.preventDefault()}\n onClick={onBack}\n >\n <ArrowLeft size={14} aria-hidden />\n <span>{contextLabel}</span>\n </button>\n </div>\n )}\n <ScrollArea maxHeight=\"min(22rem, 50dvh)\">\n <ScrollAreaViewport className=\"overscroll-y-contain\">\n <div id={id} role=\"listbox\" aria-label={label} className=\"flex flex-col gap-px p-1.5\">\n {items.map((item, index) => (\n <button\n ref={index === activeIndex ? activeOption : undefined}\n id={item.id}\n key={item.id}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n aria-selected={index === activeIndex}\n aria-current={item.active ? 'true' : undefined}\n className={cn(\n 'flex w-full cursor-pointer items-center justify-between gap-4 rounded-2xl px-2 py-1.5 text-left text-caption transition-colors duration-normal ease-out-custom motion-reduce:transition-none',\n index === activeIndex\n ? 'bg-fill-subtle text-foreground'\n : 'text-muted-foreground hover:bg-fill-subtle hover:text-foreground',\n )}\n onMouseDown={event => event.preventDefault()}\n onClick={() => onSelect(index)}\n >\n <span className=\"max-w-[60%] min-w-0 shrink-0 truncate\" title={item.label}>\n {item.label}\n </span>\n {(item.description || item.active) && (\n <span className=\"flex min-w-0 items-center gap-1.5 text-right\">\n {item.description && (\n <span className=\"truncate\" title={item.description}>\n {item.description}\n </span>\n )}\n {item.active && (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Check size={13} aria-hidden />\n Current\n </span>\n )}\n </span>\n )}\n </button>\n ))}\n </div>\n </ScrollAreaViewport>\n </ScrollArea>\n </div>\n </Collapsible.Panel>\n </Collapsible.Root>\n );\n}\n","export interface ComposerCommandOption {\n value: string;\n label: string;\n description?: string;\n active?: boolean;\n}\n\nexport interface ComposerCommand {\n name: string;\n description: string;\n options?: readonly ComposerCommandOption[];\n}\n\nexport function matchCommands<T extends Pick<ComposerCommand, 'name'>>(commands: readonly T[], draft: string): T[] {\n if (!draft.startsWith('/')) return [];\n const query = draft.slice(1).toLowerCase();\n if (/\\s/.test(query)) return [];\n return commands.filter(command => command.name.toLowerCase().startsWith(query));\n}\n\nexport function matchCommandOptions<T extends ComposerCommand>(commands: readonly T[], draft: string) {\n if (!draft.startsWith('/')) return undefined;\n const firstWhitespace = draft.search(/\\s/);\n if (firstWhitespace === -1) return undefined;\n const command = commands.find(candidate => candidate.name === draft.slice(1, firstWhitespace));\n if (!command?.options) return undefined;\n const query = draft.slice(firstWhitespace).trim().toLowerCase();\n if (/\\s/.test(query)) return undefined;\n const options = command.options.filter(option => option.value.toLowerCase().startsWith(query));\n return options.length > 0 ? { command, options } : undefined;\n}\n","import type { ChangeEvent, ComponentPropsWithoutRef, RefObject } from 'react';\nimport { useId, useState } from 'react';\nimport type { ComposerCommand, ComposerCommandOption } from './command-matches';\nimport { matchCommandOptions, matchCommands } from './command-matches';\nimport type { ComposerSuggestionItem, ComposerSuggestionsProps } from './composer-suggestions';\nimport { useKeydown } from '@/lib/keyboard/use-keydown';\n\nfunction createSuggestionItems(\n listId: string,\n commands: readonly ComposerCommand[],\n options?: readonly ComposerCommandOption[],\n): ComposerSuggestionItem[] {\n if (options)\n return options.map(option => ({ ...option, id: `${listId}-option-${encodeURIComponent(option.value)}` }));\n return commands.map(command => ({\n id: `${listId}-command-${encodeURIComponent(command.name)}`,\n label: `/${command.name}`,\n description: command.description,\n }));\n}\n\nexport interface UseComposerCommandsProps {\n commands: readonly ComposerCommand[];\n value: string;\n onValueChange: (value: string) => void;\n onSubmit: (value: string) => void;\n inputRef: RefObject<HTMLTextAreaElement | null>;\n enabled?: boolean;\n}\n\nexport function useComposerCommands({\n commands,\n value,\n onValueChange,\n onSubmit,\n inputRef,\n enabled = true,\n}: UseComposerCommandsProps) {\n const listId = useId();\n const [navigation, setNavigation] = useState({ value: '', index: 0 });\n const optionMatch = enabled ? matchCommandOptions(commands, value) : undefined;\n const matchingCommands = enabled && !optionMatch ? matchCommands(commands, value) : [];\n const items = createSuggestionItems(listId, matchingCommands, optionMatch?.options);\n const boundedIndex = Math.min(navigation.index, Math.max(0, items.length - 1));\n const activeIndex = navigation.value === value ? boundedIndex : 0;\n\n function updateValue(nextValue: string) {\n setNavigation({ value: nextValue, index: 0 });\n onValueChange(nextValue);\n }\n\n function returnToCommands() {\n updateValue(optionMatch ? `/${optionMatch.command.name}` : '');\n inputRef.current?.focus();\n }\n\n function selectSuggestion(index: number) {\n inputRef.current?.focus();\n if (optionMatch) {\n const option = optionMatch.options[index];\n if (option) onSubmit(`/${optionMatch.command.name} ${option.value}`);\n return;\n }\n const command = matchingCommands[index];\n if (command) updateValue(`/${command.name} `);\n }\n\n function moveSelection(direction: number) {\n setNavigation({ value, index: (activeIndex + direction + items.length) % items.length });\n }\n\n function shouldHandleCommandKey(event: KeyboardEvent) {\n const command = matchingCommands[activeIndex];\n const submitExactCommand =\n matchingCommands.length === 1 && value.toLowerCase() === `/${command?.name}` && !command?.options?.length;\n return event.key !== 'Enter' || !submitExactCommand;\n }\n\n useKeydown(\n {\n ArrowDown: () => moveSelection(1),\n ArrowUp: () => moveSelection(-1),\n Escape: returnToCommands,\n Tab: () => selectSuggestion(activeIndex),\n Enter: () => selectSuggestion(activeIndex),\n },\n {\n target: inputRef,\n enabled: items.length > 0,\n shouldHandle: shouldHandleCommandKey,\n },\n );\n\n const inputProps = {\n value,\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => updateValue(event.target.value),\n 'aria-autocomplete': 'list',\n 'aria-controls': items.length > 0 ? listId : undefined,\n 'aria-activedescendant': items[activeIndex]?.id,\n } satisfies ComponentPropsWithoutRef<'textarea'>;\n\n const suggestionsProps: ComposerSuggestionsProps = {\n id: listId,\n items,\n activeIndex,\n contextLabel: optionMatch ? `/${optionMatch.command.name}` : undefined,\n onBack: optionMatch ? returnToCommands : undefined,\n onSelect: selectSuggestion,\n };\n\n return { inputProps, suggestionsProps };\n}\n"],"names":[],"mappings":"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"}
@@ -2,14 +2,14 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
- const dataList = require('../data-list-DUfXIhyC.cjs');
6
- const dataListSkeleton = require('../data-list-skeleton-BqC9Gggi.cjs');
5
+ const dataList = require('../data-list-CmjTe8xE.cjs');
6
+ const dataListSkeleton = require('../data-list-skeleton-sdcaabdX.cjs');
7
7
  const jsxRuntime = require('react/jsx-runtime');
8
- const dataListSpacer = require('../data-list-spacer-tQaBaum4.cjs');
9
- const dataListTop = require('../data-list-top-ByT2Mo77.cjs');
8
+ const dataListSpacer = require('../data-list-spacer-CdlT6bDd.cjs');
9
+ const dataListTop = require('../data-list-top-DJh08vFA.cjs');
10
10
  const Txt = require('../Txt-CIS2G5Jx.cjs');
11
11
  const utils_dateFormat = require('../utils/date-format.cjs.js');
12
- const tracesDataList = require('../traces-data-list-BgjeB-BF.cjs');
12
+ const tracesDataList = require('../traces-data-list-Bhhg9drs.cjs');
13
13
  const useDataListKeyboard = require('../use-data-list-keyboard-DF3tLe10.cjs');
14
14
  const layout_tabbedContainer = require('../layout/tabbed-container.cjs.js');
15
15
 
@@ -1,11 +1,11 @@
1
- export { D as DataList } from '../data-list-DXQY_iQW.js';
2
- export { D as DataListSkeleton, a as DataListSkeletonRows } from '../data-list-skeleton-B_SXAeE0.js';
1
+ export { D as DataList } from '../data-list-DT1LVR29.js';
2
+ export { D as DataListSkeleton, a as DataListSkeletonRows } from '../data-list-skeleton-bNfITSHs.js';
3
3
  import { jsx } from 'react/jsx-runtime';
4
- import { D as DataListNextPageLoading, a as DataListNoMatch, d as DataListRowButton, f as DataListSortableTopCell } from '../data-list-spacer-ByA4ce2a.js';
5
- import { c as DataListCell, b as DataListTopCell, a as DataListTop, D as DataListRoot } from '../data-list-top-DSr_ocKA.js';
4
+ import { D as DataListNextPageLoading, a as DataListNoMatch, d as DataListRowButton, f as DataListSortableTopCell } from '../data-list-spacer-D--gDmOm.js';
5
+ import { c as DataListCell, b as DataListTopCell, a as DataListTop, D as DataListRoot } from '../data-list-top-T-mtdIUp.js';
6
6
  import { T as Txt } from '../Txt-BtIGLRk1.js';
7
7
  import { formatDate } from '../utils/date-format.es.js';
8
- export { T as TracesDataList } from '../traces-data-list-Zoai0OW_.js';
8
+ export { T as TracesDataList } from '../traces-data-list-DMWPJFBc.js';
9
9
  export { u as useDataListKeyboard } from '../use-data-list-keyboard-DFQr4t38.js';
10
10
  export { TabbedContainer } from '../layout/tabbed-container.es.js';
11
11
 
@@ -10,7 +10,7 @@ const Button = require('../Button-DH1aTzbs.cjs');
10
10
  const Notice = require('../Notice-DYgIy4FO.cjs');
11
11
  const envFile = require('../env-file-BU2hStkm.cjs');
12
12
  const Txt = require('../Txt-CIS2G5Jx.cjs');
13
- const dataList = require('../data-list-DUfXIhyC.cjs');
13
+ const dataList = require('../data-list-CmjTe8xE.cjs');
14
14
  const hooks_useCopyToClipboard = require('../hooks/use-copy-to-clipboard.cjs.js');
15
15
  const field = require('../field-BCU5ZtWV.cjs');
16
16
  require('../field-control-aria-WzMGs0A4.cjs');
@@ -6,7 +6,7 @@ import { B as Button } from '../Button-EGoajBQY.js';
6
6
  import { N as Notice } from '../Notice-BioYTS4b.js';
7
7
  import { D as DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE } from '../env-file-BITYowCx.js';
8
8
  import { T as Txt } from '../Txt-BtIGLRk1.js';
9
- import { D as DataList } from '../data-list-DXQY_iQW.js';
9
+ import { D as DataList } from '../data-list-DT1LVR29.js';
10
10
  import { useCopyToClipboard } from '../hooks/use-copy-to-clipboard.es.js';
11
11
  import { F as Field, e as FieldLabel, c as FieldError } from '../field-Dl1zeXTv.js';
12
12
  import '../field-control-aria-DB6y41tQ.js';
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
- const logsDataList = require('../logs-data-list-DRR6cMgl.cjs');
6
- const dataListSkeleton = require('../data-list-skeleton-BqC9Gggi.cjs');
5
+ const logsDataList = require('../logs-data-list-DlQxxrNw.cjs');
6
+ const dataListSkeleton = require('../data-list-skeleton-sdcaabdX.cjs');
7
7
 
8
8
 
9
9
 
@@ -1,3 +1,3 @@
1
- export { L as LogsDataList } from '../logs-data-list-CoER2Hst.js';
2
- export { D as LogsDataListSkeleton } from '../data-list-skeleton-B_SXAeE0.js';
1
+ export { L as LogsDataList } from '../logs-data-list-Cb85LPcT.js';
2
+ export { D as LogsDataListSkeleton } from '../data-list-skeleton-bNfITSHs.js';
3
3
  //# sourceMappingURL=LogsDataList.es.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
- const messageScroller = require('../message-scroller-C4fH6uJg.cjs');
5
+ const messageScroller = require('../message-scroller-fjucuCuw.cjs');
6
6
  const messageScrollerHooks = require('../message-scroller-hooks-BxAf8k0Y.cjs');
7
7
 
8
8
 
@@ -1,3 +1,3 @@
1
- export { M as MessageScroller, a as MessageScrollerButton, b as MessageScrollerContent, c as MessageScrollerItem, d as MessageScrollerProvider, e as MessageScrollerViewport } from '../message-scroller-CS1KxKn6.js';
1
+ export { M as MessageScroller, a as MessageScrollerButton, b as MessageScrollerContent, c as MessageScrollerItem, d as MessageScrollerProvider, e as MessageScrollerViewport } from '../message-scroller-C6gXU5d5.js';
2
2
  export { u as useMessageScroller, a as useMessageScrollerScrollable, b as useMessageScrollerVisibility, c as useOptionalMessageScroller, d as useOptionalMessageScrollerScrollable, e as useOptionalMessageScrollerVisibility } from '../message-scroller-hooks-BEeE1WE6.js';
3
3
  //# sourceMappingURL=MessageScroller.es.js.map
@@ -171,7 +171,6 @@ function SavedViewTabs({
171
171
  Button.Button,
172
172
  {
173
173
  type: "button",
174
- variant: "ghost",
175
174
  size: "icon-sm",
176
175
  tooltip: "New view",
177
176
  disabled: draft !== void 0,