@dust-tt/sparkle 0.2.557 → 0.2.558-rc-1
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/MultiPageDialog.d.ts +18 -7
- package/dist/esm/components/MultiPageDialog.d.ts.map +1 -1
- package/dist/esm/components/MultiPageDialog.js +16 -21
- package/dist/esm/components/MultiPageDialog.js.map +1 -1
- package/dist/esm/components/index.d.ts +2 -2
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/stories/MultiPageDialog.stories.d.ts +1 -0
- package/dist/esm/stories/MultiPageDialog.stories.d.ts.map +1 -1
- package/dist/esm/stories/MultiPageDialog.stories.js +227 -18
- package/dist/esm/stories/MultiPageDialog.stories.js.map +1 -1
- package/dist/sparkle.css +10 -0
- package/package.json +1 -1
- package/src/components/MultiPageDialog.tsx +56 -48
- package/src/components/index.ts +2 -0
- package/src/stories/MultiPageDialog.stories.tsx +307 -33
|
@@ -117,13 +117,19 @@ const samplePages: MultiPageDialogPage[] = [
|
|
|
117
117
|
|
|
118
118
|
const MultiPageDialogDemo = () => {
|
|
119
119
|
const [currentPageId, setCurrentPageId] = useState("profile");
|
|
120
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
120
121
|
|
|
121
122
|
const handleSave = () => {
|
|
122
123
|
alert("Changes saved!");
|
|
124
|
+
setIsOpen(false);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const handleCancel = () => {
|
|
128
|
+
setIsOpen(false);
|
|
123
129
|
};
|
|
124
130
|
|
|
125
131
|
return (
|
|
126
|
-
<MultiPageDialog>
|
|
132
|
+
<MultiPageDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
127
133
|
<MultiPageDialogTrigger asChild>
|
|
128
134
|
<Button label="Open Multi-Page Dialog" />
|
|
129
135
|
</MultiPageDialogTrigger>
|
|
@@ -132,7 +138,16 @@ const MultiPageDialogDemo = () => {
|
|
|
132
138
|
currentPageId={currentPageId}
|
|
133
139
|
onPageChange={setCurrentPageId}
|
|
134
140
|
size="xl"
|
|
135
|
-
|
|
141
|
+
leftButton={{
|
|
142
|
+
label: "Cancel",
|
|
143
|
+
variant: "outline",
|
|
144
|
+
onClick: handleCancel,
|
|
145
|
+
}}
|
|
146
|
+
rightButton={{
|
|
147
|
+
label: "Save Changes",
|
|
148
|
+
variant: "primary",
|
|
149
|
+
onClick: handleSave,
|
|
150
|
+
}}
|
|
136
151
|
/>
|
|
137
152
|
</MultiPageDialog>
|
|
138
153
|
);
|
|
@@ -142,9 +157,150 @@ export const Default: Story = {
|
|
|
142
157
|
render: () => <MultiPageDialogDemo />,
|
|
143
158
|
};
|
|
144
159
|
|
|
160
|
+
// Simple two-button example (like your screenshot)
|
|
161
|
+
export const SimpleToolDialog: Story = {
|
|
162
|
+
render: () => {
|
|
163
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
164
|
+
const [selectedTools, setSelectedTools] = useState<string[]>([]);
|
|
165
|
+
|
|
166
|
+
const handleAddTools = () => {
|
|
167
|
+
alert(
|
|
168
|
+
`Adding ${selectedTools.length} tools: ${selectedTools.join(", ")}`
|
|
169
|
+
);
|
|
170
|
+
setIsOpen(false);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const handleCancel = () => {
|
|
174
|
+
setSelectedTools([]);
|
|
175
|
+
setIsOpen(false);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const toggleTool = (tool: string) => {
|
|
179
|
+
setSelectedTools((prev) =>
|
|
180
|
+
prev.includes(tool) ? prev.filter((t) => t !== tool) : [...prev, tool]
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const toolPages: MultiPageDialogPage[] = [
|
|
185
|
+
{
|
|
186
|
+
id: "tool-selection",
|
|
187
|
+
title: "Add tools",
|
|
188
|
+
content: (
|
|
189
|
+
<div className="s-space-y-6">
|
|
190
|
+
<div className="s-space-y-4">
|
|
191
|
+
<h3 className="s-text-lg s-font-semibold">Capabilities</h3>
|
|
192
|
+
<div className="s-grid s-grid-cols-2 s-gap-3">
|
|
193
|
+
{[
|
|
194
|
+
{
|
|
195
|
+
name: "Image generation",
|
|
196
|
+
desc: "Generate images using natural language",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "Run agent",
|
|
200
|
+
desc: "Run a child agent (agent as tool)",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "Interactive content",
|
|
204
|
+
desc: "Generate interactive content",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: "Agent memory",
|
|
208
|
+
desc: "Store and recall information",
|
|
209
|
+
},
|
|
210
|
+
].map((tool) => (
|
|
211
|
+
<div
|
|
212
|
+
key={tool.name}
|
|
213
|
+
className={`s-cursor-pointer s-rounded-lg s-border s-p-4 s-transition-colors hover:s-bg-gray-50 ${
|
|
214
|
+
selectedTools.includes(tool.name)
|
|
215
|
+
? "s-border-blue-300 s-bg-blue-50"
|
|
216
|
+
: "s-border-gray-200"
|
|
217
|
+
}`}
|
|
218
|
+
onClick={() => toggleTool(tool.name)}
|
|
219
|
+
>
|
|
220
|
+
<div className="s-flex s-items-start s-justify-between">
|
|
221
|
+
<div>
|
|
222
|
+
<h4 className="s-font-medium">{tool.name}</h4>
|
|
223
|
+
<p className="s-text-sm s-text-gray-600">{tool.desc}</p>
|
|
224
|
+
</div>
|
|
225
|
+
{selectedTools.includes(tool.name) && (
|
|
226
|
+
<span className="s-rounded s-bg-green-100 s-px-2 s-py-1 s-text-xs s-text-green-700">
|
|
227
|
+
ADDED
|
|
228
|
+
</span>
|
|
229
|
+
)}
|
|
230
|
+
</div>
|
|
231
|
+
{!selectedTools.includes(tool.name) && (
|
|
232
|
+
<button className="s-mt-2 s-text-sm s-text-blue-600 hover:s-text-blue-700">
|
|
233
|
+
+ Add
|
|
234
|
+
</button>
|
|
235
|
+
)}
|
|
236
|
+
</div>
|
|
237
|
+
))}
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
{selectedTools.length > 0 && (
|
|
242
|
+
<div className="s-space-y-3">
|
|
243
|
+
<h4 className="s-font-medium">Added tools</h4>
|
|
244
|
+
<div className="s-flex s-flex-wrap s-gap-2">
|
|
245
|
+
{selectedTools.map((tool) => (
|
|
246
|
+
<span
|
|
247
|
+
key={tool}
|
|
248
|
+
className="s-flex s-items-center s-gap-1 s-rounded s-bg-gray-100 s-px-3 s-py-1 s-text-sm"
|
|
249
|
+
>
|
|
250
|
+
{tool}
|
|
251
|
+
<button
|
|
252
|
+
onClick={(e) => {
|
|
253
|
+
e.stopPropagation();
|
|
254
|
+
toggleTool(tool);
|
|
255
|
+
}}
|
|
256
|
+
className="s-ml-1 s-text-gray-500 hover:s-text-gray-700"
|
|
257
|
+
>
|
|
258
|
+
×
|
|
259
|
+
</button>
|
|
260
|
+
</span>
|
|
261
|
+
))}
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
)}
|
|
265
|
+
</div>
|
|
266
|
+
),
|
|
267
|
+
},
|
|
268
|
+
];
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<MultiPageDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
272
|
+
<MultiPageDialogTrigger asChild>
|
|
273
|
+
<Button label="Add tools" />
|
|
274
|
+
</MultiPageDialogTrigger>
|
|
275
|
+
<MultiPageDialogContent
|
|
276
|
+
pages={toolPages}
|
|
277
|
+
currentPageId="tool-selection"
|
|
278
|
+
onPageChange={() => {}}
|
|
279
|
+
size="xl"
|
|
280
|
+
leftButton={{
|
|
281
|
+
label: "Cancel",
|
|
282
|
+
variant: "outline",
|
|
283
|
+
onClick: handleCancel,
|
|
284
|
+
}}
|
|
285
|
+
rightButton={{
|
|
286
|
+
label:
|
|
287
|
+
selectedTools.length > 0
|
|
288
|
+
? `Add ${selectedTools.length} tool${selectedTools.length > 1 ? "s" : ""}`
|
|
289
|
+
: "Add tools",
|
|
290
|
+
variant: "primary",
|
|
291
|
+
disabled: selectedTools.length === 0,
|
|
292
|
+
onClick: handleAddTools,
|
|
293
|
+
}}
|
|
294
|
+
/>
|
|
295
|
+
</MultiPageDialog>
|
|
296
|
+
);
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
|
|
145
300
|
export const InteractiveContent: Story = {
|
|
146
301
|
render: () => {
|
|
147
302
|
const [currentPageId, setCurrentPageId] = useState("step1");
|
|
303
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
148
304
|
const [formData, setFormData] = useState({
|
|
149
305
|
name: "",
|
|
150
306
|
email: "",
|
|
@@ -154,8 +310,42 @@ export const InteractiveContent: Story = {
|
|
|
154
310
|
|
|
155
311
|
const handleSave = () => {
|
|
156
312
|
alert(`Setup completed! Data: ${JSON.stringify(formData, null, 2)}`);
|
|
313
|
+
setIsOpen(false);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const handleCancel = () => {
|
|
317
|
+
setIsOpen(false);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const handleNext = () => {
|
|
321
|
+
if (currentPageId === "step1") {
|
|
322
|
+
setCurrentPageId("step2");
|
|
323
|
+
} else if (currentPageId === "step2") {
|
|
324
|
+
setCurrentPageId("step3");
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const handlePrevious = () => {
|
|
329
|
+
if (currentPageId === "step3") {
|
|
330
|
+
setCurrentPageId("step2");
|
|
331
|
+
} else if (currentPageId === "step2") {
|
|
332
|
+
setCurrentPageId("step1");
|
|
333
|
+
}
|
|
157
334
|
};
|
|
158
335
|
|
|
336
|
+
const canProceed = () => {
|
|
337
|
+
if (currentPageId === "step1") {
|
|
338
|
+
return formData.name && formData.email;
|
|
339
|
+
}
|
|
340
|
+
if (currentPageId === "step2") {
|
|
341
|
+
return formData.selectedFile;
|
|
342
|
+
}
|
|
343
|
+
return true;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const isFirstPage = currentPageId === "step1";
|
|
347
|
+
const isLastPage = currentPageId === "step3";
|
|
348
|
+
|
|
159
349
|
const interactivePages: MultiPageDialogPage[] = [
|
|
160
350
|
{
|
|
161
351
|
id: "step1",
|
|
@@ -197,15 +387,6 @@ export const InteractiveContent: Story = {
|
|
|
197
387
|
}
|
|
198
388
|
/>
|
|
199
389
|
</div>
|
|
200
|
-
<div className="s-pt-2">
|
|
201
|
-
<Button
|
|
202
|
-
label="Continue to File Selection"
|
|
203
|
-
variant="primary"
|
|
204
|
-
size="md"
|
|
205
|
-
disabled={!formData.name || !formData.email}
|
|
206
|
-
onClick={() => setCurrentPageId("step2")}
|
|
207
|
-
/>
|
|
208
|
-
</div>
|
|
209
390
|
</div>
|
|
210
391
|
</div>
|
|
211
392
|
),
|
|
@@ -254,16 +435,6 @@ export const InteractiveContent: Story = {
|
|
|
254
435
|
</div>
|
|
255
436
|
))}
|
|
256
437
|
</div>
|
|
257
|
-
{formData.selectedFile && (
|
|
258
|
-
<div className="s-pt-2">
|
|
259
|
-
<Button
|
|
260
|
-
label="Continue to Settings"
|
|
261
|
-
variant="primary"
|
|
262
|
-
size="md"
|
|
263
|
-
onClick={() => setCurrentPageId("step3")}
|
|
264
|
-
/>
|
|
265
|
-
</div>
|
|
266
|
-
)}
|
|
267
438
|
</div>
|
|
268
439
|
),
|
|
269
440
|
},
|
|
@@ -314,7 +485,7 @@ export const InteractiveContent: Story = {
|
|
|
314
485
|
];
|
|
315
486
|
|
|
316
487
|
return (
|
|
317
|
-
<MultiPageDialog>
|
|
488
|
+
<MultiPageDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
318
489
|
<MultiPageDialogTrigger asChild>
|
|
319
490
|
<Button label="Open Interactive Setup" />
|
|
320
491
|
</MultiPageDialogTrigger>
|
|
@@ -323,7 +494,26 @@ export const InteractiveContent: Story = {
|
|
|
323
494
|
currentPageId={currentPageId}
|
|
324
495
|
onPageChange={setCurrentPageId}
|
|
325
496
|
size="lg"
|
|
326
|
-
|
|
497
|
+
leftButton={{
|
|
498
|
+
label: "Cancel",
|
|
499
|
+
variant: "outline",
|
|
500
|
+
onClick: handleCancel,
|
|
501
|
+
}}
|
|
502
|
+
centerButton={
|
|
503
|
+
!isFirstPage
|
|
504
|
+
? {
|
|
505
|
+
label: "Previous",
|
|
506
|
+
variant: "outline",
|
|
507
|
+
onClick: handlePrevious,
|
|
508
|
+
}
|
|
509
|
+
: undefined
|
|
510
|
+
}
|
|
511
|
+
rightButton={{
|
|
512
|
+
label: isLastPage ? "Complete Setup" : "Next",
|
|
513
|
+
variant: "primary",
|
|
514
|
+
disabled: !canProceed(),
|
|
515
|
+
onClick: isLastPage ? handleSave : handleNext,
|
|
516
|
+
}}
|
|
327
517
|
/>
|
|
328
518
|
</MultiPageDialog>
|
|
329
519
|
);
|
|
@@ -333,6 +523,7 @@ export const InteractiveContent: Story = {
|
|
|
333
523
|
export const WithConditionalNavigation: Story = {
|
|
334
524
|
render: () => {
|
|
335
525
|
const [currentPageId, setCurrentPageId] = useState("data-selection");
|
|
526
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
336
527
|
const [selectedItems, setSelectedItems] = useState<string[]>([]);
|
|
337
528
|
const [description, setDescription] = useState("");
|
|
338
529
|
|
|
@@ -340,8 +531,30 @@ export const WithConditionalNavigation: Story = {
|
|
|
340
531
|
alert(
|
|
341
532
|
`Configuration saved! Selected: ${selectedItems.join(", ")}, Description: ${description}`
|
|
342
533
|
);
|
|
534
|
+
setIsOpen(false);
|
|
343
535
|
};
|
|
344
536
|
|
|
537
|
+
const handleCancel = () => {
|
|
538
|
+
setIsOpen(false);
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
const handleNext = () => {
|
|
542
|
+
if (currentPageId === "data-selection") {
|
|
543
|
+
setCurrentPageId("description");
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
const handlePrevious = () => {
|
|
548
|
+
if (currentPageId === "description") {
|
|
549
|
+
setCurrentPageId("data-selection");
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const isFirstPage = currentPageId === "data-selection";
|
|
554
|
+
const isLastPage = currentPageId === "description";
|
|
555
|
+
const canProceedFromFirst = selectedItems.length > 0;
|
|
556
|
+
const canSave = description.trim().length > 0;
|
|
557
|
+
|
|
345
558
|
const conditionalPages: MultiPageDialogPage[] = [
|
|
346
559
|
{
|
|
347
560
|
id: "data-selection",
|
|
@@ -441,7 +654,7 @@ export const WithConditionalNavigation: Story = {
|
|
|
441
654
|
];
|
|
442
655
|
|
|
443
656
|
return (
|
|
444
|
-
<MultiPageDialog>
|
|
657
|
+
<MultiPageDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
445
658
|
<MultiPageDialogTrigger asChild>
|
|
446
659
|
<Button label="Open Configuration Wizard" />
|
|
447
660
|
</MultiPageDialogTrigger>
|
|
@@ -450,15 +663,37 @@ export const WithConditionalNavigation: Story = {
|
|
|
450
663
|
currentPageId={currentPageId}
|
|
451
664
|
onPageChange={setCurrentPageId}
|
|
452
665
|
size="lg"
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
666
|
+
leftButton={{
|
|
667
|
+
label: "Cancel",
|
|
668
|
+
variant: "outline",
|
|
669
|
+
onClick: handleCancel,
|
|
670
|
+
}}
|
|
671
|
+
centerButton={
|
|
672
|
+
!isFirstPage
|
|
673
|
+
? {
|
|
674
|
+
label: "Previous",
|
|
675
|
+
variant: "outline",
|
|
676
|
+
onClick: handlePrevious,
|
|
677
|
+
}
|
|
678
|
+
: undefined
|
|
457
679
|
}
|
|
458
|
-
|
|
680
|
+
rightButton={{
|
|
681
|
+
label: isLastPage ? "Save Configuration" : "Next",
|
|
682
|
+
variant: "primary",
|
|
683
|
+
disabled: isFirstPage ? !canProceedFromFirst : !canSave,
|
|
684
|
+
onClick: isLastPage ? handleSave : handleNext,
|
|
685
|
+
}}
|
|
459
686
|
footerContent={
|
|
460
|
-
<div className="s-
|
|
461
|
-
|
|
687
|
+
<div className="s-rounded s-bg-blue-50 s-px-3 s-py-2">
|
|
688
|
+
<p className="s-text-xs s-text-blue-700">
|
|
689
|
+
{selectedItems.length > 0 && (
|
|
690
|
+
<>
|
|
691
|
+
{selectedItems.length} data source
|
|
692
|
+
{selectedItems.length !== 1 ? "s" : ""} selected •{" "}
|
|
693
|
+
</>
|
|
694
|
+
)}
|
|
695
|
+
Step {isFirstPage ? "1" : "2"} of 2
|
|
696
|
+
</p>
|
|
462
697
|
</div>
|
|
463
698
|
}
|
|
464
699
|
/>
|
|
@@ -470,11 +705,32 @@ export const WithConditionalNavigation: Story = {
|
|
|
470
705
|
export const ScrollableContent: Story = {
|
|
471
706
|
render: () => {
|
|
472
707
|
const [currentPageId, setCurrentPageId] = useState("long-form");
|
|
708
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
473
709
|
|
|
474
710
|
const handleSave = () => {
|
|
475
711
|
alert("Long form submitted!");
|
|
712
|
+
setIsOpen(false);
|
|
476
713
|
};
|
|
477
714
|
|
|
715
|
+
const handleCancel = () => {
|
|
716
|
+
setIsOpen(false);
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
const handleNext = () => {
|
|
720
|
+
if (currentPageId === "long-form") {
|
|
721
|
+
setCurrentPageId("summary");
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
const handlePrevious = () => {
|
|
726
|
+
if (currentPageId === "summary") {
|
|
727
|
+
setCurrentPageId("long-form");
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
const isFirstPage = currentPageId === "long-form";
|
|
732
|
+
const isLastPage = currentPageId === "summary";
|
|
733
|
+
|
|
478
734
|
const scrollablePages: MultiPageDialogPage[] = [
|
|
479
735
|
{
|
|
480
736
|
id: "long-form",
|
|
@@ -575,7 +831,7 @@ export const ScrollableContent: Story = {
|
|
|
575
831
|
];
|
|
576
832
|
|
|
577
833
|
return (
|
|
578
|
-
<MultiPageDialog>
|
|
834
|
+
<MultiPageDialog open={isOpen} onOpenChange={setIsOpen}>
|
|
579
835
|
<MultiPageDialogTrigger asChild>
|
|
580
836
|
<Button label="Open Scrollable Content Dialog" />
|
|
581
837
|
</MultiPageDialogTrigger>
|
|
@@ -584,7 +840,25 @@ export const ScrollableContent: Story = {
|
|
|
584
840
|
currentPageId={currentPageId}
|
|
585
841
|
onPageChange={setCurrentPageId}
|
|
586
842
|
size="lg"
|
|
587
|
-
|
|
843
|
+
leftButton={{
|
|
844
|
+
label: "Cancel",
|
|
845
|
+
variant: "outline",
|
|
846
|
+
onClick: handleCancel,
|
|
847
|
+
}}
|
|
848
|
+
centerButton={
|
|
849
|
+
!isFirstPage
|
|
850
|
+
? {
|
|
851
|
+
label: "Previous",
|
|
852
|
+
variant: "outline",
|
|
853
|
+
onClick: handlePrevious,
|
|
854
|
+
}
|
|
855
|
+
: undefined
|
|
856
|
+
}
|
|
857
|
+
rightButton={{
|
|
858
|
+
label: isLastPage ? "Submit Form" : "Next",
|
|
859
|
+
variant: "primary",
|
|
860
|
+
onClick: isLastPage ? handleSave : handleNext,
|
|
861
|
+
}}
|
|
588
862
|
/>
|
|
589
863
|
</MultiPageDialog>
|
|
590
864
|
);
|