@dust-tt/sparkle 0.3.5 → 0.3.7

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 (95) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/esm/components/ConversationMessage.d.ts.map +1 -1
  3. package/dist/esm/components/ConversationMessage.js +2 -2
  4. package/dist/esm/components/ConversationMessage.js.map +1 -1
  5. package/dist/esm/components/ScrollArea.d.ts +1 -1
  6. package/dist/esm/components/ScrollArea.d.ts.map +1 -1
  7. package/dist/esm/components/markdown/Markdown.js +1 -1
  8. package/dist/esm/components/markdown/Markdown.js.map +1 -1
  9. package/dist/esm/icons/actions/Frame.d.ts +5 -0
  10. package/dist/esm/icons/actions/Frame.d.ts.map +1 -0
  11. package/dist/esm/icons/actions/Frame.js +6 -0
  12. package/dist/esm/icons/actions/Frame.js.map +1 -0
  13. package/dist/esm/icons/actions/index.d.ts +1 -0
  14. package/dist/esm/icons/actions/index.d.ts.map +1 -1
  15. package/dist/esm/icons/actions/index.js +1 -0
  16. package/dist/esm/icons/actions/index.js.map +1 -1
  17. package/dist/esm/icons/src/actions/frame.svg +3 -0
  18. package/dist/esm/stories/AnchoredPopover.stories.d.ts +1 -2
  19. package/dist/esm/stories/AnchoredPopover.stories.d.ts.map +1 -1
  20. package/dist/esm/stories/AnchoredPopover.stories.js +36 -48
  21. package/dist/esm/stories/AnchoredPopover.stories.js.map +1 -1
  22. package/dist/esm/stories/Avatar.stories.d.ts +64 -5
  23. package/dist/esm/stories/Avatar.stories.d.ts.map +1 -1
  24. package/dist/esm/stories/Avatar.stories.js +407 -331
  25. package/dist/esm/stories/Avatar.stories.js.map +1 -1
  26. package/dist/esm/stories/Button.stories.d.ts +1 -0
  27. package/dist/esm/stories/Button.stories.d.ts.map +1 -1
  28. package/dist/esm/stories/Button.stories.js +1 -0
  29. package/dist/esm/stories/Button.stories.js.map +1 -1
  30. package/dist/esm/stories/Card.stories.d.ts +39 -3
  31. package/dist/esm/stories/Card.stories.d.ts.map +1 -1
  32. package/dist/esm/stories/Card.stories.js +92 -22
  33. package/dist/esm/stories/Card.stories.js.map +1 -1
  34. package/dist/esm/stories/Chip.stories.d.ts +4 -3
  35. package/dist/esm/stories/Chip.stories.d.ts.map +1 -1
  36. package/dist/esm/stories/Chip.stories.js +37 -30
  37. package/dist/esm/stories/Chip.stories.js.map +1 -1
  38. package/dist/esm/stories/Dropdown.stories.d.ts +13 -4
  39. package/dist/esm/stories/Dropdown.stories.d.ts.map +1 -1
  40. package/dist/esm/stories/Dropdown.stories.js +418 -411
  41. package/dist/esm/stories/Dropdown.stories.js.map +1 -1
  42. package/dist/esm/stories/Icon.stories.d.ts +1 -0
  43. package/dist/esm/stories/Icon.stories.d.ts.map +1 -1
  44. package/dist/esm/stories/Icon.stories.js +1 -0
  45. package/dist/esm/stories/Icon.stories.js.map +1 -1
  46. package/dist/esm/stories/IconSet.stories.d.ts +7 -5
  47. package/dist/esm/stories/IconSet.stories.d.ts.map +1 -1
  48. package/dist/esm/stories/IconSet.stories.js +21 -15
  49. package/dist/esm/stories/IconSet.stories.js.map +1 -1
  50. package/dist/esm/stories/Input.stories.d.ts +46 -1
  51. package/dist/esm/stories/Input.stories.d.ts.map +1 -1
  52. package/dist/esm/stories/Input.stories.js +94 -16
  53. package/dist/esm/stories/Input.stories.js.map +1 -1
  54. package/dist/esm/stories/Logo.stories.d.ts +6 -4
  55. package/dist/esm/stories/Logo.stories.d.ts.map +1 -1
  56. package/dist/esm/stories/Logo.stories.js +41 -37
  57. package/dist/esm/stories/Logo.stories.js.map +1 -1
  58. package/dist/esm/stories/Markdown.stories.d.ts +24 -2
  59. package/dist/esm/stories/Markdown.stories.d.ts.map +1 -1
  60. package/dist/esm/stories/Markdown.stories.js +1 -0
  61. package/dist/esm/stories/Markdown.stories.js.map +1 -1
  62. package/dist/esm/stories/ScrollArea.stories.d.ts +12 -5
  63. package/dist/esm/stories/ScrollArea.stories.d.ts.map +1 -1
  64. package/dist/esm/stories/ScrollArea.stories.js +7 -3
  65. package/dist/esm/stories/ScrollArea.stories.js.map +1 -1
  66. package/dist/esm/stories/Spinner.stories.d.ts +22 -1
  67. package/dist/esm/stories/Spinner.stories.d.ts.map +1 -1
  68. package/dist/esm/stories/Spinner.stories.js +91 -50
  69. package/dist/esm/stories/Spinner.stories.js.map +1 -1
  70. package/dist/esm/stories/Tabs.stories.d.ts +6 -2
  71. package/dist/esm/stories/Tabs.stories.d.ts.map +1 -1
  72. package/dist/esm/stories/Tabs.stories.js +10 -8
  73. package/dist/esm/stories/Tabs.stories.js.map +1 -1
  74. package/dist/sparkle.css +4 -19
  75. package/package.json +1 -1
  76. package/src/components/ConversationMessage.tsx +2 -9
  77. package/src/components/ScrollArea.tsx +1 -1
  78. package/src/components/markdown/Markdown.tsx +1 -1
  79. package/src/icons/actions/Frame.tsx +18 -0
  80. package/src/icons/actions/index.ts +1 -0
  81. package/src/icons/src/actions/frame.svg +3 -0
  82. package/src/stories/AnchoredPopover.stories.tsx +77 -91
  83. package/src/stories/Avatar.stories.tsx +558 -478
  84. package/src/stories/Button.stories.tsx +1 -0
  85. package/src/stories/Card.stories.tsx +146 -70
  86. package/src/stories/Chip.stories.tsx +108 -101
  87. package/src/stories/Dropdown.stories.tsx +725 -717
  88. package/src/stories/Icon.stories.tsx +1 -0
  89. package/src/stories/IconSet.stories.tsx +61 -52
  90. package/src/stories/Input.stories.tsx +168 -79
  91. package/src/stories/Logo.stories.tsx +76 -69
  92. package/src/stories/Markdown.stories.tsx +3 -2
  93. package/src/stories/ScrollArea.stories.tsx +10 -6
  94. package/src/stories/Spinner.stories.tsx +134 -87
  95. package/src/stories/Tabs.stories.tsx +13 -10
@@ -1,7 +1,6 @@
1
1
  import { DropdownMenuCheckboxItemProps } from "@radix-ui/react-dropdown-menu";
2
- import type { Meta } from "@storybook/react";
3
- import React from "react";
4
- import { useState } from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import React, { useState } from "react";
5
4
 
6
5
  import { Spinner } from "@sparkle/components";
