@langchain/macaw-components 1.0.0-beta.0 → 1.0.0-beta.6

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 (187) hide show
  1. package/dist/_chunks/{LoadingIndicator-DgtU9aqD.js → LoadingIndicator-CDcArsiM.js} +13 -12
  2. package/dist/_chunks/LoadingIndicator-CDcArsiM.js.map +1 -0
  3. package/dist/_chunks/render-attachment-icon-BWBEMxXZ.js +270 -0
  4. package/dist/_chunks/render-attachment-icon-BWBEMxXZ.js.map +1 -0
  5. package/dist/catalog.json +527 -408
  6. package/dist/components/Attachment/Attachment.d.ts +21 -0
  7. package/dist/components/Attachment/Attachment.js +165 -0
  8. package/dist/components/Attachment/Attachment.js.map +1 -0
  9. package/dist/components/Attachment/AttachmentList.d.ts +5 -0
  10. package/dist/components/Attachment/AttachmentList.js +32 -0
  11. package/dist/components/Attachment/AttachmentList.js.map +1 -0
  12. package/dist/components/Attachment/index.d.ts +4 -0
  13. package/dist/components/Attachment/index.js +3 -0
  14. package/dist/components/Attachment/render-attachment-icon.d.ts +3 -0
  15. package/dist/components/Attachment/render-attachment-icon.js +2 -0
  16. package/dist/components/Avatar/Avatar.js +2 -2
  17. package/dist/components/Badge/Badge.d.ts +2 -0
  18. package/dist/components/Badge/Badge.js +12 -1
  19. package/dist/components/Badge/Badge.js.map +1 -1
  20. package/dist/components/Banner/Banner.js +1 -1
  21. package/dist/components/Button/Button.js +1 -1
  22. package/dist/components/Button/constants.js +2 -2
  23. package/dist/components/Button/constants.js.map +1 -1
  24. package/dist/components/ChartCard/ChartCard.d.ts +1 -4
  25. package/dist/components/ChartCard/ChartCard.js +2 -2
  26. package/dist/components/ChartCard/ChartCard.js.map +1 -1
  27. package/dist/components/ChartCard/ChartCardSkeleton.d.ts +1 -1
  28. package/dist/components/ChartCard/ChartCardSkeleton.js +37 -0
  29. package/dist/components/ChartCard/ChartCardSkeleton.js.map +1 -1
  30. package/dist/components/ChartLegend/ChartLegend.js +2 -2
  31. package/dist/components/ChartLegend/ChartLegendItemRenderer.js +2 -2
  32. package/dist/components/ChartLegend/ChartLegendItemRenderer.js.map +1 -1
  33. package/dist/components/Code/Code.utils.d.ts +3 -2
  34. package/dist/components/Code/Code.utils.js +7 -3
  35. package/dist/components/Code/Code.utils.js.map +1 -1
  36. package/dist/components/Code/CodeLanguageSelect.d.ts +7 -0
  37. package/dist/components/Code/CodeLanguageSelect.js +29 -0
  38. package/dist/components/Code/CodeLanguageSelect.js.map +1 -0
  39. package/dist/components/Code/CodeLite.js +3 -0
  40. package/dist/components/Code/CodeLite.js.map +1 -1
  41. package/dist/components/Code/CodeToolbar.d.ts +7 -0
  42. package/dist/components/Code/CodeToolbar.js +19 -0
  43. package/dist/components/Code/CodeToolbar.js.map +1 -0
  44. package/dist/components/Code/codeLanguages.d.ts +7 -0
  45. package/dist/components/Code/codeLanguages.js +59 -0
  46. package/dist/components/Code/codeLanguages.js.map +1 -0
  47. package/dist/components/Code/index.d.ts +15 -2
  48. package/dist/components/Code/index.js +70 -50
  49. package/dist/components/Code/index.js.map +1 -1
  50. package/dist/components/Code/types.d.ts +1 -1
  51. package/dist/components/Command/Command.d.ts +10 -13
  52. package/dist/components/Command/Command.js +7 -2
  53. package/dist/components/Command/Command.js.map +1 -1
  54. package/dist/components/Command/CommandMenu.d.ts +7 -1
  55. package/dist/components/Command/CommandMenu.js +17 -9
  56. package/dist/components/Command/CommandMenu.js.map +1 -1
  57. package/dist/components/ContextMenu/ContextMenu.d.ts +6 -0
  58. package/dist/components/ContextMenu/ContextMenu.js +3 -2
  59. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  60. package/dist/components/CopyButton/CopyButton.js +2 -2
  61. package/dist/components/Dialog/index.js +2 -2
  62. package/dist/components/DropdownMenu/DropdownMenu.d.ts +11 -0
  63. package/dist/components/DropdownMenu/DropdownMenu.js +5 -4
  64. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  65. package/dist/components/ErrorMessage/ErrorMessage.js +1 -1
  66. package/dist/components/GroupedTabs/GroupedTabs.d.ts +5 -2
  67. package/dist/components/GroupedTabs/GroupedTabs.js +33 -26
  68. package/dist/components/GroupedTabs/GroupedTabs.js.map +1 -1
  69. package/dist/components/IconButton/IconButton.js +2 -2
  70. package/dist/components/Input/Input.js +1 -1
  71. package/dist/components/LineChart/LineChart.d.ts +2 -2
  72. package/dist/components/LineChart/LineChart.js +3 -1
  73. package/dist/components/LineChart/LineChart.js.map +1 -1
  74. package/dist/components/LineChart/LineChart.types.d.ts +16 -0
  75. package/dist/components/LineChart/LineChartPlot.d.ts +3 -2
  76. package/dist/components/LineChart/LineChartPlot.js +8 -1
  77. package/dist/components/LineChart/LineChartPlot.js.map +1 -1
  78. package/dist/components/LineChart/LineChartVerticalMarkers.d.ts +8 -0
  79. package/dist/components/LineChart/LineChartVerticalMarkers.js +47 -0
  80. package/dist/components/LineChart/LineChartVerticalMarkers.js.map +1 -0
  81. package/dist/components/LineChart/index.d.ts +1 -1
  82. package/dist/components/Logo/index.js +11 -6
  83. package/dist/components/Logo/index.js.map +1 -1
  84. package/dist/components/MetricChart/MetricChart.d.ts +2 -0
  85. package/dist/components/MetricChart/MetricChart.js +15 -4
  86. package/dist/components/MetricChart/MetricChart.js.map +1 -1
  87. package/dist/components/MetricChart/formatters.js +15 -2
  88. package/dist/components/MetricChart/formatters.js.map +1 -1
  89. package/dist/components/MetricChart/index.d.ts +1 -1
  90. package/dist/components/Pane/Pane.js +2 -2
  91. package/dist/components/SankeyChart/AnimatedSankeyLink.d.ts +17 -0
  92. package/dist/components/SankeyChart/AnimatedSankeyLink.js +44 -0
  93. package/dist/components/SankeyChart/AnimatedSankeyLink.js.map +1 -0
  94. package/dist/components/SankeyChart/AnimatedSankeyNode.d.ts +16 -0
  95. package/dist/components/SankeyChart/AnimatedSankeyNode.js +42 -0
  96. package/dist/components/SankeyChart/AnimatedSankeyNode.js.map +1 -0
  97. package/dist/components/SankeyChart/SankeyChart.d.ts +42 -0
  98. package/dist/components/SankeyChart/SankeyChart.js +185 -0
  99. package/dist/components/SankeyChart/SankeyChart.js.map +1 -0
  100. package/dist/components/SankeyChart/SankeyChart.types.d.ts +90 -0
  101. package/dist/components/SankeyChart/SankeyChart.types.js +0 -0
  102. package/dist/components/SankeyChart/SankeyChart.utils.d.ts +21 -0
  103. package/dist/components/SankeyChart/SankeyChart.utils.js +299 -0
  104. package/dist/components/SankeyChart/SankeyChart.utils.js.map +1 -0
  105. package/dist/components/SankeyChart/SankeyNodeLabel.d.ts +10 -0
  106. package/dist/components/SankeyChart/SankeyNodeLabel.js +30 -0
  107. package/dist/components/SankeyChart/SankeyNodeLabel.js.map +1 -0
  108. package/dist/components/SankeyChart/SankeyNodeLabel.utils.d.ts +9 -0
  109. package/dist/components/SankeyChart/SankeyNodeLabel.utils.js +29 -0
  110. package/dist/components/SankeyChart/SankeyNodeLabel.utils.js.map +1 -0
  111. package/dist/components/SankeyChart/constants.d.ts +22 -0
  112. package/dist/components/SankeyChart/constants.js +27 -0
  113. package/dist/components/SankeyChart/constants.js.map +1 -0
  114. package/dist/components/SankeyChart/index.d.ts +5 -0
  115. package/dist/components/SankeyChart/index.js +4 -0
  116. package/dist/components/Select/Select.js +5 -5
  117. package/dist/components/Select/Select.js.map +1 -1
  118. package/dist/components/Select/SelectPrimitive.d.ts +6 -0
  119. package/dist/components/Select/SelectPrimitive.js +3 -2
  120. package/dist/components/Select/SelectPrimitive.js.map +1 -1
  121. package/dist/components/Slider/Slider.js +10 -3
  122. package/dist/components/Slider/Slider.js.map +1 -1
  123. package/dist/components/SplitViewPane/SplitViewPane.d.ts +2 -1
  124. package/dist/components/SplitViewPane/SplitViewPane.js +113 -219
  125. package/dist/components/SplitViewPane/SplitViewPane.js.map +1 -1
  126. package/dist/components/SplitViewPane/SplitViewPaneHeader.js +2 -2
  127. package/dist/components/SplitViewPane/useShowChildren.d.ts +5 -0
  128. package/dist/components/SplitViewPane/useShowChildren.js +14 -0
  129. package/dist/components/SplitViewPane/useShowChildren.js.map +1 -0
  130. package/dist/components/SplitViewPane/useSplitViewPaneResize.d.ts +21 -0
  131. package/dist/components/SplitViewPane/useSplitViewPaneResize.js +145 -0
  132. package/dist/components/SplitViewPane/useSplitViewPaneResize.js.map +1 -0
  133. package/dist/components/Textarea/Textarea.d.ts +4 -3
  134. package/dist/components/Textarea/Textarea.js +7 -21
  135. package/dist/components/Textarea/Textarea.js.map +1 -1
  136. package/dist/components/ThinkingState/LoadingIndicator.d.ts +1 -0
  137. package/dist/components/ThinkingState/LoadingIndicator.js +1 -1
  138. package/dist/components/ThinkingState/ThinkingState.d.ts +1 -0
  139. package/dist/components/ThinkingState/ThinkingState.js +5 -4
  140. package/dist/components/ThinkingState/ThinkingState.js.map +1 -1
  141. package/dist/components/ThinkingState/index.js +1 -1
  142. package/dist/components/Toast/index.js +33 -28
  143. package/dist/components/Toast/index.js.map +1 -1
  144. package/dist/components/Tooltip/Tooltip.js +2 -2
  145. package/dist/components/Typeahead/Typeahead.js +18 -8
  146. package/dist/components/Typeahead/Typeahead.js.map +1 -1
  147. package/dist/components/Typeahead/Typeahead.types.d.ts +2 -0
  148. package/dist/components/Typeahead/TypeaheadParts.d.ts +3 -1
  149. package/dist/components/Typeahead/TypeaheadParts.js +7 -6
  150. package/dist/components/Typeahead/TypeaheadParts.js.map +1 -1
  151. package/dist/components/Typeahead/TypeaheadView.js +19 -13
  152. package/dist/components/Typeahead/TypeaheadView.js.map +1 -1
  153. package/dist/components/Typeahead/useTypeaheadDomSync.d.ts +1 -1
  154. package/dist/components/Typeahead/useTypeaheadDomSync.js +14 -8
  155. package/dist/components/Typeahead/useTypeaheadDomSync.js.map +1 -1
  156. package/dist/components/Typeahead/useTypeaheadUncontrolledInput.d.ts +2 -1
  157. package/dist/components/Typeahead/useTypeaheadUncontrolledInput.js +10 -9
  158. package/dist/components/Typeahead/useTypeaheadUncontrolledInput.js.map +1 -1
  159. package/dist/components/UnsavedChangesDialog.js +2 -2
  160. package/dist/components/index.d.ts +3 -1
  161. package/dist/components/index.js +7 -5
  162. package/dist/components.css +22 -18
  163. package/dist/hooks/useDebouncedCommit.d.ts +14 -0
  164. package/dist/hooks/useDebouncedCommit.js +35 -0
  165. package/dist/hooks/useDebouncedCommit.js.map +1 -0
  166. package/dist/icons/LongTailPhosphorIcons.js +1 -1
  167. package/dist/icons/PaddedPhosphorIcons.d.ts +1 -0
  168. package/dist/icons/PaddedPhosphorIcons.js +4 -2
  169. package/dist/icons/PaddedPhosphorIcons.js.map +1 -1
  170. package/dist/icons/WeightedPhosphorIcons.d.ts +1 -0
  171. package/dist/icons/WeightedPhosphorIcons.js +3 -1
  172. package/dist/icons/WeightedPhosphorIcons.js.map +1 -1
  173. package/dist/icons/index.js +3 -3
  174. package/dist/index.js +7 -5
  175. package/dist/utilities.css +1 -1
  176. package/dist/utils/chartColors.d.ts +2 -1
  177. package/dist/utils/chartColors.js +2 -1
  178. package/dist/utils/chartColors.js.map +1 -1
  179. package/dist/utils/componentSizes.d.ts +0 -1
  180. package/dist/utils/componentSizes.js.map +1 -1
  181. package/dist/utils/lazy-codemirror-loader.d.ts +0 -2
  182. package/dist/utils/lazy-codemirror-loader.js +1 -3
  183. package/dist/utils/lazy-codemirror-loader.js.map +1 -1
  184. package/docs/DESIGN.md +17 -0
  185. package/docs/STYLES.md +4 -1
  186. package/package.json +21 -8
  187. package/dist/_chunks/LoadingIndicator-DgtU9aqD.js.map +0 -1
