@dust-tt/sparkle 0.2.513 → 0.2.516

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 (47) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/esm/components/BarHeader.d.ts +6 -2
  3. package/dist/esm/components/BarHeader.d.ts.map +1 -1
  4. package/dist/esm/components/BarHeader.js +18 -7
  5. package/dist/esm/components/BarHeader.js.map +1 -1
  6. package/dist/esm/components/MultiPageSheet.d.ts +30 -0
  7. package/dist/esm/components/MultiPageSheet.d.ts.map +1 -0
  8. package/dist/esm/components/MultiPageSheet.js +59 -0
  9. package/dist/esm/components/MultiPageSheet.js.map +1 -0
  10. package/dist/esm/components/index.d.ts +1 -0
  11. package/dist/esm/components/index.d.ts.map +1 -1
  12. package/dist/esm/components/index.js +1 -0
  13. package/dist/esm/components/index.js.map +1 -1
  14. package/dist/esm/icons/app/Moon.d.ts +5 -0
  15. package/dist/esm/icons/app/Moon.d.ts.map +1 -0
  16. package/dist/esm/icons/app/Moon.js +6 -0
  17. package/dist/esm/icons/app/Moon.js.map +1 -0
  18. package/dist/esm/icons/app/Sun.d.ts +5 -0
  19. package/dist/esm/icons/app/Sun.d.ts.map +1 -0
  20. package/dist/esm/icons/app/Sun.js +6 -0
  21. package/dist/esm/icons/app/Sun.js.map +1 -0
  22. package/dist/esm/icons/app/index.d.ts +2 -0
  23. package/dist/esm/icons/app/index.d.ts.map +1 -1
  24. package/dist/esm/icons/app/index.js +2 -0
  25. package/dist/esm/icons/app/index.js.map +1 -1
  26. package/dist/esm/icons/src/app/moon.svg +3 -0
  27. package/dist/esm/icons/src/app/sun.svg +3 -0
  28. package/dist/esm/stories/BarHeader.stories.d.ts +1 -0
  29. package/dist/esm/stories/BarHeader.stories.d.ts.map +1 -1
  30. package/dist/esm/stories/BarHeader.stories.js +25 -1
  31. package/dist/esm/stories/BarHeader.stories.js.map +1 -1
  32. package/dist/esm/stories/MultiPageSheet.stories.d.ts +8 -0
  33. package/dist/esm/stories/MultiPageSheet.stories.d.ts.map +1 -0
  34. package/dist/esm/stories/MultiPageSheet.stories.js +179 -0
  35. package/dist/esm/stories/MultiPageSheet.stories.js.map +1 -0
  36. package/dist/sparkle.css +13 -0
  37. package/package.json +1 -1
  38. package/src/components/BarHeader.tsx +25 -15
  39. package/src/components/MultiPageSheet.tsx +202 -0
  40. package/src/components/index.ts +8 -0
  41. package/src/icons/app/Moon.tsx +18 -0
  42. package/src/icons/app/Sun.tsx +18 -0
  43. package/src/icons/app/index.ts +2 -0
  44. package/src/icons/src/app/moon.svg +3 -0
  45. package/src/icons/src/app/sun.svg +3 -0
  46. package/src/stories/BarHeader.stories.tsx +80 -1
  47. package/src/stories/MultiPageSheet.stories.tsx +331 -0
@@ -3,7 +3,13 @@ import React from "react";
3
3
 
4
4
  import { ChatBubbleBottomCenterTextIcon } from "@sparkle/icons/app";
5
5
 
6
- import { BarHeader, Page } from "../index_with_tw_base";
6
+ import {
7
+ BarHeader,
8
+ Page,
9
+ ResizableHandle,
10
+ ResizablePanel,
11
+ ResizablePanelGroup,
12
+ } from "../index_with_tw_base";
7
13
 
