@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.
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/ConversationMessage.d.ts.map +1 -1
- package/dist/esm/components/ConversationMessage.js +2 -2
- package/dist/esm/components/ConversationMessage.js.map +1 -1
- package/dist/esm/components/ScrollArea.d.ts +1 -1
- package/dist/esm/components/ScrollArea.d.ts.map +1 -1
- package/dist/esm/components/markdown/Markdown.js +1 -1
- package/dist/esm/components/markdown/Markdown.js.map +1 -1
- package/dist/esm/icons/actions/Frame.d.ts +5 -0
- package/dist/esm/icons/actions/Frame.d.ts.map +1 -0
- package/dist/esm/icons/actions/Frame.js +6 -0
- package/dist/esm/icons/actions/Frame.js.map +1 -0
- package/dist/esm/icons/actions/index.d.ts +1 -0
- package/dist/esm/icons/actions/index.d.ts.map +1 -1
- package/dist/esm/icons/actions/index.js +1 -0
- package/dist/esm/icons/actions/index.js.map +1 -1
- package/dist/esm/icons/src/actions/frame.svg +3 -0
- package/dist/esm/stories/AnchoredPopover.stories.d.ts +1 -2
- package/dist/esm/stories/AnchoredPopover.stories.d.ts.map +1 -1
- package/dist/esm/stories/AnchoredPopover.stories.js +36 -48
- package/dist/esm/stories/AnchoredPopover.stories.js.map +1 -1
- package/dist/esm/stories/Avatar.stories.d.ts +64 -5
- package/dist/esm/stories/Avatar.stories.d.ts.map +1 -1
- package/dist/esm/stories/Avatar.stories.js +407 -331
- package/dist/esm/stories/Avatar.stories.js.map +1 -1
- package/dist/esm/stories/Button.stories.d.ts +1 -0
- package/dist/esm/stories/Button.stories.d.ts.map +1 -1
- package/dist/esm/stories/Button.stories.js +1 -0
- package/dist/esm/stories/Button.stories.js.map +1 -1
- package/dist/esm/stories/Card.stories.d.ts +39 -3
- package/dist/esm/stories/Card.stories.d.ts.map +1 -1
- package/dist/esm/stories/Card.stories.js +92 -22
- package/dist/esm/stories/Card.stories.js.map +1 -1
- package/dist/esm/stories/Chip.stories.d.ts +4 -3
- package/dist/esm/stories/Chip.stories.d.ts.map +1 -1
- package/dist/esm/stories/Chip.stories.js +37 -30
- package/dist/esm/stories/Chip.stories.js.map +1 -1
- package/dist/esm/stories/Dropdown.stories.d.ts +13 -4
- package/dist/esm/stories/Dropdown.stories.d.ts.map +1 -1
- package/dist/esm/stories/Dropdown.stories.js +418 -411
- package/dist/esm/stories/Dropdown.stories.js.map +1 -1
- package/dist/esm/stories/Icon.stories.d.ts +1 -0
- package/dist/esm/stories/Icon.stories.d.ts.map +1 -1
- package/dist/esm/stories/Icon.stories.js +1 -0
- package/dist/esm/stories/Icon.stories.js.map +1 -1
- package/dist/esm/stories/IconSet.stories.d.ts +7 -5
- package/dist/esm/stories/IconSet.stories.d.ts.map +1 -1
- package/dist/esm/stories/IconSet.stories.js +21 -15
- package/dist/esm/stories/IconSet.stories.js.map +1 -1
- package/dist/esm/stories/Input.stories.d.ts +46 -1
- package/dist/esm/stories/Input.stories.d.ts.map +1 -1
- package/dist/esm/stories/Input.stories.js +94 -16
- package/dist/esm/stories/Input.stories.js.map +1 -1
- package/dist/esm/stories/Logo.stories.d.ts +6 -4
- package/dist/esm/stories/Logo.stories.d.ts.map +1 -1
- package/dist/esm/stories/Logo.stories.js +41 -37
- package/dist/esm/stories/Logo.stories.js.map +1 -1
- package/dist/esm/stories/Markdown.stories.d.ts +24 -2
- package/dist/esm/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/esm/stories/Markdown.stories.js +1 -0
- package/dist/esm/stories/Markdown.stories.js.map +1 -1
- package/dist/esm/stories/ScrollArea.stories.d.ts +12 -5
- package/dist/esm/stories/ScrollArea.stories.d.ts.map +1 -1
- package/dist/esm/stories/ScrollArea.stories.js +7 -3
- package/dist/esm/stories/ScrollArea.stories.js.map +1 -1
- package/dist/esm/stories/Spinner.stories.d.ts +22 -1
- package/dist/esm/stories/Spinner.stories.d.ts.map +1 -1
- package/dist/esm/stories/Spinner.stories.js +91 -50
- package/dist/esm/stories/Spinner.stories.js.map +1 -1
- package/dist/esm/stories/Tabs.stories.d.ts +6 -2
- package/dist/esm/stories/Tabs.stories.d.ts.map +1 -1
- package/dist/esm/stories/Tabs.stories.js +10 -8
- package/dist/esm/stories/Tabs.stories.js.map +1 -1
- package/dist/sparkle.css +4 -19
- package/package.json +1 -1
- package/src/components/ConversationMessage.tsx +2 -9
- package/src/components/ScrollArea.tsx +1 -1
- package/src/components/markdown/Markdown.tsx +1 -1
- package/src/icons/actions/Frame.tsx +18 -0
- package/src/icons/actions/index.ts +1 -0
- package/src/icons/src/actions/frame.svg +3 -0
- package/src/stories/AnchoredPopover.stories.tsx +77 -91
- package/src/stories/Avatar.stories.tsx +558 -478
- package/src/stories/Button.stories.tsx +1 -0
- package/src/stories/Card.stories.tsx +146 -70
- package/src/stories/Chip.stories.tsx +108 -101
- package/src/stories/Dropdown.stories.tsx +725 -717
- package/src/stories/Icon.stories.tsx +1 -0
- package/src/stories/IconSet.stories.tsx +61 -52
- package/src/stories/Input.stories.tsx +168 -79
- package/src/stories/Logo.stories.tsx +76 -69
- package/src/stories/Markdown.stories.tsx +3 -2
- package/src/stories/ScrollArea.stories.tsx +10 -6
- package/src/stories/Spinner.stories.tsx +134 -87
- 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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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={
|
|
178
|
-
label="
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
180
|
+
icon={LogoutIcon}
|
|
181
|
+
label="Log out"
|
|
182
|
+
variant="warning"
|
|
183
|
+
href="/api/auth/logout"
|
|
182
184
|
/>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<
|
|
242
|
-
<
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
332
|
-
|
|
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
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
<
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
<
|
|
290
|
+
<DropdownMenuItem
|
|
376
291
|
key={modelConfig.name}
|
|
377
292
|
label={modelConfig.name}
|
|
378
|
-
|
|
293
|
+
onClick={() => setSelectedModel(modelConfig.name)}
|
|
379
294
|
description={modelConfig.description}
|
|
380
|
-
|
|
295
|
+
icon={modelConfig.icon}
|
|
381
296
|
/>
|
|
382
297
|
))}
|
|
383
|
-
</
|
|
384
|
-
</
|
|
385
|
-
|
|
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
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
}, [openAgents]);
|
|
304
|
+
interface ModelConfig {
|
|
305
|
+
name: string;
|
|
306
|
+
description: string;
|
|
307
|
+
icon: React.ComponentType;
|
|
308
|
+
}
|
|
414
309
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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={
|
|
590
|
-
label={
|
|
591
|
-
description=
|
|
592
|
-
icon={
|
|
593
|
-
<
|
|
594
|
-
size="
|
|
595
|
-
|
|
596
|
-
|
|
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(
|
|
624
|
+
setSelectedItem(agent.name);
|
|
601
625
|
setSearchText("");
|
|
602
626
|
}}
|
|
603
627
|
truncateText
|
|
604
628
|
/>
|
|
605
629
|
);
|
|
606
|
-
})
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
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
|
-
|
|
701
|
-
|
|
702
|
-
}
|
|
720
|
+
);
|
|
721
|
+
},
|
|
722
|
+
};
|
|
703
723
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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
|
-
|
|
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
|
-
|
|
800
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
784
|
+
variant="outline"
|
|
785
|
+
label="Select Tags"
|
|
786
|
+
icon={PlusIcon}
|
|
805
787
|
size="sm"
|
|
806
|
-
|
|
807
|
-
icon={
|
|
808
|
-
isLoading
|
|
809
|
-
? () => <Spinner size="xs" variant="color" />
|
|
810
|
-
: undefined
|
|
811
|
-
}
|
|
788
|
+
isSelect
|
|
812
789
|
/>
|
|
813
|
-
</
|
|
814
|
-
|
|
815
|
-
|
|
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
|
-
|
|
818
|
-
|
|
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
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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
|
-
|
|
838
|
-
|
|
845
|
+
);
|
|
846
|
+
},
|
|
839
847
|
};
|