@@ -1,12 +1,15 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { Button } from "../Button/Button.js";
2
3
  import zIndices from "../../utils/zIndices.js";
3
4
  import { useZIndex } from "../../utils/useZIndex.js";
4
5
  import { Banner } from "../Banner/Banner.js";
5
6
  import "../Banner/index.js";
6
7
  import { useColorScheme } from "../../hooks/useColorScheme.js";
7
- import { Button } from "../Button/Button.js";
8
8
  import { getLanguageExtension, getSyntaxTheme, useEditorTheme } from "./Code.utils.js";
9
+ import { CODE_LANGUAGES, resolveCodeLanguage } from "./codeLanguages.js";
10
+ import { CodeLanguageSelect } from "./CodeLanguageSelect.js";
9
11
  import { useCodeMirror } from "../../utils/useCodeMirror.js";
12
+ import { CodeToolbar } from "./CodeToolbar.js";
10
13
  import "./constants.js";
11
14
  import { getImageReplacerExtensions } from "./ImageReplacerExtension.js";
12
15
  import { getNonce } from "../../utils/csp-nonce.js";
@@ -14,7 +17,7 @@ import { CopyButton } from "../CopyButton/CopyButton.js";
14
17
  import { ErrorBoundary } from "../ErrorBoundary.js";
15
18
  import { PlainTextEditor } from "../PlainTextEditor/index.js";
16
19
  import { useMemo, useState } from "react";
17
- import { jsx, jsxs } from "react/jsx-runtime";
20
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
18
21
  //#region packages/components/src/components/Code/index.tsx
19
22
  /**
20
23
  * Renders syntax-highlighted code with optional editing and copy support.
@@ -22,14 +25,17 @@ import { jsx, jsxs } from "react/jsx-runtime";
22
25
  * Import directly from `@langchain/macaw-components/Code` so the CodeMirror
23
26
  * dependency is only loaded by surfaces that use it.
24
27
  */
25
- var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, extensions, converterExtensions, height, maxHeight, omitMaxHeight, width, fontSize, onCreateEditor, variant = "full", testId, showCopyButton }) => {
28
+ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, ariaLabel, language, extensions, converterExtensions, height, maxHeight, omitMaxHeight, width, fontSize, onCreateEditor, onUpdate, variant = "full", testId, toolbar, showCopyButton, showFoldGutter = true }) => {
26
29
  const cm = useCodeMirror();
27
30
  const { isDarkMode } = useColorScheme();
28
31
  const copyButtonZIndex = useZIndex(zIndices.floatingBar);
29
32
  const [ignoreWarning, setIgnoreWarning] = useState(false);
30
33
  const lineCount = value?.split("\n").length ?? 0;
31
34
  const imageReplacerExtensions = useMemo(() => cm ? getImageReplacerExtensions(cm) : null, [cm]);
32
- const editorTheme = useEditorTheme(cm, { variant });
35
+ const editorTheme = useEditorTheme(cm, {
36
+ variant,
37
+ showFoldGutter
38
+ });
33
39
  const langExt = useMemo(() => cm ? getLanguageExtension(cm, language) : null, [cm, language]);
34
40
  const syntaxTheme = useMemo(() => cm ? getSyntaxTheme(cm, isDarkMode) : null, [cm, isDarkMode]);
35
41
  const nonce = getNonce();
@@ -49,6 +55,8 @@ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, exten
49
55
  decorationStateField,
50
56
  EditorView.lineWrapping,
51
57
  editorTheme,
58
+ ...language === "plaintext" ? [EditorView.theme({ ".cm-content": { color: "var(--text-primary)" } })] : [],
59
+ ...ariaLabel ? [EditorView.contentAttributes.of({ "aria-label": ariaLabel })] : [],
52
60
  ...readOnly ? [EditorView.editable.of(false)] : [],
53
61
  ...nonce ? [EditorView.cspNonce.of(nonce)] : []
54
62
  ];
@@ -57,6 +65,8 @@ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, exten
57
65
  imageReplacerExtensions,
58
66
  langExt,
59
67
  editorTheme,
68
+ language,
69
+ ariaLabel,
60
70
  extensions,
61
71
  converterExtensions,
62
72
  lineCount,
@@ -64,7 +74,11 @@ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, exten
64
74
  nonce
65
75
  ]);
66
76
  if (value == null) return null;