8
14
  const meta = {
9
15
  title: "Modules/BarHeader",
@@ -183,3 +189,76 @@ export const BasicBarHeaderValidateSaveDisabledWithTooltip = () => (
183
189
  </div>
184
190
  </div>
185
191
  );
192
+
193
+ export const DefaultVariantInPanel = () => {
194
+ const [isSaving, setIsSaving] = React.useState(false);
195
+
196
+ return (
197
+ <div className="s-h-full s-w-full">
198
+ <ResizablePanelGroup direction="horizontal" className="s-h-full s-w-full">
199
+ <ResizablePanel defaultSize={70} minSize={30}>
200
+ <div className="s-flex s-h-full s-flex-col s-bg-white s-shadow-sm">
201
+ <BarHeader
202
+ variant="default"
203
+ title="Agent Builder"
204
+ rightActions={
205
+ <BarHeader.ButtonBar
206
+ variant="validate"
207
+ isSaving={isSaving}
208
+ onCancel={() => alert("Cancelled!")}
209
+ onSave={() => {
210
+ setIsSaving(true);
211
+ setTimeout(() => {
212
+ setIsSaving(false);
213
+ alert("Saved!");
214
+ }, 2000);
215
+ }}
216
+ />
217
+ }
218
+ />
219
+ <div className="s-flex-1 s-overflow-y-auto s-p-4">
220
+ <Page.Header
221
+ title="Left Panel Content"
222
+ icon={ChatBubbleBottomCenterTextIcon}
223
+ />
224
+ <p className="s-text-sm s-text-gray-600">
225
+ This demonstrates the "default" variant of BarHeader that is
226
+ contained within its parent container, perfect for panels and
227
+ sidebars. This panel uses ResizablePanelGroup like
228
+ AgentBuilderLayout.
229
+ </p>
230
+ </div>
231
+ </div>
232
+ </ResizablePanel>
233
+
234
+ <ResizableHandle />
235
+
236
+ <ResizablePanel defaultSize={30} minSize={20}>
237
+ <div className="s-flex s-h-full s-flex-col s-bg-white s-shadow-sm">
238
+ <BarHeader
239
+ variant="default"
240
+ title="Preview Panel"
241
+ rightActions={
242
+ <BarHeader.ButtonBar
243
+ variant="close"
244
+ onClose={() => alert("Closed!")}
245
+ />
246
+ }
247
+ />
248
+ <div className="s-flex-1 s-overflow-y-auto s-p-4">
249
+ <Page.Header
250
+ title="Right Panel Content"
251
+ icon={ChatBubbleBottomCenterTextIcon}
252
+ />
253
+ <p className="s-text-sm s-text-gray-600">
254
+ Notice how each BarHeader is scoped to its own panel width,
255
+ unlike the "full" variant which would span the entire viewport
256
+ width. You can resize this panel!
257
+ </p>
258
+ </div>
259
+ </div>
260
+ </ResizablePanel>
261
+ </ResizablePanelGroup>
262
+ </div>
263
+ );
264
+ };
@@ -0,0 +1,331 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import React, { useState } from "react";
3
+
4
+ import { Button } from "@sparkle/components/Button";
5
+ import {
6
+ MultiPageSheet,
7
+ MultiPageSheetContent,
8
+ type MultiPageSheetPage,
9
+ MultiPageSheetTrigger,
10
+ } from "@sparkle/components/MultiPageSheet";
11
+ import { Cog6ToothIcon, DocumentTextIcon, UserIcon } from "@sparkle/icons/app";
12
+
13
+ const meta: Meta<typeof MultiPageSheetContent> = {
14
+ title: "Primitives/MultiPageSheet",
15
+ component: MultiPageSheetContent,
16
+ };
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ const samplePages: MultiPageSheetPage[] = [
22
+ {
23
+ id: "profile",
24
+ title: "User Profile",
25
+ description: "Manage your personal information",
26
+ icon: UserIcon,
27
+ content: (
28
+ <div className="s-space-y-4">
29
+ <div>
30
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">
31
+ Personal Information
32
+ </h3>
33
+ <p className="s-text-sm s-text-muted-foreground">
34
+ Update your profile details and preferences.
35
+ </p>
36
+ </div>
37
+ <div className="s-space-y-3">
38
+ <div>
39
+ <label className="s-text-sm s-font-medium">Full Name</label>
40
+ <input
41
+ type="text"
42
+ className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
43
+ placeholder="John Doe"
44
+ />
45
+ </div>
46
+ <div>
47
+ <label className="s-text-sm s-font-medium">Email</label>
48
+ <input
49
+ type="email"
50
+ className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
51
+ placeholder="john@example.com"
52
+ />
53
+ </div>
54
+ </div>
55
+ </div>
56
+ ),
57
+ },
58
+ {
59
+ id: "documents",
60
+ title: "Documents",
61
+ description: "Manage your uploaded files",
62
+ icon: DocumentTextIcon,
63
+ content: (
64
+ <div className="s-space-y-4">
65
+ <div>
66
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">File Management</h3>
67
+ <p className="s-text-sm s-text-muted-foreground">
68
+ Upload, organize, and manage your documents.
69
+ </p>
70
+ </div>
71
+ <div className="s-space-y-2">
72
+ <div className="s-flex s-items-center s-justify-between s-rounded-md s-border s-p-3">
73
+ <span className="s-text-sm">document1.pdf</span>
74
+ <Button label="Download" size="sm" variant="outline" />
75
+ </div>
76
+ <div className="s-flex s-items-center s-justify-between s-rounded-md s-border s-p-3">
77
+ <span className="s-text-sm">report.docx</span>
78
+ <Button label="Download" size="sm" variant="outline" />
79
+ </div>
80
+ </div>
81
+ </div>
82
+ ),
83
+ },
84
+ {
85
+ id: "settings",
86
+ title: "Settings",
87
+ description: "Configure your preferences",
88
+ icon: Cog6ToothIcon,
89
+ content: (
90
+ <div className="s-space-y-4">
91
+ <div>
92
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">
93
+ Application Settings
94
+ </h3>
95
+ <p className="s-text-sm s-text-muted-foreground">
96
+ Customize your experience and notification preferences.
97
+ </p>
98
+ </div>
99
+ <div className="s-space-y-3">
100
+ <div className="s-flex s-items-center s-justify-between">
101
+ <span className="s-text-sm">Email notifications</span>
102
+ <input type="checkbox" className="s-rounded" defaultChecked />
103
+ </div>
104
+ <div className="s-flex s-items-center s-justify-between">
105
+ <span className="s-text-sm">Dark mode</span>
106
+ <input type="checkbox" className="s-rounded" />
107
+ </div>
108
+ <div className="s-flex s-items-center s-justify-between">
109
+ <span className="s-text-sm">Auto-save</span>
110
+ <input type="checkbox" className="s-rounded" defaultChecked />
111
+ </div>
112
+ </div>
113
+ </div>
114
+ ),
115
+ },
116
+ ];
117
+
118
+ const MultiPageSheetDemo = () => {
119
+ const [currentPageId, setCurrentPageId] = useState("profile");
120
+
121
+ const handleSave = () => {
122
+ alert("Changes saved!");
123
+ };
124
+
125
+ return (
126
+ <MultiPageSheet>
127
+ <MultiPageSheetTrigger asChild>
128
+ <Button label="Open Multi-Page Sheet" />
129
+ </MultiPageSheetTrigger>
130
+ <MultiPageSheetContent
131
+ pages={samplePages}
132
+ currentPageId={currentPageId}
133
+ onPageChange={setCurrentPageId}
134
+ size="lg"
135
+ onSave={handleSave}
136
+ />
137
+ </MultiPageSheet>
138
+ );
139
+ };
140
+
141
+ export const Default: Story = {
142
+ render: () => <MultiPageSheetDemo />,
143
+ };
144
+
145
+ export const InteractiveContent: Story = {
146
+ render: () => {
147
+ const [currentPageId, setCurrentPageId] = useState("step1");
148
+ const [formData, setFormData] = useState({
149
+ name: "",
150
+ email: "",
151
+ selectedFile: "",
152
+ notifications: false,
153
+ });
154
+
155
+ const handleSave = () => {
156
+ alert(`Setup completed! Data: ${JSON.stringify(formData, null, 2)}`);
157
+ };
158
+
159
+ const interactivePages: MultiPageSheetPage[] = [
160
+ {
161
+ id: "step1",
162
+ title: "Personal Info",
163
+ description: "Enter your basic information",
164
+ icon: UserIcon,
165
+ content: (
166
+ <div className="s-space-y-4">
167
+ <div>
168
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">
169
+ Let's get started
170
+ </h3>
171
+ <p className="s-text-sm s-text-muted-foreground">
172
+ Fill in your details to continue to the next step.
173
+ </p>
174
+ </div>
175
+ <div className="s-space-y-3">
176
+ <div>
177
+ <label className="s-text-sm s-font-medium">Full Name *</label>
178
+ <input
179
+ type="text"
180
+ className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
181
+ placeholder="Enter your name"
182
+ value={formData.name}
183
+ onChange={(e) =>
184
+ setFormData({ ...formData, name: e.target.value })
185
+ }
186
+ />
187
+ </div>
188
+ <div>
189
+ <label className="s-text-sm s-font-medium">Email *</label>
190
+ <input
191
+ type="email"
192
+ className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
193
+ placeholder="Enter your email"
194
+ value={formData.email}
195
+ onChange={(e) =>
196
+ setFormData({ ...formData, email: e.target.value })
197
+ }
198
+ />
199
+ </div>
200
+ <div className="s-pt-2">
201
+ <Button
202
+ label="Continue to File Selection"
203
+ variant="primary"
204
+ size="sm"
205
+ disabled={!formData.name || !formData.email}
206
+ onClick={() => setCurrentPageId("step2")}
207
+ />
208
+ </div>
209
+ </div>
210
+ </div>
211
+ ),
212
+ },
213
+ {
214
+ id: "step2",
215
+ title: "File Selection",
216
+ description: "Choose your files",
217
+ icon: DocumentTextIcon,
218
+ content: (
219
+ <div className="s-space-y-4">
220
+ <div>
221
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">
222
+ Select a file to work with
223
+ </h3>
224
+ <p className="s-text-sm s-text-muted-foreground">
225
+ Choose from the available files below.
226
+ </p>
227
+ </div>
228
+ <div className="s-space-y-2">
229
+ {[
230
+ "project-proposal.pdf",
231
+ "budget-2024.xlsx",
232
+ "meeting-notes.docx",
233
+ ].map((file) => (
234
+ <div
235
+ key={file}
236
+ className={`s-flex s-cursor-pointer s-items-center s-justify-between s-rounded-md s-border s-p-3 s-transition-colors hover:s-bg-gray-50 ${
237
+ formData.selectedFile === file
238
+ ? "s-border-blue-300 s-bg-blue-50"
239
+ : ""
240
+ }`}
241
+ onClick={() =>
242
+ setFormData({ ...formData, selectedFile: file })
243
+ }
244
+ >
245
+ <span className="s-text-sm">{file}</span>
246
+ <div className="s-flex s-items-center s-gap-2">
247
+ <input
248
+ type="radio"
249
+ checked={formData.selectedFile === file}
250
+ readOnly
251
+ className="s-pointer-events-none"
252
+ />
253
+ </div>
254
+ </div>
255
+ ))}
256
+ </div>
257
+ {formData.selectedFile && (
258
+ <div className="s-pt-2">
259
+ <Button
260
+ label="Continue to Settings"
261
+ variant="primary"
262
+ size="sm"
263
+ onClick={() => setCurrentPageId("step3")}
264
+ />
265
+ </div>
266
+ )}
267
+ </div>
268
+ ),
269
+ },
270
+ {
271
+ id: "step3",
272
+ title: "Final Settings",
273
+ description: "Configure your preferences",
274
+ icon: Cog6ToothIcon,
275
+ content: (
276
+ <div className="s-space-y-4">
277
+ <div>
278
+ <h3 className="s-mb-2 s-text-lg s-font-semibold">Almost done!</h3>
279
+ <p className="s-text-sm s-text-muted-foreground">
280
+ Configure your final preferences and complete the setup.
281
+ </p>
282
+ </div>
283
+ <div className="s-space-y-3">
284
+ <div className="s-flex s-items-center s-justify-between">
285
+ <span className="s-text-sm">Enable email notifications</span>
286
+ <input
287
+ type="checkbox"
288
+ className="s-rounded"
289
+ checked={formData.notifications}
290
+ onChange={(e) =>
291
+ setFormData({
292
+ ...formData,
293
+ notifications: e.target.checked,
294
+ })
295
+ }
296
+ />
297
+ </div>
298
+ <div className="s-rounded-md s-bg-gray-50 s-p-3">
299
+ <h4 className="s-mb-2 s-text-sm s-font-medium">Summary</h4>
300
+ <div className="s-space-y-1 s-text-xs s-text-gray-600">
301
+ <div>Name: {formData.name}</div>
302
+ <div>Email: {formData.email}</div>
303
+ <div>Selected File: {formData.selectedFile}</div>
304
+ <div>
305
+ Notifications:{" "}
306
+ {formData.notifications ? "Enabled" : "Disabled"}
307
+ </div>
308
+ </div>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ ),
313
+ },
314
+ ];
315
+
316
+ return (
317
+ <MultiPageSheet>
318
+ <MultiPageSheetTrigger asChild>
319
+ <Button label="Open Interactive Setup" />
320
+ </MultiPageSheetTrigger>
321
+ <MultiPageSheetContent
322
+ pages={interactivePages}
323
+ currentPageId={currentPageId}
324
+ onPageChange={setCurrentPageId}
325
+ size="lg"
326
+ onSave={handleSave}
327
+ />
328
+ </MultiPageSheet>
329
+ );
330
+ },
331
+ };