7
6
  import {
@@ -48,6 +47,7 @@ import {
48
47
  Avatar,
49
48
  Button,
50
49
  ChatBubbleBottomCenterPlusIcon,
50
+ Chip,
51
51
  CloudArrowDownIcon,
52
52
  Cog6ToothIcon,
53
53
  DocumentIcon,
@@ -66,774 +66,782 @@ import {
66
66
  UserGroupIcon,
67
67
  UserIcon,
68
68
  } from "../index_with_tw_base";
69
- import { Chip } from "../index_with_tw_base";
70
69
 
71
70
  const meta = {
72
71
  title: "Primitives/Dropdown",
73
72
  component: DropdownMenu,
73
+ tags: ["autodocs"],
74
74
  } satisfies Meta<typeof DropdownMenu>;
75
75
 
76
76
  export default meta;
77
-
78
- export const DropdownExamples = () => (
79
- <div className="s-flex s-h-80 s-w-full s-flex-col s-items-center s-justify-center s-gap-4 s-text-foreground dark:s-text-foreground-night">
80
- <div>{SimpleDropdownDemo()}</div>
81
- <div>{ComplexDropdownDemo()}</div>
82
- <div>{DropdownMenuCheckboxes()}</div>
83
- <div>{DropdownMenuRadioGroupDemo()}</div>
84
- <div>{ModelsDropdownDemo()}</div>
85
- <div>{ModelsDropdownRadioGroupDemo()}</div>
86
- <div>{StaticItemDropdownDemo()}</div>
87
- </div>
88
- );
89
-
90
- export const PickerExamples = () => (
91
- <div className="s-flex s-h-80 s-w-full s-flex-col s-items-center s-justify-center s-gap-4 s-text-foreground dark:s-text-foreground-night">
92
- <div>{AttachFileDemo()}</div>
93
- </div>
94
- );
95
-
96
- export const SearchDropdownMenuExamples = () => {
97
- const [searchInputValue, setSearchInputValue] = React.useState("");
98
-
99
- const items = ["Profile", "Billing", "Team", "Subscription"];
100
-
101
- const filteredItems = items.filter((item) =>
102
- item.toLowerCase().includes(searchInputValue.toLowerCase())
103
- );
104
-
105
- return (
106
- <div className="s-flex s-h-80 s-w-full s-flex-col s-items-center s-justify-center s-gap-4 s-text-foreground dark:s-text-foreground-night">
107
- <div>
108
- <SearchDropdownMenu
109
- searchInputValue={searchInputValue}
110
- setSearchInputValue={setSearchInputValue}
111
- >
112
- {filteredItems.map((item) => (
113
- <DropdownMenuItem
114
- key={item}
115
- label={item}
116
- onClick={() => {
117
- console.log(item);
118
- }}
119
- />
120
- ))}
121
- </SearchDropdownMenu>
122
- </div>
123
- </div>
124
- );
77
+ type Story = StoryObj<typeof meta>;
78
+
79
+ export const SimpleDropdown: Story = {
80
+ render: () => {
81
+ return (
82
+ <DropdownMenu>
83
+ <DropdownMenuTrigger>Open Simple Dropdown</DropdownMenuTrigger>
84
+ <DropdownMenuContent className="s-max-w-[300px]">
85
+ <DropdownMenuLabel label="My Account" />
86
+ <DropdownMenuItem
87
+ icon={() => (
88
+ <Avatar
89
+ size="xs"
90
+ visual="https://dust.tt/static/droidavatar/Droid_Lime_3.jpg"
91
+ />
92
+ )}
93
+ label="@hello"
94
+ onClick={() => {
95
+ console.log("hello");
96
+ }}
97
+ description="Anthropic's latest Claude 3.5 Sonnet model (200k context). Anthropic's latest Claude 3.5 Sonnet model (200k context). Anthropic's latest Claude 3.5 Sonnet model (200k context)."
98
+ />
99
+ <DropdownMenuItem
100
+ truncateText
101
+ icon={() => (
102
+ <Avatar
103
+ size="xs"
104
+ visual="https://dust.tt/static/droidavatar/Droid_Pink_3.jpg"
105
+ />
106
+ )}
107
+ label="@helloWorld"
108
+ onClick={() => {
109
+ console.log("hello");
110
+ }}
111
+ description="Anthropic's latest Claude 3.5 Sonnet model (200k context)."
112
+ />
113
+ <DropdownMenuItem label="Profile" />
114
+ <DropdownMenuItem label="Billing" />
115
+ <DropdownMenuItem label="Team" />
116
+ <DropdownMenuItem label="Subscription" />
117
+ </DropdownMenuContent>
118
+ </DropdownMenu>
119
+ );
120
+ },
125
121
  };
126
122
 
127
- function SimpleDropdownDemo() {
128
- return (
129
- <DropdownMenu>
130
- <DropdownMenuTrigger>Open Simple Dropdown</DropdownMenuTrigger>
131
- <DropdownMenuContent className="s-max-w-[300px]">
132
- <DropdownMenuLabel label="My Account" />
133
- <DropdownMenuItem
134
- icon={() => (
135
- <Avatar
136
- size="xs"
137
- visual="https://dust.tt/static/droidavatar/Droid_Lime_3.jpg"
138
- />
139
- )}
140
- label="@hello"
141
- onClick={() => {
142
- console.log("hello");
143
- }}
144
- description="Anthropic's latest Claude 3.5 Sonnet model (200k context). Anthropic's latest Claude 3.5 Sonnet model (200k context). Anthropic's latest Claude 3.5 Sonnet model (200k context)."
145
- />
146
- <DropdownMenuItem
147
- truncateText
148
- icon={() => (
149
- <Avatar
150
- size="xs"
151
- visual="https://dust.tt/static/droidavatar/Droid_Pink_3.jpg"
123
+ export const ComplexDropdown: Story = {
124
+ render: () => {
125
+ return (
126
+ <DropdownMenu>
127
+ <DropdownMenuTrigger>Open Complex</DropdownMenuTrigger>
128
+ <DropdownMenuContent className="s-w-56">
129
+ <DropdownMenuLabel label="My Account" />
130
+ <DropdownMenuGroup>
131
+ <DropdownMenuItem
132
+ icon={UserIcon}
133
+ label="Profile"
134
+ endComponent={
135
+ <Button
136
+ size="mini"
137
+ icon={ArrowUpOnSquareIcon}
138
+ variant="ghost"
139
+ />
140
+ }
152
141
  />
153
- )}
154
- label="@helloWorld"
155
- onClick={() => {
156
- console.log("hello");
157
- }}
158
- description="Anthropic's latest Claude 3.5 Sonnet model (200k context)."
159
- />
160
- <DropdownMenuItem label="Profile" />
161
- <DropdownMenuItem label="Billing" />
162
- <DropdownMenuItem label="Team" />
163
- <DropdownMenuItem label="Subscription" />
164
- </DropdownMenuContent>
165
- </DropdownMenu>
166
- );
167
- }
168
-
169
- function ComplexDropdownDemo() {
170
- return (
171
- <DropdownMenu>
172
- <DropdownMenuTrigger>Open Complex</DropdownMenuTrigger>
173
- <DropdownMenuContent className="s-w-56">
174
- <DropdownMenuLabel label="My Account" />
175
- <DropdownMenuGroup>
142
+ <DropdownMenuItem icon={ArrowDownCircleIcon} label="Billing" />
143
+ <DropdownMenuItem icon={Cog6ToothIcon} label="Settings" />
144
+ <DropdownMenuItem icon={UserIcon} label="Keyboard shortcuts" />
145
+ </DropdownMenuGroup>
146
+ <DropdownMenuSeparator />
147
+ <DropdownMenuGroup>
148
+ <DropdownMenuLabel label="Team" />
149
+ <DropdownMenuItem icon={UserIcon} label="Members" />
150
+ <DropdownMenuSub>
151
+ <DropdownMenuSubTrigger icon={UserIcon} label="Invite users" />
152
+ <DropdownMenuPortal>
153
+ <DropdownMenuSubContent>
154
+ <DropdownMenuItem icon={MagicIcon} label="Email" />
155
+ <DropdownMenuItem
156
+ icon={ChatBubbleBottomCenterPlusIcon}
157
+ label="Message"
158
+ />
159
+ <DropdownMenuSeparator />
160
+ <DropdownMenuItem icon={UserIcon} label="More..." />
161
+ <DropdownMenuItem icon={UserIcon} label="More.." />
162
+ <DropdownMenuItem icon={UserIcon} label="More..." />
163
+ <DropdownMenuItem icon={UserIcon} label="More.." />
164
+ <DropdownMenuItem icon={UserIcon} label="More" />
165
+ <DropdownMenuItem icon={UserIcon} label="More....." />
166
+ <DropdownMenuItem icon={UserIcon} label="More.." />
167
+ <DropdownMenuItem icon={UserIcon} label="More" />
168
+ <DropdownMenuItem icon={UserIcon} label="More...." />
169
+ </DropdownMenuSubContent>
170
+ </DropdownMenuPortal>
171
+ </DropdownMenuSub>
172
+ <DropdownMenuItem icon={UserGroupIcon} label="New Team" />
173
+ </DropdownMenuGroup>
174
+ <DropdownMenuSeparator />
175
+ <DropdownMenuItem icon={GithubLogo} label="GitHub" />
176
+ <DropdownMenuItem icon={UserIcon} label="Support" />
177
+ <DropdownMenuItem icon={CloudArrowDownIcon} label="API" disabled />
178
+ <DropdownMenuSeparator />
176
179
  <DropdownMenuItem
177
- icon={UserIcon}
178
- label="Profile"
179
- endComponent={
180
- <Button size="mini" icon={ArrowUpOnSquareIcon} variant="ghost" />
181
- }
180
+ icon={LogoutIcon}
181
+ label="Log out"
182
+ variant="warning"
183
+ href="/api/auth/logout"
182
184
  />
183
- <DropdownMenuItem icon={ArrowDownCircleIcon} label="Billing" />
184
- <DropdownMenuItem icon={Cog6ToothIcon} label="Settings" />
185
- <DropdownMenuItem icon={UserIcon} label="Keyboard shortcuts" />
186
- </DropdownMenuGroup>
187
- <DropdownMenuSeparator />
188
- <DropdownMenuGroup>
189
- <DropdownMenuLabel label="Team" />
190
- <DropdownMenuItem icon={UserIcon} label="Members" />
191
- <DropdownMenuSub>
192
- <DropdownMenuSubTrigger icon={UserIcon} label="Invite users" />
193
- <DropdownMenuPortal>
194
- <DropdownMenuSubContent>
195
- <DropdownMenuItem icon={MagicIcon} label="Email" />
196
- <DropdownMenuItem
197
- icon={ChatBubbleBottomCenterPlusIcon}
198
- label="Message"
199
- />
200
- <DropdownMenuSeparator />
201
- <DropdownMenuItem icon={UserIcon} label="More..." />
202
- <DropdownMenuItem icon={UserIcon} label="More.." />
203
- <DropdownMenuItem icon={UserIcon} label="More..." />
204
- <DropdownMenuItem icon={UserIcon} label="More.." />
205
- <DropdownMenuItem icon={UserIcon} label="More" />
206
- <DropdownMenuItem icon={UserIcon} label="More....." />
207
- <DropdownMenuItem icon={UserIcon} label="More.." />
208
- <DropdownMenuItem icon={UserIcon} label="More" />
209
- <DropdownMenuItem icon={UserIcon} label="More...." />
210
- </DropdownMenuSubContent>
211
- </DropdownMenuPortal>
212
- </DropdownMenuSub>
213
- <DropdownMenuItem icon={UserGroupIcon} label="New Team" />
214
- </DropdownMenuGroup>
215
- <DropdownMenuSeparator />
216
- <DropdownMenuItem icon={GithubLogo} label="GitHub" />
217
- <DropdownMenuItem icon={UserIcon} label="Support" />
218
- <DropdownMenuItem icon={CloudArrowDownIcon} label="API" disabled />
219
- <DropdownMenuSeparator />
220
- <DropdownMenuItem
221
- icon={LogoutIcon}
222
- label="Log out"
223
- variant="warning"
224
- href="/api/auth/logout"
225
- />
226
- </DropdownMenuContent>
227
- </DropdownMenu>
228
- );
229
- }
185
+ </DropdownMenuContent>
186
+ </DropdownMenu>
187
+ );
188
+ },
189
+ };
230
190
 
231
191
  type Checked = DropdownMenuCheckboxItemProps["checked"];
232
192
 
233
- function DropdownMenuCheckboxes() {
234
- const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true);
235
- const [showActivityBar, setShowActivityBar] = React.useState<Checked>(false);
236
- const [showPanel, setShowPanel] = React.useState<Checked>(false);
237
-
238
- return (
239
- <DropdownMenu>
240
- <DropdownMenuTrigger>Open Checkbox</DropdownMenuTrigger>
241
- <DropdownMenuContent className="s-w-72">
242
- <DropdownMenuLabel label="Interface Settings" />
243
- <DropdownMenuSeparator />
244
- <DropdownMenuCheckboxItem
245
- checked={showStatusBar}
246
- onCheckedChange={setShowStatusBar}
247
- label="Status Bar"
248
- description="Show application status and progress indicators"
249
- truncateText
250
- />
251
- <DropdownMenuCheckboxItem
252
- checked={showActivityBar}
253
- onCheckedChange={setShowActivityBar}
254
- label="Activity Bar"
255
- description="Display sidebar with quick access to tools"
256
- truncateText
257
- disabled
258
- />
259
- <DropdownMenuCheckboxItem
260
- checked={showPanel}
261
- onCheckedChange={setShowPanel}
262
- label="Panel"
263
- description="Bottom panel for terminal and debug output"
264
- truncateText
265
- />
266
- </DropdownMenuContent>
267
- </DropdownMenu>
268
- );
269
- }
270
-
271
- function DropdownMenuRadioGroupDemo() {
272
- const [position, setPosition] = React.useState("bottom");
273
-
274
- return (
275
- <DropdownMenu>
276
- <DropdownMenuTrigger>Open Radio Group</DropdownMenuTrigger>
277
- <DropdownMenuContent className="s-w-56">
278
- <DropdownMenuLabel label="Panel Position" />
279
- <DropdownMenuSeparator />
280
- <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
281
- <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
282
- <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
283
- <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
284
- </DropdownMenuRadioGroup>
285
- </DropdownMenuContent>
286
- </DropdownMenu>
287
- );
288
- }
289
-
290
- function ModelsDropdownDemo() {
291
- const [selectedModel, setSelectedModel] = React.useState<string>("GPT4-o");
292
- const bestPerformingModels = [
293
- {
294
- name: "GPT4-o",
295
- description: "OpenAI's most advanced model.",
296
- icon: OpenaiLogo,
297
- },
298
- {
299
- name: "Claude 3.5 Sonnet",
300
- description: "Anthropic's latest Claude 3.5 Sonnet model (200k context).",
301
- icon: AnthropicLogo,
302
- },
303
- {
304
- name: "Mistral Large",
305
- description: "Mistral's `large 2` model (128k context).",
306
- icon: MistralLogo,
307
- },
308
- ];
309
-
310
- return (
311
- <DropdownMenu>
312
- <DropdownMenuTrigger asChild>
313
- <Button
314
- label={selectedModel}
315
- variant="outline"
316
- size="sm"
317
- tooltip="Test"
318
- />
319
- </DropdownMenuTrigger>
320
- <DropdownMenuContent>
321
- <DropdownMenuLabel label="Best performing models" />
322
- {bestPerformingModels.map((modelConfig) => (
323
- <DropdownMenuItem
324
- key={modelConfig.name}
325
- label={modelConfig.name}
326
- onClick={() => setSelectedModel(modelConfig.name)}
327
- description={modelConfig.description}
328
- icon={modelConfig.icon}
193
+ export const WithCheckboxes: Story = {
194
+ render: () => {
195
+ const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true);
196
+ const [showActivityBar, setShowActivityBar] =
197
+ React.useState<Checked>(false);
198
+ const [showPanel, setShowPanel] = React.useState<Checked>(false);
199
+
200
+ return (
201
+ <DropdownMenu>
202
+ <DropdownMenuTrigger>Open Checkbox</DropdownMenuTrigger>
203
+ <DropdownMenuContent className="s-w-72">
204
+ <DropdownMenuLabel label="Interface Settings" />
205
+ <DropdownMenuSeparator />
206
+ <DropdownMenuCheckboxItem
207
+ checked={showStatusBar}
208
+ onCheckedChange={setShowStatusBar}
209
+ label="Status Bar"
210
+ description="Show application status and progress indicators"
211
+ truncateText
329
212
  />
330
- ))}
331
- </DropdownMenuContent>
332
- </DropdownMenu>
333
- );
334
- }
213
+ <DropdownMenuCheckboxItem
214
+ checked={showActivityBar}
215
+ onCheckedChange={setShowActivityBar}
216
+ label="Activity Bar"
217
+ description="Display sidebar with quick access to tools"
218
+ truncateText
219
+ disabled
220
+ />
221
+ <DropdownMenuCheckboxItem
222
+ checked={showPanel}
223
+ onCheckedChange={setShowPanel}
224
+ label="Panel"
225
+ description="Bottom panel for terminal and debug output"
226
+ truncateText
227
+ />
228
+ </DropdownMenuContent>
229
+ </DropdownMenu>
230
+ );
231
+ },
232
+ };
335
233
 
336
- interface ModelConfig {
337
- name: string;
338
- description: string;
339
- icon: React.ComponentType;
340
- }
234
+ export const WithRadioGroup: Story = {
235
+ render: () => {
236
+ const [position, setPosition] = React.useState("bottom");
237
+
238
+ return (
239
+ <DropdownMenu>
240
+ <DropdownMenuTrigger>Open Radio Group</DropdownMenuTrigger>
241
+ <DropdownMenuContent className="s-w-56">
242
+ <DropdownMenuLabel label="Panel Position" />
243
+ <DropdownMenuSeparator />
244
+ <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
245
+ <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
246
+ <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
247
+ <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
248
+ </DropdownMenuRadioGroup>
249
+ </DropdownMenuContent>
250
+ </DropdownMenu>
251
+ );
252
+ },
253
+ };
341
254
 
342
- function ModelsDropdownRadioGroupDemo() {
343
- const [selectedModel, setSelectedModel] = React.useState<string>("GPT4-o");
344
-
345
- const bestPerformingModels: ModelConfig[] = [
346
- {
347
- name: "GPT4-o",
348
- description: "OpenAI's most advanced model.",
349
- icon: OpenaiLogo,
350
- },
351
- {
352
- name: "Claude 3.5 Sonnet",
353
- description: "Anthropic's latest Claude 3.5 Sonnet model (200k context).",
354
- icon: AnthropicLogo,
355
- },
356
- {
357
- name: "Mistral Large",
358
- description: "Mistral's `large 2` model (128k context).",
359
- icon: MistralLogo,
360
- },
361
- ];
362
-
363
- return (
364
- <DropdownMenu>
365
- <DropdownMenuTrigger asChild>
366
- <Button label={selectedModel} variant="ghost" size="sm" />
367
- </DropdownMenuTrigger>
368
- <DropdownMenuContent>
369
- <DropdownMenuRadioGroup
370
- value={selectedModel}
371
- onValueChange={(value) => setSelectedModel(value)}
372
- >
255
+ export const ModelSelector: Story = {
256
+ render: () => {
257
+ const [selectedModel, setSelectedModel] = React.useState<string>("GPT4-o");
258
+ const bestPerformingModels = [
259
+ {
260
+ name: "GPT4-o",
261
+ description: "OpenAI's most advanced model.",
262
+ icon: OpenaiLogo,
263
+ },
264
+ {
265
+ name: "Claude 3.5 Sonnet",
266
+ description:
267
+ "Anthropic's latest Claude 3.5 Sonnet model (200k context).",
268
+ icon: AnthropicLogo,
269
+ },
270
+ {
271
+ name: "Mistral Large",
272
+ description: "Mistral's `large 2` model (128k context).",
273
+ icon: MistralLogo,
274
+ },
275
+ ];
276
+
277
+ return (
278
+ <DropdownMenu>
279
+ <DropdownMenuTrigger asChild>
280
+ <Button
281
+ label={selectedModel}
282
+ variant="outline"
283
+ size="sm"
284
+ tooltip="Test"
285
+ />
286
+ </DropdownMenuTrigger>
287
+ <DropdownMenuContent>
373
288
  <DropdownMenuLabel label="Best performing models" />
374
289
  {bestPerformingModels.map((modelConfig) => (
375
- <DropdownMenuRadioItem
290
+ <DropdownMenuItem
376
291
  key={modelConfig.name}
377
292
  label={modelConfig.name}
378
- icon={modelConfig.icon}
293
+ onClick={() => setSelectedModel(modelConfig.name)}
379
294
  description={modelConfig.description}
380
- value={modelConfig.name}
295
+ icon={modelConfig.icon}
381
296
  />
382
297
  ))}
383
- </DropdownMenuRadioGroup>
384
- </DropdownMenuContent>
385
- </DropdownMenu>
386
- );
387
- }
388
-
389
- function AttachFileDemo() {
390
- const [searchText, setSearchText] = React.useState("");
391
- const [selectedItem, setSelectedItem] = React.useState<string | null>(null);
392
- const [open, setOpen] = React.useState(false);
393
- const [openAgents, setOpenAgents] = React.useState(false);
394
- const [openToolsets, setOpenToolsets] = React.useState(false);
395
- const searchInputRef = React.useRef<HTMLInputElement>(null);
396
- const agentsSearchInputRef = React.useRef<HTMLInputElement>(null);
397
- const toolsetsSearchInputRef = React.useRef<HTMLInputElement>(null);
398
-
399
- React.useEffect(() => {
400
- if (open) {
401
- setTimeout(() => {
402
- searchInputRef.current?.focus();
403
- }, 0);
404
- }
405
- }, [open]);
298
+ </DropdownMenuContent>
299
+ </DropdownMenu>
300
+ );
301
+ },
302
+ };
406
303
 
407
- React.useEffect(() => {
408
- if (openAgents) {
409
- setTimeout(() => {
410
- agentsSearchInputRef.current?.focus();
411
- }, 0);
412
- }
413
- }, [openAgents]);
304
+ interface ModelConfig {
305
+ name: string;
306
+ description: string;
307
+ icon: React.ComponentType;
308
+ }
414
309
 
415
- React.useEffect(() => {
416
- if (openToolsets) {
417
- setTimeout(() => {
418
- toolsetsSearchInputRef.current?.focus();
419
- }, 0);
420
- }
421
- }, [openToolsets]);
422
-
423
- const items = [
424
- "Automated Data Processing Automated Data Processing Automated Data Processing Automated Data Processing",
425
- "Business Intelligence Dashboard",
426
- "Cloud Infrastructure Setup",
427
- "Data Migration Service",
428
- "Enterprise Resource Planning",
429
- "Financial Analytics Platform",
430
- "Geographic Information System",
431
- "Human Resources Management",
432
- "Inventory Control System",
433
- "Knowledge Base Integration",
434
- "Machine Learning Pipeline",
435
- "Network Security Monitor",
436
- "Operations Management Tool",
437
- "Project Portfolio Tracker",
438
- "Quality Assurance Framework",
439
- "Real-time Analytics Engine",
440
- "Supply Chain Optimizer",
441
- "Team Collaboration Hub",
442
- "User Authentication Service",
443
- "Workflow Automation System",
444
- ];
445
-
446
- const filteredItems = items.filter((item) =>
447
- item.toLowerCase().includes(searchText.toLowerCase())
448
- );
449
-
450
- const mainIcons = [FolderIcon, DocumentIcon];
451
- const extraIcons = [DriveLogo, NotionLogo, SlackLogo];
452
-
453
- const filteredAgents = [
454
- {
455
- name: "Research Assistant",
456
- description: "Academic research and paper analysis",
457
- emoji: "🔬",
458
- backgroundColor: "s-bg-blue-200",
459
- },
460
- {
461
- name: "Code Companion",
462
- description: "Pair programming and code review",
463
- emoji: "💻",
464
- backgroundColor: "s-bg-purple-200",
465
- },
466
- {
467
- name: "Data Analyst",
468
- description: "Data visualization and insights",
469
- emoji: "��",
470
- backgroundColor: "s-bg-green-200",
471
- },
472
- {
473
- name: "Content Writer",
474
- description: "Blog posts and marketing copy",
475
- emoji: "✍️",
476
- backgroundColor: "s-bg-yellow-200",
477
- },
478
- {
479
- name: "Customer Support",
480
- description: "24/7 customer service automation",
481
- emoji: "🤝",
482
- backgroundColor: "s-bg-pink-200",
483
- },
484
- {
485
- name: "Legal Assistant",
486
- description: "Contract review and legal research",
487
- emoji: "⚖️",
488
- backgroundColor: "s-bg-red-200",
489
- },
490
- {
491
- name: "Design Assistant",
492
- description: "UI/UX design and prototyping",
493
- emoji: "🎨",
494
- backgroundColor: "s-bg-indigo-200",
495
- },
496
- {
497
- name: "Financial Advisor",
498
- description: "Investment analysis and planning",
499
- emoji: "💰",
500
- backgroundColor: "s-bg-emerald-200",
501
- },
502
- ] as const;
503
-
504
- const filteredToolsetList = [
505
- {
506
- name: "Product Design Suite",
507
- description: "Figma, Adobe XD, and design assets",
508
- icon: ActionMagicIcon,
509
- },
510
- {
511
- name: "Business Intelligence",
512
- description: "Tableau, PowerBI, and analytics tools",
513
- icon: ActionDocumentIcon,
514
- },
515
- {
516
- name: "Project Management",
517
- description: "Notion, Jira, and task tracking",
518
- icon: ActionFolderIcon,
519
- },
520
- {
521
- name: "Communication Hub",
522
- description: "Slack, Email, and messaging platforms",
523
- icon: ActionArmchairIcon,
524
- },
525
- {
526
- name: "Development Stack",
527
- description: "GitHub, VSCode, and dev tools",
528
- icon: ActionCommand1Icon,
529
- },
530
- {
531
- name: "Customer Success",
532
- description: "Zendesk, Intercom, and support tools",
533
- icon: ActionUserGroupIcon,
534
- },
535
- {
536
- name: "Marketing Suite",
537
- description: "HubSpot, Mailchimp, and campaign tools",
538
- icon: ActionCloudArrowDownIcon,
539
- },
540
- {
541
- name: "Data Warehouse",
542
- description: "Snowflake, BigQuery, and data storage",
543
- icon: ActionArmchairIcon,
544
- },
545
- {
546
- name: "HR Platform",
547
- description: "BambooHR, Workday, and people tools",
548
- icon: ActionMagicIcon,
549
- },
550
- {
551
- name: "Finance Stack",
552
- description: "QuickBooks, Stripe, and payment tools",
553
- icon: ActionFolderIcon,
554
- },
555
- ] as const;
556
-
557
- return (
558
- <div className="s-flex s-gap-2">
559
- <DropdownMenu open={open} onOpenChange={setOpen} modal={false}>
310
+ export const ModelSelectorWithRadio: Story = {
311
+ render: () => {
312
+ const [selectedModel, setSelectedModel] = React.useState<string>("GPT4-o");
313
+
314
+ const bestPerformingModels: ModelConfig[] = [
315
+ {
316
+ name: "GPT4-o",
317
+ description: "OpenAI's most advanced model.",
318
+ icon: OpenaiLogo,
319
+ },
320
+ {
321
+ name: "Claude 3.5 Sonnet",
322
+ description:
323
+ "Anthropic's latest Claude 3.5 Sonnet model (200k context).",
324
+ icon: AnthropicLogo,
325
+ },
326
+ {
327
+ name: "Mistral Large",
328
+ description: "Mistral's `large 2` model (128k context).",
329
+ icon: MistralLogo,
330
+ },
331
+ ];
332
+
333
+ return (
334
+ <DropdownMenu>
560
335
  <DropdownMenuTrigger asChild>
561
- <Button
562
- label={selectedItem || "Attach"}
563
- icon={AttachmentIcon}
564
- variant="outline"
565
- size="sm"
566
- />
336
+ <Button label={selectedModel} variant="ghost" size="sm" />
567
337
  </DropdownMenuTrigger>
568
- <DropdownMenuContent
569
- className="s-w-[380px]"
570
- dropdownHeaders={
571
- <DropdownMenuSearchbar
572
- value={searchText}
573
- onChange={setSearchText}
574
- name="search"
575
- placeholder="Search in Dust"
576
- button={<Button icon={ArrowUpOnSquareIcon} label="Upload File" />}
338
+ <DropdownMenuContent>
339
+ <DropdownMenuRadioGroup
340
+ value={selectedModel}
341
+ onValueChange={(value) => setSelectedModel(value)}
342
+ >
343
+ <DropdownMenuLabel label="Best performing models" />
344
+ {bestPerformingModels.map((modelConfig) => (
345
+ <DropdownMenuRadioItem
346
+ key={modelConfig.name}
347
+ label={modelConfig.name}
348
+ icon={modelConfig.icon}
349
+ description={modelConfig.description}
350
+ value={modelConfig.name}
351
+ />
352
+ ))}
353
+ </DropdownMenuRadioGroup>
354
+ </DropdownMenuContent>
355
+ </DropdownMenu>
356
+ );
357
+ },
358
+ };
359
+
360
+ export const WithSearchAndPicker: Story = {
361
+ render: () => {
362
+ const [searchText, setSearchText] = React.useState("");
363
+ const [selectedItem, setSelectedItem] = React.useState<string | null>(null);
364
+ const [open, setOpen] = React.useState(false);
365
+ const [openAgents, setOpenAgents] = React.useState(false);
366
+ const [openToolsets, setOpenToolsets] = React.useState(false);
367
+ const searchInputRef = React.useRef<HTMLInputElement>(null);
368
+ const agentsSearchInputRef = React.useRef<HTMLInputElement>(null);
369
+ const toolsetsSearchInputRef = React.useRef<HTMLInputElement>(null);
370
+
371
+ React.useEffect(() => {
372
+ if (open) {
373
+ setTimeout(() => {
374
+ searchInputRef.current?.focus();
375
+ }, 0);
376
+ }
377
+ }, [open]);
378
+
379
+ React.useEffect(() => {
380
+ if (openAgents) {
381
+ setTimeout(() => {
382
+ agentsSearchInputRef.current?.focus();
383
+ }, 0);
384
+ }
385
+ }, [openAgents]);
386
+
387
+ React.useEffect(() => {
388
+ if (openToolsets) {
389
+ setTimeout(() => {
390
+ toolsetsSearchInputRef.current?.focus();
391
+ }, 0);
392
+ }
393
+ }, [openToolsets]);
394
+
395
+ const items = [
396
+ "Automated Data Processing Automated Data Processing Automated Data Processing Automated Data Processing",
397
+ "Business Intelligence Dashboard",
398
+ "Cloud Infrastructure Setup",
399
+ "Data Migration Service",
400
+ "Enterprise Resource Planning",
401
+ "Financial Analytics Platform",
402
+ "Geographic Information System",
403
+ "Human Resources Management",
404
+ "Inventory Control System",
405
+ "Knowledge Base Integration",
406
+ "Machine Learning Pipeline",
407
+ "Network Security Monitor",
408
+ "Operations Management Tool",
409
+ "Project Portfolio Tracker",
410
+ "Quality Assurance Framework",
411
+ "Real-time Analytics Engine",
412
+ "Supply Chain Optimizer",
413
+ "Team Collaboration Hub",
414
+ "User Authentication Service",
415
+ "Workflow Automation System",
416
+ ];
417
+
418
+ const filteredItems = items.filter((item) =>
419
+ item.toLowerCase().includes(searchText.toLowerCase())
420
+ );
421
+
422
+ const mainIcons = [FolderIcon, DocumentIcon];
423
+ const extraIcons = [DriveLogo, NotionLogo, SlackLogo];
424
+
425
+ const filteredAgents = [
426
+ {
427
+ name: "Research Assistant",
428
+ description: "Academic research and paper analysis",
429
+ emoji: "🔬",
430
+ backgroundColor: "s-bg-blue-200",
431
+ },
432
+ {
433
+ name: "Code Companion",
434
+ description: "Pair programming and code review",
435
+ emoji: "💻",
436
+ backgroundColor: "s-bg-purple-200",
437
+ },
438
+ {
439
+ name: "Data Analyst",
440
+ description: "Data visualization and insights",
441
+ emoji: "��",
442
+ backgroundColor: "s-bg-green-200",
443
+ },
444
+ {
445
+ name: "Content Writer",
446
+ description: "Blog posts and marketing copy",
447
+ emoji: "✍️",
448
+ backgroundColor: "s-bg-yellow-200",
449
+ },
450
+ {
451
+ name: "Customer Support",
452
+ description: "24/7 customer service automation",
453
+ emoji: "🤝",
454
+ backgroundColor: "s-bg-pink-200",
455
+ },
456
+ {
457
+ name: "Legal Assistant",
458
+ description: "Contract review and legal research",
459
+ emoji: "⚖️",
460
+ backgroundColor: "s-bg-red-200",
461
+ },
462
+ {
463
+ name: "Design Assistant",
464
+ description: "UI/UX design and prototyping",
465
+ emoji: "🎨",
466
+ backgroundColor: "s-bg-indigo-200",
467
+ },
468
+ {
469
+ name: "Financial Advisor",
470
+ description: "Investment analysis and planning",
471
+ emoji: "💰",
472
+ backgroundColor: "s-bg-emerald-200",
473
+ },
474
+ ] as const;
475
+
476
+ const filteredToolsetList = [
477
+ {
478
+ name: "Product Design Suite",
479
+ description: "Figma, Adobe XD, and design assets",
480
+ icon: ActionMagicIcon,
481
+ },
482
+ {
483
+ name: "Business Intelligence",
484
+ description: "Tableau, PowerBI, and analytics tools",
485
+ icon: ActionDocumentIcon,
486
+ },
487
+ {
488
+ name: "Project Management",
489
+ description: "Notion, Jira, and task tracking",
490
+ icon: ActionFolderIcon,
491
+ },
492
+ {
493
+ name: "Communication Hub",
494
+ description: "Slack, Email, and messaging platforms",
495
+ icon: ActionArmchairIcon,
496
+ },
497
+ {
498
+ name: "Development Stack",
499
+ description: "GitHub, VSCode, and dev tools",
500
+ icon: ActionCommand1Icon,
501
+ },
502
+ {
503
+ name: "Customer Success",
504
+ description: "Zendesk, Intercom, and support tools",
505
+ icon: ActionUserGroupIcon,
506
+ },
507
+ {
508
+ name: "Marketing Suite",
509
+ description: "HubSpot, Mailchimp, and campaign tools",
510
+ icon: ActionCloudArrowDownIcon,
511
+ },
512
+ {
513
+ name: "Data Warehouse",
514
+ description: "Snowflake, BigQuery, and data storage",
515
+ icon: ActionArmchairIcon,
516
+ },
517
+ {
518
+ name: "HR Platform",
519
+ description: "BambooHR, Workday, and people tools",
520
+ icon: ActionMagicIcon,
521
+ },
522
+ {
523
+ name: "Finance Stack",
524
+ description: "QuickBooks, Stripe, and payment tools",
525
+ icon: ActionFolderIcon,
526
+ },
527
+ ] as const;
528
+
529
+ return (
530
+ <div className="s-flex s-gap-2">
531
+ <DropdownMenu open={open} onOpenChange={setOpen} modal={false}>
532
+ <DropdownMenuTrigger asChild>
533
+ <Button
534
+ label={selectedItem || "Attach"}
535
+ icon={AttachmentIcon}
536
+ variant="outline"
537
+ size="sm"
577
538
  />
578
- }
579
- >
580
- <DropdownMenuSeparator />
581
- {searchText ? (
582
- filteredItems.map((item) => {
583
- const randomMainIcon =
584
- mainIcons[Math.floor(Math.random() * mainIcons.length)];
585
- const randomExtraIcon =
586
- extraIcons[Math.floor(Math.random() * extraIcons.length)];
539
+ </DropdownMenuTrigger>
540
+ <DropdownMenuContent
541
+ className="s-w-[380px]"
542
+ dropdownHeaders={
543
+ <DropdownMenuSearchbar
544
+ value={searchText}
545
+ onChange={setSearchText}
546
+ name="search"
547
+ placeholder="Search in Dust"
548
+ button={
549
+ <Button icon={ArrowUpOnSquareIcon} label="Upload File" />
550
+ }
551
+ />
552
+ }
553
+ >
554
+ <DropdownMenuSeparator />
555
+ {searchText ? (
556
+ filteredItems.map((item) => {
557
+ const randomMainIcon =
558
+ mainIcons[Math.floor(Math.random() * mainIcons.length)];
559
+ const randomExtraIcon =
560
+ extraIcons[Math.floor(Math.random() * extraIcons.length)];
561
+ return (
562
+ <DropdownMenuItem
563
+ key={item}
564
+ label={item}
565
+ description="Company Space/Notion"
566
+ icon={
567
+ <DoubleIcon
568
+ size="lg"
569
+ mainIcon={randomMainIcon}
570
+ secondaryIcon={randomExtraIcon}
571
+ />
572
+ }
573
+ onClick={() => {
574
+ setSelectedItem(item);
575
+ setSearchText("");
576
+ }}
577
+ truncateText
578
+ />
579
+ );
580
+ })
581
+ ) : (
582
+ <div className="s-flex s-h-full s-w-full s-items-center s-justify-center s-py-8">
583
+ <div className="s-flex s-flex-col s-items-center s-justify-center s-gap-0 s-text-center s-text-base s-font-semibold s-text-primary-400">
584
+ <Icon visual={MagnifyingGlassIcon} size="sm" />
585
+ Search in Dust
586
+ </div>
587
+ </div>
588
+ )}
589
+ </DropdownMenuContent>
590
+ </DropdownMenu>
591
+ <DropdownMenu open={openAgents} onOpenChange={setOpenAgents}>
592
+ <DropdownMenuTrigger asChild>
593
+ <Button icon={RobotIcon} variant="outline" size="sm" isSelect />
594
+ </DropdownMenuTrigger>
595
+ <DropdownMenuContent
596
+ className="s-h-96 s-w-[380px]"
597
+ dropdownHeaders={
598
+ <DropdownMenuSearchbar
599
+ ref={agentsSearchInputRef}
600
+ name="search"
601
+ value={searchText}
602
+ onChange={setSearchText}
603
+ onKeyDown={() => {}}
604
+ placeholder="Search Agents"
605
+ button={<Button icon={PlusIcon} label="Create" />}
606
+ />
607
+ }
608
+ >
609
+ <DropdownMenuSeparator />
610
+ {filteredAgents.map((agent) => {
587
611
  return (
588
612
  <DropdownMenuItem
589
- key={item}
590
- label={item}
591
- description="Company Space/Notion"
592
- icon={
593
- <DoubleIcon
594
- size="lg"
595
- mainIcon={randomMainIcon}
596
- secondaryIcon={randomExtraIcon}
613
+ key={agent.name}
614
+ label={agent.name}
615
+ description={agent.description}
616
+ icon={() => (
617
+ <Avatar
618
+ size="sm"
619
+ emoji={agent.emoji}
620
+ backgroundColor={agent.backgroundColor}
597
621
  />
598
- }
622
+ )}
599
623
  onClick={() => {
600
- setSelectedItem(item);
624
+ setSelectedItem(agent.name);
601
625
  setSearchText("");
602
626
  }}
603
627
  truncateText
604
628
  />
605
629
  );
606
- })
607
- ) : (
608
- <div className="s-flex s-h-full s-w-full s-items-center s-justify-center s-py-8">
609
- <div className="s-flex s-flex-col s-items-center s-justify-center s-gap-0 s-text-center s-text-base s-font-semibold s-text-primary-400">
610
- <Icon visual={MagnifyingGlassIcon} size="sm" />
611
- Search in Dust
612
- </div>
613
- </div>
614
- )}
615
- </DropdownMenuContent>
616
- </DropdownMenu>
617
- <DropdownMenu open={openAgents} onOpenChange={setOpenAgents}>
618
- <DropdownMenuTrigger asChild>
619
- <Button icon={RobotIcon} variant="outline" size="sm" isSelect />
620
- </DropdownMenuTrigger>
621
- <DropdownMenuContent
622
- className="s-h-96 s-w-[380px]"
623
- dropdownHeaders={
624
- <DropdownMenuSearchbar
625
- ref={agentsSearchInputRef}
626
- name="search"
627
- value={searchText}
628
- onChange={setSearchText}
629
- onKeyDown={() => {}}
630
- placeholder="Search Agents"
631
- button={<Button icon={PlusIcon} label="Create" />}
630
+ })}
631
+ </DropdownMenuContent>
632
+ </DropdownMenu>
633
+ <DropdownMenu open={openToolsets} onOpenChange={setOpenToolsets}>
634
+ <DropdownMenuTrigger asChild>
635
+ <Button
636
+ label={selectedItem || "Add Toolset"}
637
+ icon={SuitcaseIcon}
638
+ variant="outline"
639
+ size="sm"
632
640
  />
633
- }
634
- >
635
- <DropdownMenuSeparator />
636
- {filteredAgents.map((agent) => {
637
- return (
638
- <DropdownMenuItem
639
- key={agent.name}
640
- label={agent.name}
641
- description={agent.description}
642
- icon={() => (
643
- <Avatar
644
- size="sm"
645
- emoji={agent.emoji}
646
- backgroundColor={agent.backgroundColor}
647
- />
648
- )}
649
- onClick={() => {
650
- setSelectedItem(agent.name);
651
- setSearchText("");
652
- }}
653
- truncateText
641
+ </DropdownMenuTrigger>
642
+ <DropdownMenuContent
643
+ className="s-h-96 s-w-[380px]"
644
+ dropdownHeaders={
645
+ <DropdownMenuSearchbar
646
+ ref={toolsetsSearchInputRef}
647
+ name="search"
648
+ value={searchText}
649
+ onChange={setSearchText}
650
+ onKeyDown={() => {}}
651
+ placeholder="Search Tools"
652
+ button={<Button icon={PlusIcon} label="Add MCP Server" />}
654
653
  />
655
- );
656
- })}
657
- </DropdownMenuContent>
658
- </DropdownMenu>
659
- <DropdownMenu open={openToolsets} onOpenChange={setOpenToolsets}>
654
+ }
655
+ >
656
+ <DropdownMenuSeparator />
657
+ {filteredToolsetList.map((toolset) => {
658
+ return (
659
+ <DropdownMenuItem
660
+ key={toolset.name}
661
+ label={toolset.name}
662
+ description={toolset.description}
663
+ icon={() => <Avatar size="sm" icon={toolset.icon} />}
664
+ onClick={() => {
665
+ setSelectedItem(toolset.name);
666
+ setSearchText("");
667
+ }}
668
+ truncateText
669
+ />
670
+ );
671
+ })}
672
+ </DropdownMenuContent>
673
+ </DropdownMenu>
674
+ </div>
675
+ );
676
+ },
677
+ };
678
+
679
+ export const WithStaticItems: Story = {
680
+ render: () => {
681
+ return (
682
+ <DropdownMenu>
660
683
  <DropdownMenuTrigger asChild>
661
- <Button
662
- label={selectedItem || "Add Toolset"}
663
- icon={SuitcaseIcon}
664
- variant="outline"
665
- size="sm"
666
- />
684
+ <Button label="System Status" variant="outline" size="sm" />
667
685
  </DropdownMenuTrigger>
668
- <DropdownMenuContent
669
- className="s-h-96 s-w-[380px]"
670
- dropdownHeaders={
671
- <DropdownMenuSearchbar
672
- ref={toolsetsSearchInputRef}
673
- name="search"
674
- value={searchText}
675
- onChange={setSearchText}
676
- onKeyDown={() => {}}
677
- placeholder="Search Tools"
678
- button={<Button icon={PlusIcon} label="Add MCP Server" />}
679
- />
680
- }
681
- >
682
- <DropdownMenuSeparator />
683
- {filteredToolsetList.map((toolset) => {
684
- return (
685
- <DropdownMenuItem
686
- key={toolset.name}
687
- label={toolset.name}
688
- description={toolset.description}
689
- icon={() => <Avatar size="sm" icon={toolset.icon} />}
690
- onClick={() => {
691
- setSelectedItem(toolset.name);
692
- setSearchText("");
693
- }}
694
- truncateText
686
+ <DropdownMenuContent className="s-w-[250px]">
687
+ <DropdownMenuLabel label="System Metrics" />
688
+ <DropdownMenuStaticItem label="CPU Usage" value="45%" />
689
+ <DropdownMenuStaticItem label="Memory" value="2.3GB/8GB" />
690
+ <DropdownMenuStaticItem label="Disk Space">
691
+ <span className="s-flex s-items-center s-gap-2 s-text-muted-foreground">
692
+ 3
693
+ <Icon
694
+ size="xs"
695
+ className="s-text-muted-foreground"
696
+ visual={HandThumbUpIcon}
697
+ />
698
+ 1
699
+ <Icon
700
+ size="xs"
701
+ className="s-text-muted-foreground"
702
+ visual={HandThumbDownIcon}
695
703
  />
696
- );
697
- })}
704
+ </span>
705
+ </DropdownMenuStaticItem>
706
+ <DropdownMenuSeparator />
707
+ <DropdownMenuLabel label="Actions" />
708
+ <DropdownMenuItem
709
+ icon={Cog6ToothIcon}
710
+ label="System Settings"
711
+ onClick={() => console.log("Settings clicked")}
712
+ />
713
+ <DropdownMenuItem
714
+ icon={CloudArrowDownIcon}
715
+ label="Download Report"
716
+ onClick={() => console.log("Download clicked")}
717
+ />
698
718
  </DropdownMenuContent>
699
719
  </DropdownMenu>
700
- </div>
701
- );
702
- }
720
+ );
721
+ },
722
+ };
703
723
 
704
- function StaticItemDropdownDemo() {
705
- return (
706
- <DropdownMenu>
707
- <DropdownMenuTrigger asChild>
708
- <Button label="System Status" variant="outline" size="sm" />
709
- </DropdownMenuTrigger>
710
- <DropdownMenuContent className="s-w-[250px]">
711
- <DropdownMenuLabel label="System Metrics" />
712
- <DropdownMenuStaticItem label="CPU Usage" value="45%" />
713
- <DropdownMenuStaticItem label="Memory" value="2.3GB/8GB" />
714
- <DropdownMenuStaticItem label="Disk Space">
715
- <span className="s-flex s-items-center s-gap-2 s-text-muted-foreground">
716
- 3
717
- <Icon
718
- size="xs"
719
- className="s-text-muted-foreground"
720
- visual={HandThumbUpIcon}
721
- />
722
- 1
723
- <Icon
724
- size="xs"
725
- className="s-text-muted-foreground"
726
- visual={HandThumbDownIcon}
727
- />
728
- </span>
729
- </DropdownMenuStaticItem>
730
- <DropdownMenuSeparator />
731
- <DropdownMenuLabel label="Actions" />
732
- <DropdownMenuItem
733
- icon={Cog6ToothIcon}
734
- label="System Settings"
735
- onClick={() => console.log("Settings clicked")}
736
- />
737
- <DropdownMenuItem
738
- icon={CloudArrowDownIcon}
739
- label="Download Report"
740
- onClick={() => console.log("Download clicked")}
741
- />
742
- </DropdownMenuContent>
743
- </DropdownMenu>
744
- );
745
- }
724
+ export const WithSearchFilter: Story = {
725
+ render: () => {
726
+ const [searchInputValue, setSearchInputValue] = React.useState("");
746
727
 
747
- export const TagsDropdownExample = () => {
748
- const [tags, setTags] = useState([
749
- "react",
750
- "typescript",
751
- "ui",
752
- "design-system",
753
- ]);
754
- const [isLoading, setIsLoading] = useState(false);
755
-
756
- const handleRemoveTag = (tagToRemove: string) => {
757
- setTags(tags.filter((tag) => tag !== tagToRemove));
758
- };
759
-
760
- const handleAddTag = () => {
761
- setIsLoading(true);
762
-
763
- // Simulate API call delay
764
- setTimeout(() => {
765
- const newTag = `tag-${Math.floor(Math.random() * 1000)}`;
766
- setTags([...tags, newTag]);
767
- setIsLoading(false);
768
- }, 1500);
769
- };
770
-
771
- return (
772
- <div className="s-flex s-flex-col s-gap-4 s-p-4">
773
- <div className="s-flex s-items-center s-gap-2">
774
- <DropdownMenu open={true}>
775
- <DropdownMenuTrigger asChild>
776
- <Button
777
- variant="outline"
778
- label="Select Tags"
779
- icon={PlusIcon}
780
- size="sm"
781
- isSelect
782
- />
783
- </DropdownMenuTrigger>
784
- <DropdownMenuContent className="s-w-80">
785
- <DropdownMenuLabel label="Available Tags" />
786
- <DropdownMenuSeparator />
787
- <DropdownMenuTagList>
788
- {tags.map((tag) => (
789
- <DropdownMenuTagItem
790
- key={tag}
791
- label={tag}
792
- color="highlight"
793
- onRemove={() => handleRemoveTag(tag)}
794
- onClick={() => console.log(tag)}
795
- />
796
- ))}
797
- </DropdownMenuTagList>
728
+ const items = ["Profile", "Billing", "Team", "Subscription"];
798
729
 
799
- <DropdownMenuSeparator />
800
- <div className="s-p-2">
730
+ const filteredItems = items.filter((item) =>
731
+ item.toLowerCase().includes(searchInputValue.toLowerCase())
732
+ );
733
+
734
+ return (
735
+ <SearchDropdownMenu
736
+ searchInputValue={searchInputValue}
737
+ setSearchInputValue={setSearchInputValue}
738
+ >
739
+ {filteredItems.map((item) => (
740
+ <DropdownMenuItem
741
+ key={item}
742
+ label={item}
743
+ onClick={() => {
744
+ console.log(item);
745
+ }}
746
+ />
747
+ ))}
748
+ </SearchDropdownMenu>
749
+ );
750
+ },
751
+ };
752
+
753
+ export const WithTags: Story = {
754
+ render: () => {
755
+ const [tags, setTags] = useState([
756
+ "react",
757
+ "typescript",
758
+ "ui",
759
+ "design-system",
760
+ ]);
761
+ const [isLoading, setIsLoading] = useState(false);
762
+
763
+ const handleRemoveTag = (tagToRemove: string) => {
764
+ setTags(tags.filter((tag) => tag !== tagToRemove));
765
+ };
766
+
767
+ const handleAddTag = () => {
768
+ setIsLoading(true);
769
+
770
+ // Simulate API call delay
771
+ setTimeout(() => {
772
+ const newTag = `tag-${Math.floor(Math.random() * 1000)}`;
773
+ setTags([...tags, newTag]);
774
+ setIsLoading(false);
775
+ }, 1500);
776
+ };
777
+
778
+ return (
779
+ <div className="s-flex s-flex-col s-gap-4 s-p-4">
780
+ <div className="s-flex s-items-center s-gap-2">
781
+ <DropdownMenu>
782
+ <DropdownMenuTrigger asChild>
801
783
  <Button
802
- label={isLoading ? "Adding..." : "Add Random Tag"}
803
- onClick={handleAddTag}
804
- className="s-w-full"
784
+ variant="outline"
785
+ label="Select Tags"
786
+ icon={PlusIcon}
805
787
  size="sm"
806
- disabled={isLoading}
807
- icon={
808
- isLoading
809
- ? () => <Spinner size="xs" variant="color" />
810
- : undefined
811
- }
788
+ isSelect
812
789
  />
813
- </div>
814
- </DropdownMenuContent>
815
- </DropdownMenu>
790
+ </DropdownMenuTrigger>
791
+ <DropdownMenuContent className="s-w-80">
792
+ <DropdownMenuLabel label="Available Tags" />
793
+ <DropdownMenuSeparator />
794
+ <DropdownMenuTagList>
795
+ {tags.map((tag) => (
796
+ <DropdownMenuTagItem
797
+ key={tag}
798
+ label={tag}
799
+ color="highlight"
800
+ onRemove={() => handleRemoveTag(tag)}
801
+ onClick={() => console.log(tag)}
802
+ />
803
+ ))}
804
+ </DropdownMenuTagList>
805
+
806
+ <DropdownMenuSeparator />
807
+ <div className="s-p-2">
808
+ <Button
809
+ label={isLoading ? "Adding..." : "Add Random Tag"}
810
+ onClick={handleAddTag}
811
+ className="s-w-full"
812
+ size="sm"
813
+ disabled={isLoading}
814
+ icon={
815
+ isLoading
816
+ ? () => <Spinner size="xs" variant="color" />
817
+ : undefined
818
+ }
819
+ />
820
+ </div>
821
+ </DropdownMenuContent>
822
+ </DropdownMenu>
816
823
 
817
- <div className="s-text-sm s-text-muted-foreground">
818
- Click to view available tags
824
+ <div className="s-text-sm s-text-muted-foreground">
825
+ Click to view available tags
826
+ </div>
819
827
  </div>
820
- </div>
821
828
 
822
- <div className="s-flex s-flex-wrap s-gap-2 s-rounded-lg s-border s-border-border s-p-4">
823
- <span className="s-mr-2 s-text-sm s-text-muted-foreground">
824
- Current tags:
825
- </span>
826
- {tags.map((tag) => (
827
- <div key={tag} className="s-inline-flex">
828
- <Chip
829
- label={tag}
830
- color="highlight"
831
- size="xs"
832
- onRemove={() => handleRemoveTag(tag)}
833
- />
834
- </div>
835
- ))}
829
+ <div className="s-flex s-flex-wrap s-gap-2 s-rounded-lg s-border s-border-border s-p-4">
830
+ <span className="s-mr-2 s-text-sm s-text-muted-foreground">
831
+ Current tags:
832
+ </span>
833
+ {tags.map((tag) => (
834
+ <div key={tag} className="s-inline-flex">
835
+ <Chip
836
+ label={tag}
837
+ color="highlight"
838
+ size="xs"
839
+ onRemove={() => handleRemoveTag(tag)}
840
+ />
841
+ </div>
842
+ ))}
843
+ </div>
836
844
  </div>
837
- </div>
838
- );
845
+ );
846
+ },
839
847
  };