@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.
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/BarHeader.d.ts +6 -2
- package/dist/esm/components/BarHeader.d.ts.map +1 -1
- package/dist/esm/components/BarHeader.js +18 -7
- package/dist/esm/components/BarHeader.js.map +1 -1
- package/dist/esm/components/MultiPageSheet.d.ts +30 -0
- package/dist/esm/components/MultiPageSheet.d.ts.map +1 -0
- package/dist/esm/components/MultiPageSheet.js +59 -0
- package/dist/esm/components/MultiPageSheet.js.map +1 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/icons/app/Moon.d.ts +5 -0
- package/dist/esm/icons/app/Moon.d.ts.map +1 -0
- package/dist/esm/icons/app/Moon.js +6 -0
- package/dist/esm/icons/app/Moon.js.map +1 -0
- package/dist/esm/icons/app/Sun.d.ts +5 -0
- package/dist/esm/icons/app/Sun.d.ts.map +1 -0
- package/dist/esm/icons/app/Sun.js +6 -0
- package/dist/esm/icons/app/Sun.js.map +1 -0
- package/dist/esm/icons/app/index.d.ts +2 -0
- package/dist/esm/icons/app/index.d.ts.map +1 -1
- package/dist/esm/icons/app/index.js +2 -0
- package/dist/esm/icons/app/index.js.map +1 -1
- package/dist/esm/icons/src/app/moon.svg +3 -0
- package/dist/esm/icons/src/app/sun.svg +3 -0
- package/dist/esm/stories/BarHeader.stories.d.ts +1 -0
- package/dist/esm/stories/BarHeader.stories.d.ts.map +1 -1
- package/dist/esm/stories/BarHeader.stories.js +25 -1
- package/dist/esm/stories/BarHeader.stories.js.map +1 -1
- package/dist/esm/stories/MultiPageSheet.stories.d.ts +8 -0
- package/dist/esm/stories/MultiPageSheet.stories.d.ts.map +1 -0
- package/dist/esm/stories/MultiPageSheet.stories.js +179 -0
- package/dist/esm/stories/MultiPageSheet.stories.js.map +1 -0
- package/dist/sparkle.css +13 -0
- package/package.json +1 -1
- package/src/components/BarHeader.tsx +25 -15
- package/src/components/MultiPageSheet.tsx +202 -0
- package/src/components/index.ts +8 -0
- package/src/icons/app/Moon.tsx +18 -0
- package/src/icons/app/Sun.tsx +18 -0
- package/src/icons/app/index.ts +2 -0
- package/src/icons/src/app/moon.svg +3 -0
- package/src/icons/src/app/sun.svg +3 -0
- package/src/stories/BarHeader.stories.tsx +80 -1
- 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 {
|
|
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
|
+
};
|