@dust-tt/sparkle 0.2.552 → 0.2.553-rc-2
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 +34 -0
- package/dist/esm/components/MultiPageDialog.d.ts.map +1 -0
- package/dist/esm/components/MultiPageDialog.js +116 -0
- package/dist/esm/components/MultiPageDialog.js.map +1 -0
- package/dist/esm/components/MultiPageSheet.d.ts +1 -0
- package/dist/esm/components/MultiPageSheet.d.ts.map +1 -1
- package/dist/esm/components/MultiPageSheet.js +2 -2
- package/dist/esm/components/MultiPageSheet.js.map +1 -1
- package/dist/esm/components/markdown/Markdown.js +6 -6
- package/dist/esm/components/markdown/Markdown.js.map +1 -1
- package/dist/esm/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/esm/stories/Markdown.stories.js +1 -1
- package/dist/esm/stories/Markdown.stories.js.map +1 -1
- package/dist/esm/stories/MultiPageDialog.stories.d.ts +10 -0
- package/dist/esm/stories/MultiPageDialog.stories.d.ts.map +1 -0
- package/dist/esm/stories/MultiPageDialog.stories.js +301 -0
- package/dist/esm/stories/MultiPageDialog.stories.js.map +1 -0
- package/dist/sparkle.css +47 -0
- package/package.json +1 -1
- package/src/components/MultiPageDialog.tsx +295 -0
- package/src/components/MultiPageSheet.tsx +3 -1
- package/src/components/markdown/Markdown.tsx +6 -6
- package/src/stories/Markdown.stories.tsx +7 -0
- package/src/stories/MultiPageDialog.stories.tsx +592 -0
|
@@ -0,0 +1,592 @@
|
|
|
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
|
+
MultiPageDialog,
|
|
7
|
+
MultiPageDialogContent,
|
|
8
|
+
type MultiPageDialogPage,
|
|
9
|
+
MultiPageDialogTrigger,
|
|
10
|
+
} from "@sparkle/components/MultiPageDialog";
|
|
11
|
+
import { Cog6ToothIcon, DocumentTextIcon, UserIcon } from "@sparkle/icons/app";
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof MultiPageDialogContent> = {
|
|
14
|
+
title: "Primitives/MultiPageDialog",
|
|
15
|
+
component: MultiPageDialogContent,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
const samplePages: MultiPageDialogPage[] = [
|
|
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 MultiPageDialogDemo = () => {
|
|
119
|
+
const [currentPageId, setCurrentPageId] = useState("profile");
|
|
120
|
+
|
|
121
|
+
const handleSave = () => {
|
|
122
|
+
alert("Changes saved!");
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<MultiPageDialog>
|
|
127
|
+
<MultiPageDialogTrigger asChild>
|
|
128
|
+
<Button label="Open Multi-Page Dialog" />
|
|
129
|
+
</MultiPageDialogTrigger>
|
|
130
|
+
<MultiPageDialogContent
|
|
131
|
+
pages={samplePages}
|
|
132
|
+
currentPageId={currentPageId}
|
|
133
|
+
onPageChange={setCurrentPageId}
|
|
134
|
+
size="xl"
|
|
135
|
+
onSave={handleSave}
|
|
136
|
+
/>
|
|
137
|
+
</MultiPageDialog>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const Default: Story = {
|
|
142
|
+
render: () => <MultiPageDialogDemo />,
|
|
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: MultiPageDialogPage[] = [
|
|
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="md"
|
|
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="md"
|
|
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
|
+
<MultiPageDialog>
|
|
318
|
+
<MultiPageDialogTrigger asChild>
|
|
319
|
+
<Button label="Open Interactive Setup" />
|
|
320
|
+
</MultiPageDialogTrigger>
|
|
321
|
+
<MultiPageDialogContent
|
|
322
|
+
pages={interactivePages}
|
|
323
|
+
currentPageId={currentPageId}
|
|
324
|
+
onPageChange={setCurrentPageId}
|
|
325
|
+
size="lg"
|
|
326
|
+
onSave={handleSave}
|
|
327
|
+
/>
|
|
328
|
+
</MultiPageDialog>
|
|
329
|
+
);
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
export const WithConditionalNavigation: Story = {
|
|
334
|
+
render: () => {
|
|
335
|
+
const [currentPageId, setCurrentPageId] = useState("data-selection");
|
|
336
|
+
const [selectedItems, setSelectedItems] = useState<string[]>([]);
|
|
337
|
+
const [description, setDescription] = useState("");
|
|
338
|
+
|
|
339
|
+
const handleSave = () => {
|
|
340
|
+
alert(
|
|
341
|
+
`Configuration saved! Selected: ${selectedItems.join(", ")}, Description: ${description}`
|
|
342
|
+
);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const conditionalPages: MultiPageDialogPage[] = [
|
|
346
|
+
{
|
|
347
|
+
id: "data-selection",
|
|
348
|
+
title: "Select Data Sources",
|
|
349
|
+
description: "Choose which data sources to include",
|
|
350
|
+
icon: DocumentTextIcon,
|
|
351
|
+
content: (
|
|
352
|
+
<div className="s-space-y-4">
|
|
353
|
+
<div>
|
|
354
|
+
<h3 className="s-mb-2 s-text-lg s-font-semibold">
|
|
355
|
+
Available Data Sources
|
|
356
|
+
</h3>
|
|
357
|
+
<p className="s-text-sm s-text-muted-foreground">
|
|
358
|
+
Select at least one data source to proceed to the next step.
|
|
359
|
+
</p>
|
|
360
|
+
</div>
|
|
361
|
+
<div className="s-space-y-2">
|
|
362
|
+
{[
|
|
363
|
+
"Company Database",
|
|
364
|
+
"Customer Files",
|
|
365
|
+
"Analytics Data",
|
|
366
|
+
"Reports Archive",
|
|
367
|
+
].map((item) => (
|
|
368
|
+
<div
|
|
369
|
+
key={item}
|
|
370
|
+
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 ${
|
|
371
|
+
selectedItems.includes(item)
|
|
372
|
+
? "s-border-blue-300 s-bg-blue-50"
|
|
373
|
+
: ""
|
|
374
|
+
}`}
|
|
375
|
+
onClick={() => {
|
|
376
|
+
if (selectedItems.includes(item)) {
|
|
377
|
+
setSelectedItems(selectedItems.filter((i) => i !== item));
|
|
378
|
+
} else {
|
|
379
|
+
setSelectedItems([...selectedItems, item]);
|
|
380
|
+
}
|
|
381
|
+
}}
|
|
382
|
+
>
|
|
383
|
+
<span className="s-text-sm">{item}</span>
|
|
384
|
+
<input
|
|
385
|
+
type="checkbox"
|
|
386
|
+
checked={selectedItems.includes(item)}
|
|
387
|
+
readOnly
|
|
388
|
+
className="s-pointer-events-none"
|
|
389
|
+
/>
|
|
390
|
+
</div>
|
|
391
|
+
))}
|
|
392
|
+
</div>
|
|
393
|
+
{selectedItems.length > 0 && (
|
|
394
|
+
<div className="s-rounded-md s-border s-bg-blue-50 s-p-3">
|
|
395
|
+
<p className="s-text-sm s-text-blue-700">
|
|
396
|
+
{selectedItems.length} data source
|
|
397
|
+
{selectedItems.length !== 1 ? "s" : ""} selected
|
|
398
|
+
</p>
|
|
399
|
+
</div>
|
|
400
|
+
)}
|
|
401
|
+
</div>
|
|
402
|
+
),
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
id: "description",
|
|
406
|
+
title: "Add Description",
|
|
407
|
+
description: "Describe your configuration",
|
|
408
|
+
icon: Cog6ToothIcon,
|
|
409
|
+
content: (
|
|
410
|
+
<div className="s-space-y-4">
|
|
411
|
+
<div>
|
|
412
|
+
<h3 className="s-mb-2 s-text-lg s-font-semibold">
|
|
413
|
+
Configuration Details
|
|
414
|
+
</h3>
|
|
415
|
+
<p className="s-text-sm s-text-muted-foreground">
|
|
416
|
+
Add a description for your selected data sources.
|
|
417
|
+
</p>
|
|
418
|
+
</div>
|
|
419
|
+
<div className="s-rounded-md s-border s-bg-blue-50 s-p-3">
|
|
420
|
+
<p className="s-text-sm s-text-blue-700">
|
|
421
|
+
Selected: {selectedItems.join(", ")}
|
|
422
|
+
</p>
|
|
423
|
+
</div>
|
|
424
|
+
<div className="s-space-y-2">
|
|
425
|
+
<label className="s-text-sm s-font-medium">Description</label>
|
|
426
|
+
<textarea
|
|
427
|
+
className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
|
|
428
|
+
placeholder="Describe how these data sources will be used..."
|
|
429
|
+
value={description}
|
|
430
|
+
onChange={(e) => setDescription(e.target.value)}
|
|
431
|
+
rows={4}
|
|
432
|
+
/>
|
|
433
|
+
<p className="s-text-xs s-text-muted-foreground">
|
|
434
|
+
This description helps explain the purpose of your
|
|
435
|
+
configuration.
|
|
436
|
+
</p>
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
),
|
|
440
|
+
},
|
|
441
|
+
];
|
|
442
|
+
|
|
443
|
+
return (
|
|
444
|
+
<MultiPageDialog>
|
|
445
|
+
<MultiPageDialogTrigger asChild>
|
|
446
|
+
<Button label="Open Configuration Wizard" />
|
|
447
|
+
</MultiPageDialogTrigger>
|
|
448
|
+
<MultiPageDialogContent
|
|
449
|
+
pages={conditionalPages}
|
|
450
|
+
currentPageId={currentPageId}
|
|
451
|
+
onPageChange={setCurrentPageId}
|
|
452
|
+
size="lg"
|
|
453
|
+
onSave={handleSave}
|
|
454
|
+
showNavigation={true}
|
|
455
|
+
disableNext={
|
|
456
|
+
currentPageId === "data-selection" && selectedItems.length === 0
|
|
457
|
+
}
|
|
458
|
+
disableSave={!description.trim()}
|
|
459
|
+
footerContent={
|
|
460
|
+
<div className="s-w-full s-border s-border-border-dark">
|
|
461
|
+
This is a footer content
|
|
462
|
+
</div>
|
|
463
|
+
}
|
|
464
|
+
/>
|
|
465
|
+
</MultiPageDialog>
|
|
466
|
+
);
|
|
467
|
+
},
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
export const ScrollableContent: Story = {
|
|
471
|
+
render: () => {
|
|
472
|
+
const [currentPageId, setCurrentPageId] = useState("long-form");
|
|
473
|
+
|
|
474
|
+
const handleSave = () => {
|
|
475
|
+
alert("Long form submitted!");
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const scrollablePages: MultiPageDialogPage[] = [
|
|
479
|
+
{
|
|
480
|
+
id: "long-form",
|
|
481
|
+
title: "Long Form Content",
|
|
482
|
+
description: "This page demonstrates scrollable content",
|
|
483
|
+
icon: DocumentTextIcon,
|
|
484
|
+
content: (
|
|
485
|
+
<div className="s-space-y-6">
|
|
486
|
+
<div>
|
|
487
|
+
<h3 className="s-mb-2 s-text-lg s-font-semibold">
|
|
488
|
+
Terms and Conditions
|
|
489
|
+
</h3>
|
|
490
|
+
<p className="s-text-sm s-text-muted-foreground">
|
|
491
|
+
This page contains a lot of content to demonstrate scrolling
|
|
492
|
+
functionality. The content should be scrollable within the
|
|
493
|
+
dialog area.
|
|
494
|
+
</p>
|
|
495
|
+
</div>
|
|
496
|
+
|
|
497
|
+
{Array.from({ length: 15 }, (_, i) => (
|
|
498
|
+
<div key={i} className="s-space-y-3">
|
|
499
|
+
<h4 className="s-text-md s-font-semibold">Section {i + 1}</h4>
|
|
500
|
+
<p className="s-text-sm s-text-muted-foreground">
|
|
501
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
|
|
502
|
+
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
503
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco
|
|
504
|
+
laboris nisi ut aliquip ex ea commodo consequat. Duis aute
|
|
505
|
+
irure dolor in reprehenderit in voluptate velit esse cillum
|
|
506
|
+
dolore eu fugiat nulla pariatur.
|
|
507
|
+
</p>
|
|
508
|
+
<div className="s-space-y-2">
|
|
509
|
+
<div>
|
|
510
|
+
<label className="s-text-sm s-font-medium">
|
|
511
|
+
Field {i + 1}
|
|
512
|
+
</label>
|
|
513
|
+
<input
|
|
514
|
+
type="text"
|
|
515
|
+
className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
|
|
516
|
+
placeholder={`Enter value for field ${i + 1}`}
|
|
517
|
+
/>
|
|
518
|
+
</div>
|
|
519
|
+
{i % 3 === 0 && (
|
|
520
|
+
<div>
|
|
521
|
+
<label className="s-text-sm s-font-medium">
|
|
522
|
+
Additional Notes
|
|
523
|
+
</label>
|
|
524
|
+
<textarea
|
|
525
|
+
className="s-mt-1 s-w-full s-rounded-md s-border s-px-3 s-py-2"
|
|
526
|
+
placeholder="Add any additional notes here..."
|
|
527
|
+
rows={3}
|
|
528
|
+
/>
|
|
529
|
+
</div>
|
|
530
|
+
)}
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
))}
|
|
534
|
+
|
|
535
|
+
<div className="s-rounded-md s-border s-bg-blue-50 s-p-4">
|
|
536
|
+
<h4 className="s-mb-2 s-text-sm s-font-semibold s-text-blue-900">
|
|
537
|
+
Scroll Test Complete
|
|
538
|
+
</h4>
|
|
539
|
+
<p className="s-text-xs s-text-blue-700">
|
|
540
|
+
If you can see this message, the scrolling functionality is
|
|
541
|
+
working correctly! The dialog maintains its fixed height while
|
|
542
|
+
allowing the content to scroll.
|
|
543
|
+
</p>
|
|
544
|
+
</div>
|
|
545
|
+
</div>
|
|
546
|
+
),
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
id: "summary",
|
|
550
|
+
title: "Summary",
|
|
551
|
+
description: "Review your information",
|
|
552
|
+
icon: Cog6ToothIcon,
|
|
553
|
+
content: (
|
|
554
|
+
<div className="s-space-y-4">
|
|
555
|
+
<div>
|
|
556
|
+
<h3 className="s-mb-2 s-text-lg s-font-semibold">Form Summary</h3>
|
|
557
|
+
<p className="s-text-sm s-text-muted-foreground">
|
|
558
|
+
Thank you for testing the scrollable content functionality.
|
|
559
|
+
</p>
|
|
560
|
+
</div>
|
|
561
|
+
<div className="s-rounded-md s-border s-bg-green-50 s-p-3">
|
|
562
|
+
<p className="s-text-sm s-text-green-700">
|
|
563
|
+
✓ Scrolling functionality verified
|
|
564
|
+
</p>
|
|
565
|
+
<p className="s-text-sm s-text-green-700">
|
|
566
|
+
✓ Fixed dialog height maintained
|
|
567
|
+
</p>
|
|
568
|
+
<p className="s-text-sm s-text-green-700">
|
|
569
|
+
✓ Content overflow handled properly
|
|
570
|
+
</p>
|
|
571
|
+
</div>
|
|
572
|
+
</div>
|
|
573
|
+
),
|
|
574
|
+
},
|
|
575
|
+
];
|
|
576
|
+
|
|
577
|
+
return (
|
|
578
|
+
<MultiPageDialog>
|
|
579
|
+
<MultiPageDialogTrigger asChild>
|
|
580
|
+
<Button label="Open Scrollable Content Dialog" />
|
|
581
|
+
</MultiPageDialogTrigger>
|
|
582
|
+
<MultiPageDialogContent
|
|
583
|
+
pages={scrollablePages}
|
|
584
|
+
currentPageId={currentPageId}
|
|
585
|
+
onPageChange={setCurrentPageId}
|
|
586
|
+
size="lg"
|
|
587
|
+
onSave={handleSave}
|
|
588
|
+
/>
|
|
589
|
+
</MultiPageDialog>
|
|
590
|
+
);
|
|
591
|
+
},
|
|
592
|
+
};
|