67
- if (lineCount > 5e3 && !ignoreWarning) return /* @__PURE__ */ jsx(Banner, {
77
+ const showWarning = lineCount > 5e3 && !ignoreWarning;
78
+ const hasToolbar = Boolean(toolbar);
79
+ const CodeMirror = cm?.CodeMirror;
80
+ const editorHeight = hasToolbar && height ? "100%" : height;
81
+ const editor = showWarning ? /* @__PURE__ */ jsx(Banner, {
68
82
  intent: "warning",
69
83
  action: /* @__PURE__ */ jsx(Button, {
70
84
  variant: "underlined",
@@ -74,56 +88,62 @@ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, exten
74
88
  children: "Open anyway"
75
89
  }),
76
90
  children: "This content might be too long to display in the editor."
77
- });
78
- if (!cm || !syntaxTheme) return /* @__PURE__ */ jsx("div", {
79
- "data-testid": testId,
80
- className: cn("group relative text-xs", height && "h-full"),
81
- children: /* @__PURE__ */ jsx(PlainTextEditor, {
91
+ }) : !CodeMirror || !syntaxTheme ? /* @__PURE__ */ jsx(PlainTextEditor, {
92
+ value,
93
+ readOnly: true,
94
+ placeholder,
95
+ className: cn("font-mono text-xs", height && "h-full overflow-auto", maxHeight && !omitMaxHeight && `max-h-[${maxHeight}]`)
96
+ }) : /* @__PURE__ */ jsx(ErrorBoundary, {
97
+ fallback: () => /* @__PURE__ */ jsx("div", { children: "Error showing code" }),
98
+ children: /* @__PURE__ */ jsx(CodeMirror, {
82
99
  value,
83
- readOnly: true,
100
+ readOnly,
101
+ autoFocus,
84
102
  placeholder,
85
- className: cn("font-mono text-xs", height && "h-full overflow-auto", maxHeight && !omitMaxHeight && `max-h-[${maxHeight}]`)
103
+ height: editorHeight,
104
+ maxHeight: omitMaxHeight ? void 0 : maxHeight ?? "50vh",
105
+ width: hasToolbar ? "100%" : width,
106
+ style: {
107
+ fontSize,
108
+ backgroundColor: "var(--bg-surface-level-2)",
109
+ borderRadius: hasToolbar ? 0 : "var(--radius-lg)",
110
+ cursor: readOnly ? "default" : "text",
111
+ ...editorHeight ? { height: editorHeight } : {},
112
+ ...width ? { width: hasToolbar ? "100%" : width } : {}
113
+ },
114
+ extensions: mExtensions,
115
+ onCreateEditor,
116
+ onUpdate,
117
+ onChange: (code) => {
118
+ if (!readOnly) onChange?.(code);
119
+ },
120
+ theme: syntaxTheme,
121
+ basicSetup: {
122
+ foldGutter: showFoldGutter,
123
+ highlightActiveLine: false,
124
+ highlightActiveLineGutter: false,
125
+ defaultKeymap: false,
126
+ ...variant === "plain" && {
127
+ lineNumbers: false,
128
+ highlightSelectionMatches: false
129
+ }
130
+ }
86
131
  })
87
132
  });
88
- const { CodeMirror } = cm;
89
133
  return /* @__PURE__ */ jsxs("div", {
90
134
  "data-testid": testId,
91
- className: cn("group relative text-xs", height && "h-full"),
92
- children: [/* @__PURE__ */ jsx(ErrorBoundary, {
93
- fallback: () => /* @__PURE__ */ jsx("div", { children: "Error showing code" }),
94
- children: /* @__PURE__ */ jsx(CodeMirror, {
95
- value,
96
- readOnly,
97
- autoFocus,
98
- placeholder,
99
- height,
100
- maxHeight: omitMaxHeight ? void 0 : maxHeight ?? "50vh",
101
- width,
102
- style: {
103
- fontSize,
104
- backgroundColor: "var(--bg-surface-level-2)",
105
- borderRadius: "8px",
106
- cursor: readOnly ? "default" : "text",
107
- ...height ? { height } : {},
108
- ...width ? { width } : {}
109
- },
110
- extensions: mExtensions,
111
- onCreateEditor,
112
- onChange: (code) => {
113
- if (!readOnly) onChange?.(code);
114
- },
115
- theme: syntaxTheme,
116
- basicSetup: {
117
- highlightActiveLine: false,
118
- highlightActiveLineGutter: false,
119
- defaultKeymap: false,
120
- ...variant === "plain" && {
121
- lineNumbers: false,
122
- highlightSelectionMatches: false
123
- }
124
- }
125
- })
126
- }), showCopyButton && value && /* @__PURE__ */ jsx("div", {
135
+ className: cn("group relative text-xs", height && !hasToolbar && "h-full", hasToolbar && "flex flex-col overflow-hidden rounded-lg border border-subtle bg-surface-level-2"),
136
+ style: hasToolbar ? {
137
+ width,
138
+ height
139
+ } : void 0,
140
+ children: [hasToolbar ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
141
+ className: "shrink-0",
142
+ children: toolbar
143
+ }), /* @__PURE__ */ jsx("div", {
144
+ className: cn(height && "min-h-0 flex-1 overflow-auto"),
145
+ children: editor
146
+ })] }) : editor, !hasToolbar && !showWarning && CodeMirror && syntaxTheme && showCopyButton && value && /* @__PURE__ */ jsx("div", {
127
147
  onMouseDown: (e) => e.preventDefault(),
128
148
  className: "absolute right-1 top-1 opacity-0 transition-opacity duration-300 group-hover:opacity-100",
129
149
  style: { zIndex: copyButtonZIndex },
@@ -135,6 +155,6 @@ var Code = ({ value, readOnly, onChange, autoFocus, placeholder, language, exten
135
155
  });
136
156
  };
137
157
  //#endregion
138
- export { Code };
158
+ export { CODE_LANGUAGES, Code, CodeLanguageSelect, CodeToolbar, resolveCodeLanguage };
139
159
 
140
160
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Code/index.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\n\nimport type { Extension } from '@codemirror/state';\nimport type { EditorView } from '@codemirror/view';\n\nimport { useColorScheme } from '../../hooks/useColorScheme';\nimport { cn } from '../../utils/cn';\nimport { getNonce } from '../../utils/csp-nonce';\nimport { useCodeMirror } from '../../utils/useCodeMirror';\nimport { useZIndex } from '../../utils/useZIndex';\nimport zIndices from '../../utils/zIndices';\nimport { Banner } from '../Banner';\nimport { Button } from '../Button';\nimport { CopyButton } from '../CopyButton';\nimport { ErrorBoundary } from '../ErrorBoundary';\nimport { PlainTextEditor } from '../PlainTextEditor';\nimport {\n getLanguageExtension,\n getSyntaxTheme,\n useEditorTheme,\n} from './Code.utils';\nimport { MAX_CODE_LENGTH } from './constants';\nimport { getImageReplacerExtensions } from './ImageReplacerExtension';\nimport type { CodeLanguageType } from './types';\n\n/** Props for the syntax-highlighted CodeMirror block. */\nexport interface CodeProps {\n language: CodeLanguageType;\n extensions?: Extension[];\n value: string | undefined;\n onChange?: (code: string) => void;\n readOnly?: boolean;\n autoFocus?: boolean;\n height?: string;\n maxHeight?: string;\n omitMaxHeight?: boolean;\n width?: string;\n fontSize?: string;\n placeholder?: string;\n showCopyButton?: boolean;\n testId?: string;\n variant?: 'plain' | 'full';\n onCreateEditor?: (view: EditorView) => void;\n converterExtensions?: Extension[];\n}\n\n/**\n * Renders syntax-highlighted code with optional editing and copy support.\n *\n * Import directly from `@langchain/macaw-components/Code` so the CodeMirror\n * dependency is only loaded by surfaces that use it.\n */\nexport const Code = ({\n value,\n readOnly,\n onChange,\n autoFocus,\n placeholder,\n language,\n extensions,\n converterExtensions,\n height,\n maxHeight,\n omitMaxHeight,\n width,\n fontSize,\n onCreateEditor,\n variant = 'full',\n testId,\n showCopyButton,\n}: CodeProps) => {\n const cm = useCodeMirror();\n const { isDarkMode } = useColorScheme();\n const copyButtonZIndex = useZIndex(zIndices.floatingBar);\n\n const [ignoreWarning, setIgnoreWarning] = useState(false);\n\n const lineCount = value?.split('\\n').length ?? 0;\n\n // Stable CM-derived values — memoized so StateField/ViewPlugin instances are\n // created once and not recreated on every render (which resets editor state).\n const imageReplacerExtensions = useMemo(\n () => (cm ? getImageReplacerExtensions(cm) : null),\n [cm]\n );\n const editorTheme = useEditorTheme(cm, { variant });\n const langExt = useMemo(\n () => (cm ? getLanguageExtension(cm, language) : null),\n [cm, language]\n );\n const syntaxTheme = useMemo(\n () => (cm ? getSyntaxTheme(cm, isDarkMode) : null),\n [cm, isDarkMode]\n );\n\n const nonce = getNonce();\n\n const mExtensions = useMemo(() => {\n if (!cm || !imageReplacerExtensions || !langExt || !editorTheme) return [];\n const { keymap, defaultKeymap, EditorView } = cm;\n const { decorationStateField, imageReplacerPlugin } =\n imageReplacerExtensions;\n return [\n keymap.of([{ key: 'Mod-Enter', run: () => true }, ...defaultKeymap]),\n langExt.language,\n ...(extensions ?? []),\n // YAML folding blocks rendering for large files, so cap it at 500 lines.\n ...(lineCount <= 500\n ? (converterExtensions ?? langExt.extensions ?? [])\n : []),\n imageReplacerPlugin,\n decorationStateField,\n EditorView.lineWrapping,\n editorTheme,\n ...(readOnly ? [EditorView.editable.of(false)] : []),\n ...(nonce ? [EditorView.cspNonce.of(nonce)] : []),\n ];\n // extensions/converterExtensions are caller-provided arrays. Include them\n // directly so changes propagate.\n }, [\n cm,\n imageReplacerExtensions,\n langExt,\n editorTheme,\n extensions,\n converterExtensions,\n lineCount,\n readOnly,\n nonce,\n ]);\n\n if (value == null) return null;\n\n // Avoid mounting CodeMirror by default when style recomputation could block rendering.\n if (lineCount > MAX_CODE_LENGTH && !ignoreWarning)\n return (\n <Banner\n intent=\"warning\"\n action={\n <Button\n variant=\"underlined\"\n color=\"secondary\"\n size=\"sm\"\n onClick={() => setIgnoreWarning(true)}\n >\n Open anyway\n </Button>\n }\n >\n This content might be too long to display in the editor.\n </Banner>\n );\n\n if (!cm || !syntaxTheme) {\n return (\n <div\n data-testid={testId}\n className={cn('group relative text-xs', height && 'h-full')}\n >\n <PlainTextEditor\n value={value}\n readOnly={true}\n placeholder={placeholder}\n className={cn(\n 'font-mono text-xs',\n height && 'h-full overflow-auto',\n maxHeight && !omitMaxHeight && `max-h-[${maxHeight}]`\n )}\n />\n </div>\n );\n }\n\n const { CodeMirror } = cm;\n\n return (\n <div\n data-testid={testId}\n className={cn('group relative text-xs', height && 'h-full')}\n >\n <ErrorBoundary fallback={() => <div>Error showing code</div>}>\n <CodeMirror\n value={value}\n readOnly={readOnly}\n autoFocus={autoFocus}\n placeholder={placeholder}\n height={height}\n maxHeight={omitMaxHeight ? undefined : (maxHeight ?? '50vh')}\n width={width}\n style={{\n fontSize,\n backgroundColor: 'var(--bg-surface-level-2)',\n borderRadius: '8px',\n cursor: readOnly ? 'default' : 'text',\n ...(height ? { height } : {}),\n ...(width ? { width } : {}),\n }}\n extensions={mExtensions}\n onCreateEditor={onCreateEditor}\n onChange={(code) => {\n if (!readOnly) {\n onChange?.(code);\n }\n }}\n theme={syntaxTheme}\n basicSetup={{\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n defaultKeymap: false,\n ...(variant === 'plain' && {\n lineNumbers: false,\n highlightSelectionMatches: false,\n }),\n }}\n />\n </ErrorBoundary>\n {showCopyButton && value && (\n <div\n onMouseDown={(e) => e.preventDefault()}\n className=\"absolute right-1 top-1 opacity-0 transition-opacity duration-300 group-hover:opacity-100\"\n style={{ zIndex: copyButtonZIndex }}\n >\n <CopyButton copy={value} variant=\"icon\" />\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Code/index.tsx"],"sourcesContent":["import { type ReactNode, useMemo, useState } from 'react';\n\nimport type { Extension } from '@codemirror/state';\nimport type { EditorView, ViewUpdate } from '@codemirror/view';\n\nimport { useColorScheme } from '../../hooks/useColorScheme';\nimport { cn } from '../../utils/cn';\nimport { getNonce } from '../../utils/csp-nonce';\nimport { useCodeMirror } from '../../utils/useCodeMirror';\nimport { useZIndex } from '../../utils/useZIndex';\nimport zIndices from '../../utils/zIndices';\nimport { Banner } from '../Banner';\nimport { Button } from '../Button';\nimport { CopyButton } from '../CopyButton';\nimport { ErrorBoundary } from '../ErrorBoundary';\nimport { PlainTextEditor } from '../PlainTextEditor';\nimport {\n getLanguageExtension,\n getSyntaxTheme,\n useEditorTheme,\n} from './Code.utils';\nimport { MAX_CODE_LENGTH } from './constants';\nimport { getImageReplacerExtensions } from './ImageReplacerExtension';\nimport type { CodeLanguageType } from './types';\n\nexport { CodeLanguageSelect } from './CodeLanguageSelect';\nexport type { CodeLanguageSelectProps } from './CodeLanguageSelect';\nexport { CodeToolbar } from './CodeToolbar';\nexport type { CodeToolbarProps } from './CodeToolbar';\nexport { CODE_LANGUAGES, resolveCodeLanguage } from './codeLanguages';\nexport type { CodeLanguageType } from './types';\n\n/** Props for the syntax-highlighted CodeMirror block. */\nexport interface CodeProps {\n language: CodeLanguageType;\n extensions?: Extension[];\n value: string | undefined;\n onChange?: (code: string) => void;\n readOnly?: boolean;\n autoFocus?: boolean;\n height?: string;\n maxHeight?: string;\n omitMaxHeight?: boolean;\n width?: string;\n fontSize?: string;\n placeholder?: string;\n ariaLabel?: string;\n toolbar?: ReactNode;\n /** Floating copy control when no toolbar is supplied. */\n showCopyButton?: boolean;\n showFoldGutter?: boolean;\n testId?: string;\n variant?: 'plain' | 'full';\n onCreateEditor?: (view: EditorView) => void;\n /** Receives document and selection updates, including programmatic changes. */\n onUpdate?: (update: ViewUpdate) => void;\n converterExtensions?: Extension[];\n}\n\n/**\n * Renders syntax-highlighted code with optional editing and copy support.\n *\n * Import directly from `@langchain/macaw-components/Code` so the CodeMirror\n * dependency is only loaded by surfaces that use it.\n */\nexport const Code = ({\n value,\n readOnly,\n onChange,\n autoFocus,\n placeholder,\n ariaLabel,\n language,\n extensions,\n converterExtensions,\n height,\n maxHeight,\n omitMaxHeight,\n width,\n fontSize,\n onCreateEditor,\n onUpdate,\n variant = 'full',\n testId,\n toolbar,\n showCopyButton,\n showFoldGutter = true,\n}: CodeProps) => {\n const cm = useCodeMirror();\n const { isDarkMode } = useColorScheme();\n const copyButtonZIndex = useZIndex(zIndices.floatingBar);\n\n const [ignoreWarning, setIgnoreWarning] = useState(false);\n\n const lineCount = value?.split('\\n').length ?? 0;\n\n // Stable CM-derived values — memoized so StateField/ViewPlugin instances are\n // created once and not recreated on every render (which resets editor state).\n const imageReplacerExtensions = useMemo(\n () => (cm ? getImageReplacerExtensions(cm) : null),\n [cm]\n );\n const editorTheme = useEditorTheme(cm, { variant, showFoldGutter });\n const langExt = useMemo(\n () => (cm ? getLanguageExtension(cm, language) : null),\n [cm, language]\n );\n const syntaxTheme = useMemo(\n () => (cm ? getSyntaxTheme(cm, isDarkMode) : null),\n [cm, isDarkMode]\n );\n\n const nonce = getNonce();\n\n const mExtensions = useMemo(() => {\n if (!cm || !imageReplacerExtensions || !langExt || !editorTheme) return [];\n const { keymap, defaultKeymap, EditorView } = cm;\n const { decorationStateField, imageReplacerPlugin } =\n imageReplacerExtensions;\n return [\n keymap.of([{ key: 'Mod-Enter', run: () => true }, ...defaultKeymap]),\n langExt.language,\n ...(extensions ?? []),\n // YAML folding blocks rendering for large files, so cap it at 500 lines.\n ...(lineCount <= 500\n ? (converterExtensions ?? langExt.extensions ?? [])\n : []),\n imageReplacerPlugin,\n decorationStateField,\n EditorView.lineWrapping,\n editorTheme,\n // Untagged text otherwise uses the syntax theme's dim default.\n ...(language === 'plaintext'\n ? [\n EditorView.theme({\n '.cm-content': { color: 'var(--text-primary)' },\n }),\n ]\n : []),\n ...(ariaLabel\n ? [EditorView.contentAttributes.of({ 'aria-label': ariaLabel })]\n : []),\n ...(readOnly ? [EditorView.editable.of(false)] : []),\n ...(nonce ? [EditorView.cspNonce.of(nonce)] : []),\n ];\n // extensions/converterExtensions are caller-provided arrays. Include them\n // directly so changes propagate.\n }, [\n cm,\n imageReplacerExtensions,\n langExt,\n editorTheme,\n language,\n ariaLabel,\n extensions,\n converterExtensions,\n lineCount,\n readOnly,\n nonce,\n ]);\n\n if (value == null) return null;\n\n // Avoid mounting CodeMirror by default when style recomputation could block rendering.\n const showWarning = lineCount > MAX_CODE_LENGTH && !ignoreWarning;\n const hasToolbar = Boolean(toolbar);\n const CodeMirror = cm?.CodeMirror;\n const editorHeight = hasToolbar && height ? '100%' : height;\n const editor = showWarning ? (\n <Banner\n intent=\"warning\"\n action={\n <Button\n variant=\"underlined\"\n color=\"secondary\"\n size=\"sm\"\n onClick={() => setIgnoreWarning(true)}\n >\n Open anyway\n </Button>\n }\n >\n This content might be too long to display in the editor.\n </Banner>\n ) : !CodeMirror || !syntaxTheme ? (\n <PlainTextEditor\n value={value}\n readOnly={true}\n placeholder={placeholder}\n className={cn(\n 'font-mono text-xs',\n height && 'h-full overflow-auto',\n maxHeight && !omitMaxHeight && `max-h-[${maxHeight}]`\n )}\n />\n ) : (\n <ErrorBoundary fallback={() => <div>Error showing code</div>}>\n <CodeMirror\n value={value}\n readOnly={readOnly}\n autoFocus={autoFocus}\n placeholder={placeholder}\n height={editorHeight}\n maxHeight={omitMaxHeight ? undefined : (maxHeight ?? '50vh')}\n width={hasToolbar ? '100%' : width}\n style={{\n fontSize,\n backgroundColor: 'var(--bg-surface-level-2)',\n borderRadius: hasToolbar ? 0 : 'var(--radius-lg)',\n cursor: readOnly ? 'default' : 'text',\n ...(editorHeight ? { height: editorHeight } : {}),\n ...(width ? { width: hasToolbar ? '100%' : width } : {}),\n }}\n extensions={mExtensions}\n onCreateEditor={onCreateEditor}\n onUpdate={onUpdate}\n onChange={(code) => {\n if (!readOnly) {\n onChange?.(code);\n }\n }}\n theme={syntaxTheme}\n basicSetup={{\n foldGutter: showFoldGutter,\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n defaultKeymap: false,\n ...(variant === 'plain' && {\n lineNumbers: false,\n highlightSelectionMatches: false,\n }),\n }}\n />\n </ErrorBoundary>\n );\n\n return (\n <div\n data-testid={testId}\n className={cn(\n 'group relative text-xs',\n height && !hasToolbar && 'h-full',\n hasToolbar &&\n 'flex flex-col overflow-hidden rounded-lg border border-subtle bg-surface-level-2'\n )}\n style={hasToolbar ? { width, height } : undefined}\n >\n {hasToolbar ? (\n <>\n <div className=\"shrink-0\">{toolbar}</div>\n <div className={cn(height && 'min-h-0 flex-1 overflow-auto')}>\n {editor}\n </div>\n </>\n ) : (\n editor\n )}\n {!hasToolbar &&\n !showWarning &&\n CodeMirror &&\n syntaxTheme &&\n showCopyButton &&\n value && (\n <div\n onMouseDown={(e) => e.preventDefault()}\n className=\"absolute right-1 top-1 opacity-0 transition-opacity duration-300 group-hover:opacity-100\"\n style={{ zIndex: copyButtonZIndex }}\n >\n <CopyButton copy={value} variant=\"icon\" />\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export type CodeLanguageType = 'yaml' | 'json' | 'javascript' | 'typescript' | 'python' | 'shell' | 'markdown';
1
+ export type CodeLanguageType = 'plaintext' | 'yaml' | 'json' | 'javascript' | 'typescript' | 'python' | 'shell' | 'markdown';
2
2
  export type SyntaxHighlighterRow = {
3
3
  type: string;
4
4
  tagName: string;
@@ -1,5 +1,6 @@
1
1
  import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
2
  import { Command as CommandPrimitive } from 'cmdk';
3
+ import { type OptionRowSize } from '../../utils/componentSizes.js';
3
4
  import type { InputSize, InputVariant } from '../Input/inputStyles.js';
4
5
  export declare const Command: import("react").ForwardRefExoticComponent<Omit<{
5
6
  children?: React.ReactNode;
@@ -63,16 +64,12 @@ export declare const CommandSeparator: import("react").ForwardRefExoticComponent
63
64
  }, "key" | "asChild" | keyof import("react").HTMLAttributes<HTMLDivElement>> & {
64
65
  alwaysRender?: boolean;
65
66
  } & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
66
- export declare const CommandItem: import("react").ForwardRefExoticComponent<Omit<{
67
- children?: React.ReactNode;
68
- } & Omit<Pick<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof import("react").HTMLAttributes<HTMLDivElement>> & {
69
- ref?: React.Ref<HTMLDivElement>;
70
- } & {
71
- asChild?: boolean;
72
- }, "key" | "asChild" | keyof import("react").HTMLAttributes<HTMLDivElement>>, "onSelect" | "disabled" | "value"> & {
73
- disabled?: boolean;
74
- onSelect?: (value: string) => void;
75
- value?: string;
76
- keywords?: string[];
77
- forceMount?: boolean;
78
- } & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
67
+ interface CommandItemProps extends ComponentPropsWithoutRef<typeof CommandPrimitive.Item> {
68
+ /**
69
+ * Controls minimum row height and default label typography.
70
+ * Rich or multiline content grows intrinsically.
71
+ */
72
+ size?: OptionRowSize;
73
+ }
74
+ export declare const CommandItem: import("react").ForwardRefExoticComponent<CommandItemProps & import("react").RefAttributes<HTMLDivElement>>;
75
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { OPTION_ROW_SIZES } from "../../utils/componentSizes.js";
2
3
  import { getInputContainerClasses, getInputElementClasses } from "../Input/inputStyles.js";
3
4
  import { forwardRef } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -66,9 +67,13 @@ var CommandSeparator = forwardRef(({ className, ...props }, ref) => /* @__PURE__
66
67
  ...props
67
68
  }));
68
69
  CommandSeparator.displayName = Command$1.Separator.displayName;
69
- var CommandItem = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Command$1.Item, {
70
+ var COMMAND_ITEM_SIZE_CLASSES = {
71
+ sm: "py-space-1 text-xs leading-4",
72
+ md: "py-space-1 text-sm"
73
+ };
74
+ var CommandItem = forwardRef(({ className, size = "md", ...props }, ref) => /* @__PURE__ */ jsx(Command$1.Item, {
70
75
  ref,
71
- className: cn("relative flex cursor-pointer select-none items-center rounded-md px-space-2 py-1.5 outline-none hover:bg-secondary aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-selected:bg-secondary", className),
76
+ className: cn("relative flex cursor-pointer select-none items-center rounded-sm px-space-2 outline-none hover:bg-secondary aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-selected:bg-secondary", OPTION_ROW_SIZES[size].minHeightClassName, COMMAND_ITEM_SIZE_CLASSES[size], className),
72
77
  ...props
73
78
  }));
74
79
  CommandItem.displayName = Command$1.Item.displayName;
@@ -1 +1 @@
1
- {"version":3,"file":"Command.js","names":[],"sources":["../../../src/components/Command/Command.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ElementRef, ReactNode } from 'react';\nimport { forwardRef } from 'react';\n\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils/cn';\nimport {\n DECORATOR_CLASSES,\n getInputContainerClasses,\n getInputElementClasses,\n} from '../Input/inputStyles';\nimport type { InputSize, InputVariant } from '../Input/inputStyles';\n\nexport const Command = forwardRef<\n ElementRef<typeof CommandPrimitive>,\n ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n 'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover',\n className\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\nexport interface CommandInputProps extends Omit<\n ComponentPropsWithoutRef<typeof CommandPrimitive.Input>,\n 'size'\n> {\n /** Left side decorator (icon or element) */\n leftDecorator?: ReactNode;\n /** Right side decorator (icon or element) */\n rightDecorator?: ReactNode;\n /** Size variant — uses shared Input styling */\n size?: InputSize;\n /** Visual variant — uses shared Input styling */\n variant?: InputVariant;\n}\n\nexport const CommandInput = forwardRef<\n ElementRef<typeof CommandPrimitive.Input>,\n CommandInputProps\n>(\n (\n {\n className,\n leftDecorator,\n rightDecorator,\n size = 'lg',\n variant = 'outlined',\n ...props\n },\n ref\n ) => {\n const containerClasses = getInputContainerClasses({\n size,\n variant,\n disabled: props.disabled,\n className,\n });\n\n const inputClasses = getInputElementClasses({\n size,\n disabled: props.disabled,\n });\n\n return (\n <div className={containerClasses} {...{ 'cmdk-input-wrapper': '' }}>\n {leftDecorator && (\n <div className={DECORATOR_CLASSES}>{leftDecorator}</div>\n )}\n <CommandPrimitive.Input ref={ref} className={inputClasses} {...props} />\n {rightDecorator && (\n <div className={DECORATOR_CLASSES}>{rightDecorator}</div>\n )}\n </div>\n );\n }\n);\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nexport const CommandList = forwardRef<\n ElementRef<typeof CommandPrimitive.List>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}\n {...props}\n />\n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nexport const CommandEmpty = forwardRef<\n ElementRef<typeof CommandPrimitive.Empty>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className=\"py-space-5 text-center\"\n {...props}\n />\n));\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nexport const CommandGroup = forwardRef<\n ElementRef<typeof CommandPrimitive.Group>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n 'overflow-hidden',\n '[&_[cmdk-group-heading]]:px-space-2 [&_[cmdk-group-heading]]:py-space-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:text-tertiary',\n className\n )}\n {...props}\n />\n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nexport const CommandSeparator = forwardRef<\n ElementRef<typeof CommandPrimitive.Separator>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn('bg-border -mx-space-1 h-px', className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nexport const CommandItem = forwardRef<\n ElementRef<typeof CommandPrimitive.Item>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-pointer select-none items-center rounded-md px-space-2 py-1.5 outline-none hover:bg-secondary aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-selected:bg-secondary',\n className\n )}\n {...props}\n />\n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n"],"mappings":";;;;;;AAaA,IAAa,UAAU,YAGpB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,WAAD;CACO;CACL,WAAW,GACT,qEACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AACD,QAAQ,cAAc,UAAiB;AAgBvC,IAAa,eAAe,YAKxB,EACE,WACA,eACA,gBACA,OAAO,MACP,UAAU,YACV,GAAG,SAEL,QACG;CACH,MAAM,mBAAmB,yBAAyB;EAChD;EACA;EACA,UAAU,MAAM;EAChB;CACF,CAAC;CAED,MAAM,eAAe,uBAAuB;EAC1C;EACA,UAAU,MAAM;CAClB,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW;EAAwB,sBAAsB;EAA9D,UAAA;GACG,iBACC,oBAAC,OAAD;IAAK,WAAA;IAA+B,UAAA;GAAmB,CAAA;GAEzD,oBAAC,UAAiB,OAAlB;IAA6B;IAAK,WAAW;IAAc,GAAI;GAAQ,CAAA;GACtE,kBACC,oBAAC,OAAD;IAAK,WAAA;IAA+B,UAAA;GAAoB,CAAA;EAEvD;;AAET,CACF;AAEA,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,cAAc,YAGxB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,MAAlB;CACO;CACL,WAAW,GAAG,mDAAmD,SAAS;CAC1E,GAAI;AACL,CAAA,CACF;AAED,YAAY,cAAc,UAAiB,KAAK;AAEhD,IAAa,eAAe,YAGzB,OAAO,QACR,oBAAC,UAAiB,OAAlB;CACO;CACL,WAAU;CACV,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,eAAe,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,OAAlB;CACO;CACL,WAAW,GACT,mBACA,6NACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,mBAAmB,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,WAAlB;CACO;CACL,WAAW,GAAG,8BAA8B,SAAS;CACrD,GAAI;AACL,CAAA,CACF;AACD,iBAAiB,cAAc,UAAiB,UAAU;AAE1D,IAAa,cAAc,YAGxB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,MAAlB;CACO;CACL,WAAW,GACT,4MACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,YAAY,cAAc,UAAiB,KAAK"}
1
+ {"version":3,"file":"Command.js","names":[],"sources":["../../../src/components/Command/Command.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ElementRef, ReactNode } from 'react';\nimport { forwardRef } from 'react';\n\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils/cn';\nimport {\n OPTION_ROW_SIZES,\n type OptionRowSize,\n} from '../../utils/componentSizes';\nimport {\n DECORATOR_CLASSES,\n getInputContainerClasses,\n getInputElementClasses,\n} from '../Input/inputStyles';\nimport type { InputSize, InputVariant } from '../Input/inputStyles';\n\nexport const Command = forwardRef<\n ElementRef<typeof CommandPrimitive>,\n ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n 'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover',\n className\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\nexport interface CommandInputProps extends Omit<\n ComponentPropsWithoutRef<typeof CommandPrimitive.Input>,\n 'size'\n> {\n /** Left side decorator (icon or element) */\n leftDecorator?: ReactNode;\n /** Right side decorator (icon or element) */\n rightDecorator?: ReactNode;\n /** Size variant — uses shared Input styling */\n size?: InputSize;\n /** Visual variant — uses shared Input styling */\n variant?: InputVariant;\n}\n\nexport const CommandInput = forwardRef<\n ElementRef<typeof CommandPrimitive.Input>,\n CommandInputProps\n>(\n (\n {\n className,\n leftDecorator,\n rightDecorator,\n size = 'lg',\n variant = 'outlined',\n ...props\n },\n ref\n ) => {\n const containerClasses = getInputContainerClasses({\n size,\n variant,\n disabled: props.disabled,\n className,\n });\n\n const inputClasses = getInputElementClasses({\n size,\n disabled: props.disabled,\n });\n\n return (\n <div className={containerClasses} {...{ 'cmdk-input-wrapper': '' }}>\n {leftDecorator && (\n <div className={DECORATOR_CLASSES}>{leftDecorator}</div>\n )}\n <CommandPrimitive.Input ref={ref} className={inputClasses} {...props} />\n {rightDecorator && (\n <div className={DECORATOR_CLASSES}>{rightDecorator}</div>\n )}\n </div>\n );\n }\n);\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nexport const CommandList = forwardRef<\n ElementRef<typeof CommandPrimitive.List>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}\n {...props}\n />\n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nexport const CommandEmpty = forwardRef<\n ElementRef<typeof CommandPrimitive.Empty>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className=\"py-space-5 text-center\"\n {...props}\n />\n));\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nexport const CommandGroup = forwardRef<\n ElementRef<typeof CommandPrimitive.Group>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n 'overflow-hidden',\n '[&_[cmdk-group-heading]]:px-space-2 [&_[cmdk-group-heading]]:py-space-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:text-tertiary',\n className\n )}\n {...props}\n />\n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nexport const CommandSeparator = forwardRef<\n ElementRef<typeof CommandPrimitive.Separator>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn('bg-border -mx-space-1 h-px', className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\ninterface CommandItemProps extends ComponentPropsWithoutRef<\n typeof CommandPrimitive.Item\n> {\n /**\n * Controls minimum row height and default label typography.\n * Rich or multiline content grows intrinsically.\n */\n size?: OptionRowSize;\n}\n\nconst COMMAND_ITEM_SIZE_CLASSES = {\n sm: 'py-space-1 text-xs leading-4',\n md: 'py-space-1 text-sm',\n} satisfies Record<OptionRowSize, string>;\n\nexport const CommandItem = forwardRef<\n ElementRef<typeof CommandPrimitive.Item>,\n CommandItemProps\n>(({ className, size = 'md', ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-pointer select-none items-center rounded-sm px-space-2 outline-none hover:bg-secondary aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-selected:bg-secondary',\n OPTION_ROW_SIZES[size].minHeightClassName,\n COMMAND_ITEM_SIZE_CLASSES[size],\n className\n )}\n {...props}\n />\n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n"],"mappings":";;;;;;;AAiBA,IAAa,UAAU,YAGpB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,WAAD;CACO;CACL,WAAW,GACT,qEACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AACD,QAAQ,cAAc,UAAiB;AAgBvC,IAAa,eAAe,YAKxB,EACE,WACA,eACA,gBACA,OAAO,MACP,UAAU,YACV,GAAG,SAEL,QACG;CACH,MAAM,mBAAmB,yBAAyB;EAChD;EACA;EACA,UAAU,MAAM;EAChB;CACF,CAAC;CAED,MAAM,eAAe,uBAAuB;EAC1C;EACA,UAAU,MAAM;CAClB,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW;EAAwB,sBAAsB;EAA9D,UAAA;GACG,iBACC,oBAAC,OAAD;IAAK,WAAA;IAA+B,UAAA;GAAmB,CAAA;GAEzD,oBAAC,UAAiB,OAAlB;IAA6B;IAAK,WAAW;IAAc,GAAI;GAAQ,CAAA;GACtE,kBACC,oBAAC,OAAD;IAAK,WAAA;IAA+B,UAAA;GAAoB,CAAA;EAEvD;;AAET,CACF;AAEA,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,cAAc,YAGxB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,MAAlB;CACO;CACL,WAAW,GAAG,mDAAmD,SAAS;CAC1E,GAAI;AACL,CAAA,CACF;AAED,YAAY,cAAc,UAAiB,KAAK;AAEhD,IAAa,eAAe,YAGzB,OAAO,QACR,oBAAC,UAAiB,OAAlB;CACO;CACL,WAAU;CACV,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,eAAe,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,OAAlB;CACO;CACL,WAAW,GACT,mBACA,6NACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc,UAAiB,MAAM;AAElD,IAAa,mBAAmB,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,UAAiB,WAAlB;CACO;CACL,WAAW,GAAG,8BAA8B,SAAS;CACrD,GAAI;AACL,CAAA,CACF;AACD,iBAAiB,cAAc,UAAiB,UAAU;AAY1D,IAAM,4BAA4B;CAChC,IAAI;CACJ,IAAI;AACN;AAEA,IAAa,cAAc,YAGxB,EAAE,WAAW,OAAO,MAAM,GAAG,SAAS,QACvC,oBAAC,UAAiB,MAAlB;CACO;CACL,WAAW,GACT,qMACA,iBAAiB,KAAK,CAAC,oBACvB,0BAA0B,OAC1B,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,YAAY,cAAc,UAAiB,KAAK"}
@@ -1,4 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
+ import { type OptionRowSize } from '../../utils/componentSizes.js';
2
3
  import type { InputSize, InputVariant } from '../Input/inputStyles.js';
3
4
  export interface CommandMenuItem {
4
5
  /** Unique value used for selection and filtering */
@@ -41,6 +42,11 @@ interface CommandMenuBaseProps {
41
42
  renderItem?: (item: CommandMenuItem, isSelected: boolean) => ReactNode;
42
43
  /** Size variant for the search input */
43
44
  inputSize?: InputSize;
45
+ /**
46
+ * Controls minimum row height and default label typography.
47
+ * Descriptions and custom content may grow beyond the minimum height.
48
+ */
49
+ itemRowSize?: OptionRowSize;
44
50
  /** Visual variant for the search input */
45
51
  inputVariant?: InputVariant;
46
52
  /** Additional class name for the Command root */
@@ -61,5 +67,5 @@ export type CommandMenuProps = CommandMenuBaseProps & ({
61
67
  /** Grouped items with optional headings */ groups: CommandMenuGroup[];
62
68
  items?: never;
63
69
  });
64
- export declare function CommandMenu({ items, groups, onSelect, value, placeholder, emptyText, hideSearch, showSelectedIndicator, disableFilter, onSearchChange, renderItem, inputSize, inputVariant, className, loading, loadingRows, onEndReached, endReachedThresholdPx, }: CommandMenuProps): import("react").JSX.Element;
70
+ export declare function CommandMenu({ items, groups, onSelect, value, placeholder, emptyText, hideSearch, showSelectedIndicator, disableFilter, onSearchChange, renderItem, inputSize, itemRowSize, inputVariant, className, loading, loadingRows, onEndReached, endReachedThresholdPx, }: CommandMenuProps): import("react").JSX.Element;
65
71
  export {};
@@ -1,31 +1,33 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { OPTION_ROW_SIZES } from "../../utils/componentSizes.js";
2
3
  import { Text } from "../Text/Text.js";
3
4
  import { Tooltip } from "../Tooltip/Tooltip.js";
4
- import { CheckIcon } from "../../icons/PaddedPhosphorIcons.js";
5
5
  import { Icon } from "../Icon/Icon.js";
6
+ import { CheckIcon } from "../../icons/PaddedPhosphorIcons.js";
6
7
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "./Command.js";
7
8
  import { Fragment, useCallback, useEffect, useRef, useState } from "react";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { MagnifyingGlassIcon } from "@phosphor-icons/react/dist/ssr/MagnifyingGlass";
10
11
  //#region packages/components/src/components/Command/CommandMenu.tsx
11
- function TruncatedLabel({ text }) {
12
+ function TruncatedLabel({ text, size }) {
12
13
  const textRef = useRef(null);
13
14
  const [isTruncated, setIsTruncated] = useState(false);
14
15
  useEffect(() => {
15
16
  const el = textRef.current;
16
17
  if (el) setIsTruncated(el.scrollWidth > el.clientWidth);
17
- }, [text]);
18
+ }, [text, size]);
18
19
  return /* @__PURE__ */ jsx(Tooltip, {
19
20
  title: isTruncated ? text : void 0,
20
21
  children: /* @__PURE__ */ jsx(Text, {
21
22
  ref: textRef,
22
23
  as: "span",
23
- className: "truncate",
24
+ variant: size,
25
+ className: cn("truncate tracking-normal", size === "sm" ? "leading-4" : "leading-5"),
24
26
  children: text
25
27
  })
26
28
  });
27
29
  }
28
- function CommandMenu({ items, groups, onSelect, value, placeholder = "Search...", emptyText = "No results found.", hideSearch, showSelectedIndicator = true, disableFilter, onSearchChange, renderItem, inputSize = "sm", inputVariant = "plain", className, loading = false, loadingRows = 5, onEndReached, endReachedThresholdPx = 50 }) {
30
+ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search...", emptyText = "No results found.", hideSearch, showSelectedIndicator = true, disableFilter, onSearchChange, renderItem, inputSize = "sm", itemRowSize = "md", inputVariant = "plain", className, loading = false, loadingRows = 5, onEndReached, endReachedThresholdPx = 50 }) {
29
31
  const handleScroll = useCallback((e) => {
30
32
  if (!onEndReached) return;
31
33
  const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
@@ -39,7 +41,8 @@ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search..."
39
41
  keywords: item.label ? [item.label, ...item.keywords ?? []] : item.keywords,
40
42
  disabled: item.disabled,
41
43
  onSelect: () => onSelect(item.value),
42
- className: "gap-space-2",
44
+ size: itemRowSize,
45
+ className: cn("gap-space-2", hideSearch && "after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] aria-selected:after:border-2 aria-selected:after:border-focus"),
43
46
  children: renderItem ? renderItem(item, isSelected) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
44
47
  showSelectedIndicator && /* @__PURE__ */ jsx(Icon, {
45
48
  icon: CheckIcon,
@@ -48,7 +51,10 @@ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search..."
48
51
  }),
49
52
  /* @__PURE__ */ jsxs("div", {
50
53
  className: "flex min-w-0 flex-1 flex-col",
51
- children: [/* @__PURE__ */ jsx(TruncatedLabel, { text: label }), item.description && /* @__PURE__ */ jsx(Text, {
54
+ children: [/* @__PURE__ */ jsx(TruncatedLabel, {
55
+ text: label,
56
+ size: itemRowSize
57
+ }), item.description && /* @__PURE__ */ jsx(Text, {
52
58
  as: "span",
53
59
  variant: "xs",
54
60
  className: "truncate text-tertiary",
@@ -63,8 +69,9 @@ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search..."
63
69
  }, item.value);
64
70
  });
65
71
  return /* @__PURE__ */ jsxs(Command, {
66
- className: cn("flex flex-col gap-1.5 p-1.5", className),
72
+ className: cn("flex flex-col gap-1.5 p-space-1 outline-none", className),
67
73
  shouldFilter: disableFilter ? false : void 0,
74
+ tabIndex: hideSearch ? 0 : -1,
68
75
  children: [!hideSearch && /* @__PURE__ */ jsx(CommandInput, {
69
76
  placeholder,
70
77
  size: inputSize,
@@ -76,6 +83,7 @@ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search..."
76
83
  }),
77
84
  onValueChange: onSearchChange
78
85
  }), /* @__PURE__ */ jsxs(CommandList, {
86
+ className: "outline-none",
79
87
  onScroll: handleScroll,
80
88
  children: [
81
89
  !loading && /* @__PURE__ */ jsx(CommandEmpty, { children: /* @__PURE__ */ jsx(Text, {
@@ -89,7 +97,7 @@ function CommandMenu({ items, groups, onSelect, value, placeholder = "Search..."
89
97
  })] }, group.heading ?? i)),
90
98
  loading && /* @__PURE__ */ jsx("div", {
91
99
  className: "flex flex-col gap-space-1 px-space-2 py-space-1",
92
- children: Array.from({ length: loadingRows }, (_, i) => /* @__PURE__ */ jsx("div", { className: "h-7 animate-pulse rounded-md bg-tertiary" }, i))
100
+ children: Array.from({ length: loadingRows }, (_, i) => /* @__PURE__ */ jsx("div", { className: cn("animate-pulse rounded-md bg-tertiary", OPTION_ROW_SIZES[itemRowSize].minHeightClassName) }, i))
93
101
  })
94
102
  ]
95
103
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"CommandMenu.js","names":[],"sources":["../../../src/components/Command/CommandMenu.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Fragment, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';\n\nimport { CheckIcon } from '../../icons/PaddedPhosphorIcons';\nimport { cn } from '../../utils/cn';\nimport { Icon } from '../Icon';\nimport type { InputSize, InputVariant } from '../Input/inputStyles';\nimport { Text } from '../Text';\nimport { Tooltip } from '../Tooltip';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from './Command';\n\nexport interface CommandMenuItem {\n /** Unique value used for selection and filtering */\n value: string;\n /** Display label (defaults to value if not provided) */\n label?: string;\n /** Secondary description text displayed below the label */\n description?: string;\n /** Element displayed on the right side of the item (e.g. badge, shortcut) */\n rightDecorator?: ReactNode;\n /** Whether this item is disabled */\n disabled?: boolean;\n /** Extra search terms for filtering */\n keywords?: string[];\n}\n\nexport interface CommandMenuGroup {\n /** Optional heading displayed above the group */\n heading?: string;\n /** Items in this group */\n items: CommandMenuItem[];\n}\n\ninterface CommandMenuBaseProps {\n /** Callback when an item is selected */\n onSelect: (value: string) => void;\n /** The currently selected value. When set, a check icon is shown next to the selected item. */\n value?: string;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no items match the search */\n emptyText?: string;\n /** Hide the search input (default: false, search is visible) */\n hideSearch?: boolean;\n /** Show the leading selected-indicator slot in the default item layout (default: true). Set false for action menus that track no selection so labels sit flush-left. */\n showSelectedIndicator?: boolean;\n /** Disable client-side filtering by cmdk (default: false). Set true for server-side filtering. */\n disableFilter?: boolean;\n /** Callback when the search input value changes. Useful for server-side filtering. */\n onSearchChange?: (query: string) => void;\n /** Custom render function for each item */\n renderItem?: (item: CommandMenuItem, isSelected: boolean) => ReactNode;\n /** Size variant for the search input */\n inputSize?: InputSize;\n /** Visual variant for the search input */\n inputVariant?: InputVariant;\n /** Additional class name for the Command root */\n className?: string;\n /** Whether more items are currently being loaded */\n loading?: boolean;\n /** Number of skeleton rows to show while loading (default: 5) */\n loadingRows?: number;\n /** Callback when the user scrolls near the end of the list. Use for infinite loading. */\n onEndReached?: () => void;\n /** Distance in pixels from the bottom to trigger onEndReached (default: 50) */\n endReachedThresholdPx?: number;\n}\n\nexport type CommandMenuProps = CommandMenuBaseProps &\n (\n | { /** Flat list of items */ items: CommandMenuItem[]; groups?: never }\n | {\n /** Grouped items with optional headings */ groups: CommandMenuGroup[];\n items?: never;\n }\n );\n\nfunction TruncatedLabel({ text }: { text: string }) {\n const textRef = useRef<HTMLElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useEffect(() => {\n const el = textRef.current;\n if (el) {\n setIsTruncated(el.scrollWidth > el.clientWidth);\n }\n }, [text]);\n\n return (\n <Tooltip title={isTruncated ? text : undefined}>\n <Text ref={textRef} as=\"span\" className=\"truncate\">\n {text}\n </Text>\n </Tooltip>\n );\n}\n\nexport function CommandMenu({\n items,\n groups,\n onSelect,\n value,\n placeholder = 'Search...',\n emptyText = 'No results found.',\n hideSearch,\n showSelectedIndicator = true,\n disableFilter,\n onSearchChange,\n renderItem,\n inputSize = 'sm',\n inputVariant = 'plain',\n className,\n loading = false,\n loadingRows = 5,\n onEndReached,\n endReachedThresholdPx = 50,\n}: CommandMenuProps) {\n const handleScroll = useCallback(\n (e: React.UIEvent<HTMLDivElement>) => {\n if (!onEndReached) return;\n const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;\n if (scrollHeight - scrollTop - clientHeight <= endReachedThresholdPx) {\n onEndReached();\n }\n },\n [onEndReached, endReachedThresholdPx]\n );\n\n const renderItems = (menuItems: CommandMenuItem[]) =>\n menuItems.map((item) => {\n const isSelected = item.value === value;\n const label = item.label ?? item.value;\n return (\n <CommandItem\n key={item.value}\n value={item.value}\n keywords={\n item.label ? [item.label, ...(item.keywords ?? [])] : item.keywords\n }\n disabled={item.disabled}\n onSelect={() => onSelect(item.value)}\n className=\"gap-space-2\"\n >\n {renderItem ? (\n renderItem(item, isSelected)\n ) : (\n <>\n {showSelectedIndicator && (\n <Icon\n icon={CheckIcon}\n size=\"md\"\n className={cn(\n 'shrink-0',\n isSelected ? 'opacity-100' : 'opacity-0'\n )}\n />\n )}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <TruncatedLabel text={label} />\n {item.description && (\n <Text\n as=\"span\"\n variant=\"xs\"\n className=\"truncate text-tertiary\"\n >\n {item.description}\n </Text>\n )}\n </div>\n {item.rightDecorator && (\n <div className=\"ml-auto shrink-0\">{item.rightDecorator}</div>\n )}\n </>\n )}\n </CommandItem>\n );\n });\n\n return (\n <Command\n className={cn('flex flex-col gap-1.5 p-1.5', className)}\n shouldFilter={disableFilter ? false : undefined}\n >\n {!hideSearch && (\n <CommandInput\n placeholder={placeholder}\n size={inputSize}\n variant={inputVariant}\n leftDecorator={\n <MagnifyingGlassIcon aria-hidden size={16} weight=\"regular\" />\n }\n onValueChange={onSearchChange}\n />\n )}\n <CommandList onScroll={handleScroll}>\n {!loading && (\n <CommandEmpty>\n <Text variant=\"sm\">{emptyText}</Text>\n </CommandEmpty>\n )}\n {items && renderItems(items)}\n {groups?.map((group, i) => (\n <Fragment key={group.heading ?? i}>\n {i > 0 && <CommandSeparator />}\n <CommandGroup heading={group.heading}>\n {renderItems(group.items)}\n </CommandGroup>\n </Fragment>\n ))}\n {loading && (\n <div className=\"flex flex-col gap-space-1 px-space-2 py-space-1\">\n {Array.from({ length: loadingRows }, (_, i) => (\n <div\n key={i}\n className=\"h-7 animate-pulse rounded-md bg-tertiary\"\n />\n ))}\n </div>\n )}\n </CommandList>\n </Command>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommandMenu.js","names":[],"sources":["../../../src/components/Command/CommandMenu.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Fragment, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';\n\nimport { CheckIcon } from '../../icons/PaddedPhosphorIcons';\nimport { cn } from '../../utils/cn';\nimport {\n OPTION_ROW_SIZES,\n type OptionRowSize,\n} from '../../utils/componentSizes';\nimport { Icon } from '../Icon';\nimport type { InputSize, InputVariant } from '../Input/inputStyles';\nimport { Text } from '../Text';\nimport { Tooltip } from '../Tooltip';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from './Command';\n\nexport interface CommandMenuItem {\n /** Unique value used for selection and filtering */\n value: string;\n /** Display label (defaults to value if not provided) */\n label?: string;\n /** Secondary description text displayed below the label */\n description?: string;\n /** Element displayed on the right side of the item (e.g. badge, shortcut) */\n rightDecorator?: ReactNode;\n /** Whether this item is disabled */\n disabled?: boolean;\n /** Extra search terms for filtering */\n keywords?: string[];\n}\n\nexport interface CommandMenuGroup {\n /** Optional heading displayed above the group */\n heading?: string;\n /** Items in this group */\n items: CommandMenuItem[];\n}\n\ninterface CommandMenuBaseProps {\n /** Callback when an item is selected */\n onSelect: (value: string) => void;\n /** The currently selected value. When set, a check icon is shown next to the selected item. */\n value?: string;\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Text shown when no items match the search */\n emptyText?: string;\n /** Hide the search input (default: false, search is visible) */\n hideSearch?: boolean;\n /** Show the leading selected-indicator slot in the default item layout (default: true). Set false for action menus that track no selection so labels sit flush-left. */\n showSelectedIndicator?: boolean;\n /** Disable client-side filtering by cmdk (default: false). Set true for server-side filtering. */\n disableFilter?: boolean;\n /** Callback when the search input value changes. Useful for server-side filtering. */\n onSearchChange?: (query: string) => void;\n /** Custom render function for each item */\n renderItem?: (item: CommandMenuItem, isSelected: boolean) => ReactNode;\n /** Size variant for the search input */\n inputSize?: InputSize;\n /**\n * Controls minimum row height and default label typography.\n * Descriptions and custom content may grow beyond the minimum height.\n */\n itemRowSize?: OptionRowSize;\n /** Visual variant for the search input */\n inputVariant?: InputVariant;\n /** Additional class name for the Command root */\n className?: string;\n /** Whether more items are currently being loaded */\n loading?: boolean;\n /** Number of skeleton rows to show while loading (default: 5) */\n loadingRows?: number;\n /** Callback when the user scrolls near the end of the list. Use for infinite loading. */\n onEndReached?: () => void;\n /** Distance in pixels from the bottom to trigger onEndReached (default: 50) */\n endReachedThresholdPx?: number;\n}\n\nexport type CommandMenuProps = CommandMenuBaseProps &\n (\n | { /** Flat list of items */ items: CommandMenuItem[]; groups?: never }\n | {\n /** Grouped items with optional headings */ groups: CommandMenuGroup[];\n items?: never;\n }\n );\n\nfunction TruncatedLabel({ text, size }: { text: string; size: OptionRowSize }) {\n const textRef = useRef<HTMLElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useEffect(() => {\n const el = textRef.current;\n if (el) {\n setIsTruncated(el.scrollWidth > el.clientWidth);\n }\n }, [text, size]);\n\n return (\n <Tooltip title={isTruncated ? text : undefined}>\n <Text\n ref={textRef}\n as=\"span\"\n variant={size}\n className={cn(\n 'truncate tracking-normal',\n size === 'sm' ? 'leading-4' : 'leading-5'\n )}\n >\n {text}\n </Text>\n </Tooltip>\n );\n}\n\nexport function CommandMenu({\n items,\n groups,\n onSelect,\n value,\n placeholder = 'Search...',\n emptyText = 'No results found.',\n hideSearch,\n showSelectedIndicator = true,\n disableFilter,\n onSearchChange,\n renderItem,\n inputSize = 'sm',\n itemRowSize = 'md',\n inputVariant = 'plain',\n className,\n loading = false,\n loadingRows = 5,\n onEndReached,\n endReachedThresholdPx = 50,\n}: CommandMenuProps) {\n const handleScroll = useCallback(\n (e: React.UIEvent<HTMLDivElement>) => {\n if (!onEndReached) return;\n const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;\n if (scrollHeight - scrollTop - clientHeight <= endReachedThresholdPx) {\n onEndReached();\n }\n },\n [onEndReached, endReachedThresholdPx]\n );\n\n const renderItems = (menuItems: CommandMenuItem[]) =>\n menuItems.map((item) => {\n const isSelected = item.value === value;\n const label = item.label ?? item.value;\n return (\n <CommandItem\n key={item.value}\n value={item.value}\n keywords={\n item.label ? [item.label, ...(item.keywords ?? [])] : item.keywords\n }\n disabled={item.disabled}\n onSelect={() => onSelect(item.value)}\n size={itemRowSize}\n className={cn(\n 'gap-space-2',\n hideSearch &&\n 'after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] aria-selected:after:border-2 aria-selected:after:border-focus'\n )}\n >\n {renderItem ? (\n renderItem(item, isSelected)\n ) : (\n <>\n {showSelectedIndicator && (\n <Icon\n icon={CheckIcon}\n size=\"md\"\n className={cn(\n 'shrink-0',\n isSelected ? 'opacity-100' : 'opacity-0'\n )}\n />\n )}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <TruncatedLabel text={label} size={itemRowSize} />\n {item.description && (\n <Text\n as=\"span\"\n variant=\"xs\"\n className=\"truncate text-tertiary\"\n >\n {item.description}\n </Text>\n )}\n </div>\n {item.rightDecorator && (\n <div className=\"ml-auto shrink-0\">{item.rightDecorator}</div>\n )}\n </>\n )}\n </CommandItem>\n );\n });\n\n return (\n <Command\n className={cn('flex flex-col gap-1.5 p-space-1 outline-none', className)}\n shouldFilter={disableFilter ? false : undefined}\n tabIndex={hideSearch ? 0 : -1}\n >\n {!hideSearch && (\n <CommandInput\n placeholder={placeholder}\n size={inputSize}\n variant={inputVariant}\n leftDecorator={\n <MagnifyingGlassIcon aria-hidden size={16} weight=\"regular\" />\n }\n onValueChange={onSearchChange}\n />\n )}\n <CommandList className=\"outline-none\" onScroll={handleScroll}>\n {!loading && (\n <CommandEmpty>\n <Text variant=\"sm\">{emptyText}</Text>\n </CommandEmpty>\n )}\n {items && renderItems(items)}\n {groups?.map((group, i) => (\n <Fragment key={group.heading ?? i}>\n {i > 0 && <CommandSeparator />}\n <CommandGroup heading={group.heading}>\n {renderItems(group.items)}\n </CommandGroup>\n </Fragment>\n ))}\n {loading && (\n <div className=\"flex flex-col gap-space-1 px-space-2 py-space-1\">\n {Array.from({ length: loadingRows }, (_, i) => (\n <div\n key={i}\n className={cn(\n 'animate-pulse rounded-md bg-tertiary',\n OPTION_ROW_SIZES[itemRowSize].minHeightClassName\n )}\n />\n ))}\n </div>\n )}\n </CommandList>\n </Command>\n );\n}\n"],"mappings":"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"}
@@ -1,9 +1,15 @@
1
1
  import * as React from 'react';
2
2
  import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
3
+ import { type OptionRowSize } from '../../utils/componentSizes.js';
3
4
  export declare const ContextMenu: React.FC<ContextMenuPrimitive.ContextMenuProps>;
4
5
  export declare const ContextMenuTrigger: React.ForwardRefExoticComponent<ContextMenuPrimitive.ContextMenuTriggerProps & React.RefAttributes<HTMLSpanElement>>;
5
6
  export declare const ContextMenuContent: React.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
6
7
  export declare const ContextMenuItem: React.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
7
8
  inset?: boolean;
9
+ /**
10
+ * Controls minimum row height and default label typography.
11
+ * Rich or multiline content grows intrinsically.
12
+ */
13
+ size?: OptionRowSize;
8
14
  } & React.RefAttributes<HTMLDivElement>>;
9
15
  export declare const ContextMenuSeparator: React.ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { OPTION_ROW_SIZES } from "../../utils/componentSizes.js";
2
3
  import zIndices from "../../utils/zIndices.js";
3
4
  import { useZIndex } from "../../utils/useZIndex.js";
4
5
  import { ZIndexProvider } from "../../utils/ZIndexContext.js";
@@ -25,9 +26,9 @@ var ContextMenuContent = React$1.forwardRef(({ className, children, ...props },
25
26
  }) });
26
27
  });
27
28
  ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
28
- var ContextMenuItem = React$1.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(ContextMenuPrimitive.Item, {
29
+ var ContextMenuItem = React$1.forwardRef(({ className, inset, size = "md", ...props }, ref) => /* @__PURE__ */ jsx(ContextMenuPrimitive.Item, {
29
30
  ref,
30
- className: cn("flex w-full cursor-default select-none items-center rounded-sm px-space-2 py-space-2 text-sm text-primary outline-none transition-colors focus:bg-elevated-hover data-[disabled]:pointer-events-none data-[highlighted]:bg-elevated-hover data-[disabled]:opacity-50", inset ? "pl-space-8" : void 0, className),
31
+ className: cn("flex w-full cursor-default select-none items-center rounded-sm px-space-2 py-space-1 text-primary outline-none transition-colors focus:bg-elevated-hover data-[disabled]:pointer-events-none data-[highlighted]:bg-elevated-hover data-[disabled]:opacity-50", OPTION_ROW_SIZES[size].minHeightClassName, size === "sm" ? "text-xs leading-4" : "text-sm", inset ? "pl-space-8" : void 0, className),
31
32
  ...props
32
33
  }));
33
34
  ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.js","names":[],"sources":["../../../src/components/ContextMenu/ContextMenu.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as ContextMenuPrimitive from '@radix-ui/react-context-menu';\n\nimport { cn } from '../../utils/cn';\nimport { useZIndex } from '../../utils/useZIndex';\nimport { ZIndexProvider } from '../../utils/ZIndexContext';\nimport zIndices from '../../utils/zIndices';\n\nexport const ContextMenu = ContextMenuPrimitive.Root;\n\nexport const ContextMenuTrigger = ContextMenuPrimitive.Trigger;\n\nexport const ContextMenuContent = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>\n>(({ className, children, ...props }, ref) => {\n const zIndex = useZIndex(zIndices.popover);\n\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n ref={ref}\n className={cn(\n 'min-w-[8rem] overflow-hidden rounded-md border border-default bg-elevated p-space-1 text-primary shadow-md',\n className\n )}\n {...props}\n style={{ zIndex, ...props.style }}\n >\n <ZIndexProvider value={zIndex}>{children}</ZIndexProvider>\n </ContextMenuPrimitive.Content>\n </ContextMenuPrimitive.Portal>\n );\n});\nContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;\n\nexport const ContextMenuItem = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <ContextMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'flex w-full cursor-default select-none items-center rounded-sm px-space-2 py-space-2 text-sm text-primary outline-none transition-colors focus:bg-elevated-hover data-[disabled]:pointer-events-none data-[highlighted]:bg-elevated-hover data-[disabled]:opacity-50',\n inset ? 'pl-space-8' : undefined,\n className\n )}\n {...props}\n />\n));\nContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;\n\nexport const ContextMenuSeparator = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <ContextMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-space-1 my-space-1 border-b border-subtle', className)}\n {...props}\n />\n));\nContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;\n"],"mappings":";;;;;;;;AASA,IAAa,cAAc,qBAAqB;AAEhD,IAAa,qBAAqB,qBAAqB;AAEvD,IAAa,qBAAqB,QAAM,YAGrC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,SAAS,UAAU,SAAS,OAAO;CAEzC,OACE,oBAAC,qBAAqB,QAAtB,EAAA,UACE,oBAAC,qBAAqB,SAAtB;EACO;EACL,WAAW,GACT,8GACA,SACF;EACA,GAAI;EACJ,OAAO;GAAE;GAAQ,GAAG,MAAM;EAAM;EAEhC,UAAA,oBAAC,gBAAD;GAAgB,OAAO;GAAS;EAAyB,CAAA;CAC7B,CAAA,EACH,CAAA;AAEjC,CAAC;AACD,mBAAmB,cAAc,qBAAqB,QAAQ;AAE9D,IAAa,kBAAkB,QAAM,YAKlC,EAAE,WAAW,OAAO,GAAG,SAAS,QACjC,oBAAC,qBAAqB,MAAtB;CACO;CACL,WAAW,GACT,wQACA,QAAQ,eAAe,KAAA,GACvB,SACF;CACA,GAAI;AACL,CAAA,CACF;AACD,gBAAgB,cAAc,qBAAqB,KAAK;AAExD,IAAa,uBAAuB,QAAM,YAGvC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,qBAAqB,WAAtB;CACO;CACL,WAAW,GAAG,iDAAiD,SAAS;CACxE,GAAI;AACL,CAAA,CACF;AACD,qBAAqB,cAAc,qBAAqB,UAAU"}
1
+ {"version":3,"file":"ContextMenu.js","names":[],"sources":["../../../src/components/ContextMenu/ContextMenu.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as ContextMenuPrimitive from '@radix-ui/react-context-menu';\n\nimport { cn } from '../../utils/cn';\nimport {\n OPTION_ROW_SIZES,\n type OptionRowSize,\n} from '../../utils/componentSizes';\nimport { useZIndex } from '../../utils/useZIndex';\nimport { ZIndexProvider } from '../../utils/ZIndexContext';\nimport zIndices from '../../utils/zIndices';\n\nexport const ContextMenu = ContextMenuPrimitive.Root;\n\nexport const ContextMenuTrigger = ContextMenuPrimitive.Trigger;\n\nexport const ContextMenuContent = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>\n>(({ className, children, ...props }, ref) => {\n const zIndex = useZIndex(zIndices.popover);\n\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n ref={ref}\n className={cn(\n 'min-w-[8rem] overflow-hidden rounded-md border border-default bg-elevated p-space-1 text-primary shadow-md',\n className\n )}\n {...props}\n style={{ zIndex, ...props.style }}\n >\n <ZIndexProvider value={zIndex}>{children}</ZIndexProvider>\n </ContextMenuPrimitive.Content>\n </ContextMenuPrimitive.Portal>\n );\n});\nContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;\n\nexport const ContextMenuItem = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n /**\n * Controls minimum row height and default label typography.\n * Rich or multiline content grows intrinsically.\n */\n size?: OptionRowSize;\n }\n>(({ className, inset, size = 'md', ...props }, ref) => (\n <ContextMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'flex w-full cursor-default select-none items-center rounded-sm px-space-2 py-space-1 text-primary outline-none transition-colors focus:bg-elevated-hover data-[disabled]:pointer-events-none data-[highlighted]:bg-elevated-hover data-[disabled]:opacity-50',\n OPTION_ROW_SIZES[size].minHeightClassName,\n size === 'sm' ? 'text-xs leading-4' : 'text-sm',\n inset ? 'pl-space-8' : undefined,\n className\n )}\n {...props}\n />\n));\nContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;\n\nexport const ContextMenuSeparator = React.forwardRef<\n React.ElementRef<typeof ContextMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <ContextMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-space-1 my-space-1 border-b border-subtle', className)}\n {...props}\n />\n));\nContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;\n"],"mappings":";;;;;;;;;AAaA,IAAa,cAAc,qBAAqB;AAEhD,IAAa,qBAAqB,qBAAqB;AAEvD,IAAa,qBAAqB,QAAM,YAGrC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,SAAS,UAAU,SAAS,OAAO;CAEzC,OACE,oBAAC,qBAAqB,QAAtB,EAAA,UACE,oBAAC,qBAAqB,SAAtB;EACO;EACL,WAAW,GACT,8GACA,SACF;EACA,GAAI;EACJ,OAAO;GAAE;GAAQ,GAAG,MAAM;EAAM;EAEhC,UAAA,oBAAC,gBAAD;GAAgB,OAAO;GAAS;EAAyB,CAAA;CAC7B,CAAA,EACH,CAAA;AAEjC,CAAC;AACD,mBAAmB,cAAc,qBAAqB,QAAQ;AAE9D,IAAa,kBAAkB,QAAM,YAUlC,EAAE,WAAW,OAAO,OAAO,MAAM,GAAG,SAAS,QAC9C,oBAAC,qBAAqB,MAAtB;CACO;CACL,WAAW,GACT,gQACA,iBAAiB,KAAK,CAAC,oBACvB,SAAS,OAAO,sBAAsB,WACtC,QAAQ,eAAe,KAAA,GACvB,SACF;CACA,GAAI;AACL,CAAA,CACF;AACD,gBAAgB,cAAc,qBAAqB,KAAK;AAExD,IAAa,uBAAuB,QAAM,YAGvC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,qBAAqB,WAAtB;CACO;CACL,WAAW,GAAG,iDAAiD,SAAS;CACxE,GAAI;AACL,CAAA,CACF;AACD,qBAAqB,cAAc,qBAAqB,UAAU"}
@@ -1,7 +1,7 @@
1
1
  import { Text } from "../Text/Text.js";
2
- import { CheckIcon } from "../../icons/PaddedPhosphorIcons.js";
3
- import { IconButton } from "../IconButton/IconButton.js";
4
2
  import { Button } from "../Button/Button.js";
3
+ import { IconButton } from "../IconButton/IconButton.js";
4
+ import { CheckIcon } from "../../icons/PaddedPhosphorIcons.js";
5
5
  import { useCopy } from "./useCopy.js";
6
6
  import { useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,11 +1,11 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { Text } from "../Text/Text.js";
2
3
  import zIndices from "../../utils/zIndices.js";
3
4
  import { useZIndex } from "../../utils/useZIndex.js";
4
5
  import { ZIndexProvider } from "../../utils/ZIndexContext.js";
5
- import { Text } from "../Text/Text.js";
6
- import { XIcon } from "../../icons/PaddedPhosphorIcons.js";
7
6
  import { Icon } from "../Icon/Icon.js";
8
7
  import { IconButton } from "../IconButton/IconButton.js";
8
+ import { XIcon } from "../../icons/PaddedPhosphorIcons.js";
9
9
  import { mergeRefs } from "../../utils/merge-refs.js";
10
10
  import { createContext, forwardRef, useContext, useState } from "react";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";