@qwickapps/react-framework 1.3.2 → 1.3.4
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/README.md +326 -0
- package/dist/components/AccessibilityProvider.d.ts +64 -0
- package/dist/components/AccessibilityProvider.d.ts.map +1 -0
- package/dist/components/Breadcrumbs.d.ts +39 -0
- package/dist/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +39 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +1 -1
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +28 -0
- package/dist/components/input/SwitchInputField.d.ts.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.d.ts.map +1 -1
- package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
- package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
- package/dist/components/layout/CollapsibleLayout/index.d.ts +9 -0
- package/dist/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/index.bundled.css +12 -0
- package/dist/index.esm.js +1678 -25
- package/dist/index.js +1689 -21
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +31 -0
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/SwitchInputFieldSchema.d.ts +18 -0
- package/dist/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
- package/dist/types/CollapsibleLayout.d.ts +142 -0
- package/dist/types/CollapsibleLayout.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/AccessibilityProvider.tsx +466 -0
- package/src/components/Breadcrumbs.tsx +223 -0
- package/src/components/ErrorBoundary.tsx +216 -0
- package/src/components/QwickApp.tsx +17 -11
- package/src/components/__tests__/AccessibilityProvider.test.tsx +330 -0
- package/src/components/__tests__/Breadcrumbs.test.tsx +268 -0
- package/src/components/__tests__/ErrorBoundary.test.tsx +163 -0
- package/src/components/forms/FormBlock.tsx +2 -2
- package/src/components/index.ts +3 -0
- package/src/components/input/SwitchInputField.tsx +165 -0
- package/src/components/input/index.ts +2 -0
- package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +554 -0
- package/src/components/layout/CollapsibleLayout/__tests__/CollapsibleLayout.test.tsx +1469 -0
- package/src/components/layout/CollapsibleLayout/index.tsx +17 -0
- package/src/components/layout/index.ts +4 -1
- package/src/components/pages/FormPage.tsx +1 -1
- package/src/schemas/CollapsibleLayoutSchema.ts +276 -0
- package/src/schemas/SwitchInputFieldSchema.ts +99 -0
- package/src/stories/AccessibilityProvider.stories.tsx +284 -0
- package/src/stories/Breadcrumbs.stories.tsx +304 -0
- package/src/stories/CollapsibleLayout.stories.tsx +1566 -0
- package/src/stories/ErrorBoundary.stories.tsx +159 -0
- package/src/types/CollapsibleLayout.ts +231 -0
- package/src/types/index.ts +1 -0
- package/dist/schemas/Builders.d.ts +0 -7
- package/dist/schemas/Builders.d.ts.map +0 -1
- package/dist/schemas/types.d.ts +0 -7
- package/dist/schemas/types.d.ts.map +0 -1
- package/dist/types/DataBinding.d.ts +0 -7
- package/dist/types/DataBinding.d.ts.map +0 -1
- package/dist/types/DataProvider.d.ts +0 -7
- package/dist/types/DataProvider.d.ts.map +0 -1
|
@@ -0,0 +1,1566 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CollapsibleLayout Component Stories - Advanced expandable/collapsible container with comprehensive features
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
ArrowDropDown as ArrowDropDownIcon,
|
|
9
|
+
ArrowDropUp as ArrowDropUpIcon,
|
|
10
|
+
Business as BusinessIcon,
|
|
11
|
+
CheckCircle as CheckCircleIcon,
|
|
12
|
+
Delete as DeleteIcon,
|
|
13
|
+
Edit as EditIcon,
|
|
14
|
+
Info as InfoIcon,
|
|
15
|
+
Person as PersonIcon,
|
|
16
|
+
Settings as SettingsIcon,
|
|
17
|
+
Visibility as VisibilityIcon,
|
|
18
|
+
Warning as WarningIcon
|
|
19
|
+
} from '@mui/icons-material';
|
|
20
|
+
import {
|
|
21
|
+
Alert,
|
|
22
|
+
Avatar,
|
|
23
|
+
Box,
|
|
24
|
+
Card,
|
|
25
|
+
CardContent,
|
|
26
|
+
Chip,
|
|
27
|
+
FormControlLabel,
|
|
28
|
+
LinearProgress,
|
|
29
|
+
List,
|
|
30
|
+
ListItem,
|
|
31
|
+
ListItemAvatar,
|
|
32
|
+
ListItemText,
|
|
33
|
+
Paper,
|
|
34
|
+
Stack,
|
|
35
|
+
Switch,
|
|
36
|
+
Table,
|
|
37
|
+
TableBody,
|
|
38
|
+
TableCell,
|
|
39
|
+
TableContainer,
|
|
40
|
+
TableHead,
|
|
41
|
+
TableRow,
|
|
42
|
+
Typography,
|
|
43
|
+
} from '@mui/material';
|
|
44
|
+
import { JsonDataProvider } from '@qwickapps/schema';
|
|
45
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
46
|
+
import { useState } from 'react';
|
|
47
|
+
import { Button, Code, CollapsibleLayout, QwickApp, TextField } from '../components';
|
|
48
|
+
|
|
49
|
+
// Sample data for different CollapsibleLayout configurations
|
|
50
|
+
const sampleCmsData = {
|
|
51
|
+
'collapsible-layouts': {
|
|
52
|
+
'simple-card': {
|
|
53
|
+
title: 'Basic Information',
|
|
54
|
+
subtitle: 'Personal details and contact information',
|
|
55
|
+
defaultCollapsed: false,
|
|
56
|
+
variant: 'outlined',
|
|
57
|
+
headerSpacing: 'comfortable',
|
|
58
|
+
contentSpacing: 'comfortable',
|
|
59
|
+
},
|
|
60
|
+
'settings-panel': {
|
|
61
|
+
title: 'Advanced Settings',
|
|
62
|
+
subtitle: 'Configure advanced options and preferences',
|
|
63
|
+
defaultCollapsed: true,
|
|
64
|
+
variant: 'elevated',
|
|
65
|
+
headerSpacing: 'spacious',
|
|
66
|
+
contentSpacing: 'spacious',
|
|
67
|
+
leadIcon: '<SettingsIcon />',
|
|
68
|
+
showDivider: true,
|
|
69
|
+
},
|
|
70
|
+
'notification-center': {
|
|
71
|
+
title: 'Notifications',
|
|
72
|
+
subtitle: '3 unread messages',
|
|
73
|
+
defaultCollapsed: true,
|
|
74
|
+
variant: 'filled',
|
|
75
|
+
headerSpacing: 'compact',
|
|
76
|
+
contentSpacing: 'compact',
|
|
77
|
+
triggerArea: 'both',
|
|
78
|
+
animationStyle: 'fade',
|
|
79
|
+
},
|
|
80
|
+
'data-table': {
|
|
81
|
+
title: 'User Management',
|
|
82
|
+
subtitle: 'Manage users and permissions',
|
|
83
|
+
defaultCollapsed: false,
|
|
84
|
+
variant: 'default',
|
|
85
|
+
triggerArea: 'button',
|
|
86
|
+
animationStyle: 'slide',
|
|
87
|
+
persistState: true,
|
|
88
|
+
},
|
|
89
|
+
'help-section': {
|
|
90
|
+
title: 'Help & Support',
|
|
91
|
+
collapsedView: '<Typography color="text.secondary">Click to expand help section...</Typography>',
|
|
92
|
+
defaultCollapsed: true,
|
|
93
|
+
variant: 'outlined',
|
|
94
|
+
animationStyle: 'scale',
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const dataProvider = new JsonDataProvider({ data: sampleCmsData });
|
|
100
|
+
|
|
101
|
+
const meta = {
|
|
102
|
+
title: 'Layout/CollapsibleLayout',
|
|
103
|
+
component: CollapsibleLayout,
|
|
104
|
+
parameters: {
|
|
105
|
+
layout: 'padded',
|
|
106
|
+
docs: {
|
|
107
|
+
description: {
|
|
108
|
+
component: `CollapsibleLayout is an advanced expandable/collapsible container for the QwickApps React Framework with comprehensive features and customization options.
|
|
109
|
+
|
|
110
|
+
**Key Features:**
|
|
111
|
+
- **Controlled & Uncontrolled States**: Supports both controlled (with collapsed prop) and uncontrolled (with defaultCollapsed) usage patterns
|
|
112
|
+
- **Multiple Animation Styles**: Fade, slide, and scale animations with customizable duration
|
|
113
|
+
- **Flexible Trigger Areas**: Header click, button only, or both trigger areas for expanding/collapsing
|
|
114
|
+
- **LocalStorage Persistence**: Optionally remember collapsed state across browser sessions
|
|
115
|
+
- **Visual Variants**: Default, outlined, elevated, and filled styles for different design contexts
|
|
116
|
+
- **Customizable Spacing**: Compact, comfortable, and spacious spacing options for header and content
|
|
117
|
+
- **Rich Content Support**: Header actions, collapsed preview, footer, and complex content with React nodes or HTML
|
|
118
|
+
- **Complete Accessibility**: ARIA attributes, keyboard navigation, and screen reader support
|
|
119
|
+
- **Data Binding**: Full CMS integration through dataSource prop
|
|
120
|
+
- **Icon Customization**: Custom collapse/expand icons with React nodes or HTML strings
|
|
121
|
+
- **Theme Integration**: Automatically integrates with QwickApp theme and Material-UI components
|
|
122
|
+
|
|
123
|
+
**Perfect For:**
|
|
124
|
+
- Settings panels and configuration sections
|
|
125
|
+
- Data tables with expandable details
|
|
126
|
+
- FAQ sections and help documentation
|
|
127
|
+
- Feature panels and content organization
|
|
128
|
+
- Complex forms with collapsible sections
|
|
129
|
+
- Dashboard widgets and information panels`,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
tags: ['autodocs'],
|
|
134
|
+
argTypes: {
|
|
135
|
+
// State control
|
|
136
|
+
collapsed: {
|
|
137
|
+
control: 'boolean',
|
|
138
|
+
description: 'Controlled collapsed state (undefined for uncontrolled)',
|
|
139
|
+
},
|
|
140
|
+
defaultCollapsed: {
|
|
141
|
+
control: 'boolean',
|
|
142
|
+
description: 'Initial collapsed state for uncontrolled component',
|
|
143
|
+
},
|
|
144
|
+
onToggle: {
|
|
145
|
+
action: 'toggled',
|
|
146
|
+
description: 'Callback fired when collapsed state changes',
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
// Content
|
|
150
|
+
title: {
|
|
151
|
+
control: 'text',
|
|
152
|
+
description: 'Header title text',
|
|
153
|
+
},
|
|
154
|
+
subtitle: {
|
|
155
|
+
control: 'text',
|
|
156
|
+
description: 'Header subtitle text',
|
|
157
|
+
},
|
|
158
|
+
children: {
|
|
159
|
+
control: 'text',
|
|
160
|
+
description: 'Main content (ReactNode or string)',
|
|
161
|
+
},
|
|
162
|
+
collapsedView: {
|
|
163
|
+
control: 'text',
|
|
164
|
+
description: 'Content shown when collapsed (ReactNode or string)',
|
|
165
|
+
},
|
|
166
|
+
footerView: {
|
|
167
|
+
control: 'text',
|
|
168
|
+
description: 'Footer content (ReactNode or string)',
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
// Behavior
|
|
172
|
+
triggerArea: {
|
|
173
|
+
control: 'select',
|
|
174
|
+
options: ['header', 'button', 'both'],
|
|
175
|
+
description: 'Which area triggers expand/collapse',
|
|
176
|
+
},
|
|
177
|
+
animationStyle: {
|
|
178
|
+
control: 'select',
|
|
179
|
+
options: ['fade', 'slide', 'scale'],
|
|
180
|
+
description: 'Animation style for expand/collapse',
|
|
181
|
+
},
|
|
182
|
+
animationDuration: {
|
|
183
|
+
control: { type: 'number', min: 0, max: 2000 },
|
|
184
|
+
description: 'Animation duration in milliseconds',
|
|
185
|
+
},
|
|
186
|
+
disableAnimations: {
|
|
187
|
+
control: 'boolean',
|
|
188
|
+
description: 'Disable all animations',
|
|
189
|
+
},
|
|
190
|
+
persistState: {
|
|
191
|
+
control: 'boolean',
|
|
192
|
+
description: 'Remember state in localStorage',
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
// Layout
|
|
196
|
+
variant: {
|
|
197
|
+
control: 'select',
|
|
198
|
+
options: ['default', 'outlined', 'elevated', 'filled'],
|
|
199
|
+
description: 'Visual style variant',
|
|
200
|
+
},
|
|
201
|
+
headerSpacing: {
|
|
202
|
+
control: 'select',
|
|
203
|
+
options: ['compact', 'comfortable', 'spacious'],
|
|
204
|
+
description: 'Header padding/spacing',
|
|
205
|
+
},
|
|
206
|
+
contentSpacing: {
|
|
207
|
+
control: 'select',
|
|
208
|
+
options: ['compact', 'comfortable', 'spacious'],
|
|
209
|
+
description: 'Content padding/spacing',
|
|
210
|
+
},
|
|
211
|
+
showDivider: {
|
|
212
|
+
control: 'boolean',
|
|
213
|
+
description: 'Show divider between header and content',
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// Icons
|
|
217
|
+
collapsedIcon: {
|
|
218
|
+
control: 'text',
|
|
219
|
+
description: 'Custom icon when collapsed',
|
|
220
|
+
},
|
|
221
|
+
expandedIcon: {
|
|
222
|
+
control: 'text',
|
|
223
|
+
description: 'Custom icon when expanded',
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
// Accessibility
|
|
227
|
+
toggleAriaLabel: {
|
|
228
|
+
control: 'text',
|
|
229
|
+
description: 'ARIA label for toggle button',
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
} satisfies Meta<typeof CollapsibleLayout>;
|
|
233
|
+
|
|
234
|
+
export default meta;
|
|
235
|
+
type Story = StoryObj<typeof CollapsibleLayout>;
|
|
236
|
+
|
|
237
|
+
// ============================================
|
|
238
|
+
// BASIC STORIES
|
|
239
|
+
// ============================================
|
|
240
|
+
|
|
241
|
+
export const Default: Story = {
|
|
242
|
+
render: () => (
|
|
243
|
+
<QwickApp appId="collapsible-default" appName='Default CollapsibleLayout'>
|
|
244
|
+
<CollapsibleLayout
|
|
245
|
+
title="Basic Collapsible Section"
|
|
246
|
+
subtitle="Click the header to expand or collapse this content"
|
|
247
|
+
defaultCollapsed={false}
|
|
248
|
+
onToggle={(collapsed) => console.log('Toggled:', collapsed)}
|
|
249
|
+
>
|
|
250
|
+
<Typography variant="body1">
|
|
251
|
+
This is the main content of the collapsible layout. It can contain any React components,
|
|
252
|
+
text, forms, tables, or other complex layouts. The content is shown when expanded and
|
|
253
|
+
hidden when collapsed.
|
|
254
|
+
</Typography>
|
|
255
|
+
<Box sx={{ mt: 2, p: 2, backgroundColor: 'action.hover', borderRadius: 1 }}>
|
|
256
|
+
<Typography variant="body2">
|
|
257
|
+
This content is inside a styled box within the collapsible layout.
|
|
258
|
+
</Typography>
|
|
259
|
+
</Box>
|
|
260
|
+
</CollapsibleLayout>
|
|
261
|
+
</QwickApp>
|
|
262
|
+
),
|
|
263
|
+
parameters: {
|
|
264
|
+
docs: {
|
|
265
|
+
description: {
|
|
266
|
+
story: 'Default CollapsibleLayout with header title, subtitle, and simple content.',
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export const WithHeaderActions: Story = {
|
|
273
|
+
render: () => (
|
|
274
|
+
<QwickApp appId="collapsible-actions" appName='CollapsibleLayout with Header Actions'>
|
|
275
|
+
<CollapsibleLayout
|
|
276
|
+
title="User Profile Settings"
|
|
277
|
+
subtitle="Manage your account preferences"
|
|
278
|
+
defaultCollapsed={false}
|
|
279
|
+
headerActions={
|
|
280
|
+
<Stack direction="row" spacing={1}>
|
|
281
|
+
<Chip label="Pro" color="primary" size="small" />
|
|
282
|
+
<Button size="small" variant="outlined">Edit</Button>
|
|
283
|
+
</Stack>
|
|
284
|
+
}
|
|
285
|
+
leadIcon={<PersonIcon color="primary" />}
|
|
286
|
+
>
|
|
287
|
+
<Stack spacing={2}>
|
|
288
|
+
<TextField label="Display Name" defaultValue="John Doe" fullWidth />
|
|
289
|
+
<TextField label="Email Address" defaultValue="john@example.com" fullWidth />
|
|
290
|
+
<TextField label="Bio" multiline rows={3} defaultValue="Software developer passionate about creating amazing user experiences." fullWidth />
|
|
291
|
+
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
292
|
+
<Button variant="contained">Save Changes</Button>
|
|
293
|
+
<Button variant="outlined">Cancel</Button>
|
|
294
|
+
</Box>
|
|
295
|
+
</Stack>
|
|
296
|
+
</CollapsibleLayout>
|
|
297
|
+
</QwickApp>
|
|
298
|
+
),
|
|
299
|
+
parameters: {
|
|
300
|
+
docs: {
|
|
301
|
+
description: {
|
|
302
|
+
story: 'CollapsibleLayout with lead icon, header actions (chip and button), and form content.',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export const WithFooter: Story = {
|
|
309
|
+
render: () => (
|
|
310
|
+
<QwickApp appId="collapsible-footer" appName='CollapsibleLayout with Footer'>
|
|
311
|
+
<CollapsibleLayout
|
|
312
|
+
title="Project Overview"
|
|
313
|
+
subtitle="Development status and team information"
|
|
314
|
+
defaultCollapsed={false}
|
|
315
|
+
footerView={
|
|
316
|
+
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pt: 1 }}>
|
|
317
|
+
<Typography variant="caption" color="text.secondary">
|
|
318
|
+
Last updated: 2 hours ago
|
|
319
|
+
</Typography>
|
|
320
|
+
<Button size="small" variant="text">View Details</Button>
|
|
321
|
+
</Box>
|
|
322
|
+
}
|
|
323
|
+
>
|
|
324
|
+
<Stack spacing={2}>
|
|
325
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
326
|
+
<CheckCircleIcon color="success" />
|
|
327
|
+
<Typography>Development: Complete</Typography>
|
|
328
|
+
</Box>
|
|
329
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
330
|
+
<WarningIcon color="warning" />
|
|
331
|
+
<Typography>Testing: In Progress</Typography>
|
|
332
|
+
</Box>
|
|
333
|
+
<LinearProgress variant="determinate" value={75} sx={{ mt: 2 }} />
|
|
334
|
+
<Typography variant="body2" color="text.secondary">
|
|
335
|
+
Project is 75% complete
|
|
336
|
+
</Typography>
|
|
337
|
+
</Stack>
|
|
338
|
+
</CollapsibleLayout>
|
|
339
|
+
</QwickApp>
|
|
340
|
+
),
|
|
341
|
+
parameters: {
|
|
342
|
+
docs: {
|
|
343
|
+
description: {
|
|
344
|
+
story: 'CollapsibleLayout with footer content that remains visible at the bottom.',
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// ============================================
|
|
351
|
+
// VARIANT STORIES
|
|
352
|
+
// ============================================
|
|
353
|
+
|
|
354
|
+
export const AllVariants: Story = {
|
|
355
|
+
render: () => (
|
|
356
|
+
<QwickApp appId="collapsible-variants" appName='CollapsibleLayout Variants'>
|
|
357
|
+
<Stack spacing={3}>
|
|
358
|
+
<CollapsibleLayout
|
|
359
|
+
title="Default Variant"
|
|
360
|
+
subtitle="Basic styling with no container decoration"
|
|
361
|
+
variant="default"
|
|
362
|
+
defaultCollapsed={false}
|
|
363
|
+
>
|
|
364
|
+
<Typography>Content for default variant - clean and minimal appearance.</Typography>
|
|
365
|
+
</CollapsibleLayout>
|
|
366
|
+
|
|
367
|
+
<CollapsibleLayout
|
|
368
|
+
title="Outlined Variant"
|
|
369
|
+
subtitle="Container with border outline"
|
|
370
|
+
variant="outlined"
|
|
371
|
+
defaultCollapsed={false}
|
|
372
|
+
>
|
|
373
|
+
<Typography>Content for outlined variant - defined with subtle border.</Typography>
|
|
374
|
+
</CollapsibleLayout>
|
|
375
|
+
|
|
376
|
+
<CollapsibleLayout
|
|
377
|
+
title="Elevated Variant"
|
|
378
|
+
subtitle="Container with shadow elevation"
|
|
379
|
+
variant="elevated"
|
|
380
|
+
defaultCollapsed={false}
|
|
381
|
+
>
|
|
382
|
+
<Typography>Content for elevated variant - lifted appearance with shadow.</Typography>
|
|
383
|
+
</CollapsibleLayout>
|
|
384
|
+
|
|
385
|
+
<CollapsibleLayout
|
|
386
|
+
title="Filled Variant"
|
|
387
|
+
subtitle="Container with background fill"
|
|
388
|
+
variant="filled"
|
|
389
|
+
defaultCollapsed={false}
|
|
390
|
+
>
|
|
391
|
+
<Typography>Content for filled variant - emphasized with background color.</Typography>
|
|
392
|
+
</CollapsibleLayout>
|
|
393
|
+
</Stack>
|
|
394
|
+
</QwickApp>
|
|
395
|
+
),
|
|
396
|
+
parameters: {
|
|
397
|
+
docs: {
|
|
398
|
+
description: {
|
|
399
|
+
story: 'Comparison of all four visual variants: default, outlined, elevated, and filled.',
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// ============================================
|
|
406
|
+
// STATE STORIES
|
|
407
|
+
// ============================================
|
|
408
|
+
|
|
409
|
+
export const InitiallyCollapsed: Story = {
|
|
410
|
+
render: () => (
|
|
411
|
+
<QwickApp appId="collapsible-collapsed" appName='Initially Collapsed'>
|
|
412
|
+
<CollapsibleLayout
|
|
413
|
+
title="Collapsed by Default"
|
|
414
|
+
subtitle="This section starts in collapsed state"
|
|
415
|
+
defaultCollapsed={true}
|
|
416
|
+
variant="outlined"
|
|
417
|
+
>
|
|
418
|
+
<Typography>
|
|
419
|
+
This content was hidden initially and is now visible after expanding.
|
|
420
|
+
Great for less important sections or to save space on page load.
|
|
421
|
+
</Typography>
|
|
422
|
+
</CollapsibleLayout>
|
|
423
|
+
</QwickApp>
|
|
424
|
+
),
|
|
425
|
+
parameters: {
|
|
426
|
+
docs: {
|
|
427
|
+
description: {
|
|
428
|
+
story: 'CollapsibleLayout that starts in collapsed state using defaultCollapsed prop.',
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
export const ControlledState: Story = {
|
|
435
|
+
render: () => {
|
|
436
|
+
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
437
|
+
|
|
438
|
+
return (
|
|
439
|
+
<QwickApp appId="collapsible-controlled" appName='Controlled State'>
|
|
440
|
+
<Stack spacing={2}>
|
|
441
|
+
<Box>
|
|
442
|
+
<FormControlLabel
|
|
443
|
+
control={
|
|
444
|
+
<Switch
|
|
445
|
+
checked={!isCollapsed}
|
|
446
|
+
onChange={(e) => setIsCollapsed(!e.target.checked)}
|
|
447
|
+
/>
|
|
448
|
+
}
|
|
449
|
+
label="Show content"
|
|
450
|
+
/>
|
|
451
|
+
</Box>
|
|
452
|
+
|
|
453
|
+
<CollapsibleLayout
|
|
454
|
+
title="Controlled CollapsibleLayout"
|
|
455
|
+
subtitle="State controlled by external switch"
|
|
456
|
+
collapsed={isCollapsed}
|
|
457
|
+
onToggle={(collapsed) => {
|
|
458
|
+
setIsCollapsed(collapsed);
|
|
459
|
+
console.log('External control - Collapsed:', collapsed);
|
|
460
|
+
}}
|
|
461
|
+
variant="outlined"
|
|
462
|
+
>
|
|
463
|
+
<Alert severity="info">
|
|
464
|
+
This CollapsibleLayout's state is controlled by the switch above.
|
|
465
|
+
You can also click the header to toggle, but the switch will update accordingly.
|
|
466
|
+
</Alert>
|
|
467
|
+
</CollapsibleLayout>
|
|
468
|
+
</Stack>
|
|
469
|
+
</QwickApp>
|
|
470
|
+
);
|
|
471
|
+
},
|
|
472
|
+
parameters: {
|
|
473
|
+
docs: {
|
|
474
|
+
description: {
|
|
475
|
+
story: 'CollapsibleLayout with controlled state managed by external component (switch).',
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export const WithPersistence: Story = {
|
|
482
|
+
render: () => (
|
|
483
|
+
<QwickApp appId="collapsible-persistence" appName='State Persistence'>
|
|
484
|
+
<Stack spacing={2}>
|
|
485
|
+
<Alert severity="info">
|
|
486
|
+
Toggle this section and refresh the page - the state will be remembered!
|
|
487
|
+
</Alert>
|
|
488
|
+
|
|
489
|
+
<CollapsibleLayout
|
|
490
|
+
title="Persistent State"
|
|
491
|
+
subtitle="State is saved to localStorage"
|
|
492
|
+
defaultCollapsed={false}
|
|
493
|
+
persistState={true}
|
|
494
|
+
storageKey="demo-persistent-section"
|
|
495
|
+
variant="elevated"
|
|
496
|
+
>
|
|
497
|
+
<Typography>
|
|
498
|
+
This section remembers its collapsed/expanded state using localStorage.
|
|
499
|
+
Try collapsing it and refreshing the page - it will remain collapsed.
|
|
500
|
+
</Typography>
|
|
501
|
+
<Box sx={{ mt: 2, p: 2, backgroundColor: 'primary.light', borderRadius: 1 }}>
|
|
502
|
+
<Typography variant="body2">
|
|
503
|
+
The storageKey "demo-persistent-section" is used to store the state.
|
|
504
|
+
</Typography>
|
|
505
|
+
</Box>
|
|
506
|
+
</CollapsibleLayout>
|
|
507
|
+
</Stack>
|
|
508
|
+
</QwickApp>
|
|
509
|
+
),
|
|
510
|
+
parameters: {
|
|
511
|
+
docs: {
|
|
512
|
+
description: {
|
|
513
|
+
story: 'CollapsibleLayout with localStorage persistence to remember state across page refreshes.',
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// ============================================
|
|
520
|
+
// CONTENT STORIES
|
|
521
|
+
// ============================================
|
|
522
|
+
|
|
523
|
+
export const WithCollapsedView: Story = {
|
|
524
|
+
render: () => (
|
|
525
|
+
<QwickApp appId="collapsible-preview" appName='Collapsed View'>
|
|
526
|
+
<CollapsibleLayout
|
|
527
|
+
title="Article Preview"
|
|
528
|
+
subtitle="Click to read the full article"
|
|
529
|
+
defaultCollapsed={true}
|
|
530
|
+
variant="outlined"
|
|
531
|
+
collapsedView={
|
|
532
|
+
<Box sx={{ p: 2, backgroundColor: 'action.hover', borderRadius: 1 }}>
|
|
533
|
+
<Typography variant="body2" color="text.secondary">
|
|
534
|
+
📖 This article covers advanced React patterns and best practices for building
|
|
535
|
+
scalable applications. Click header to expand and read more...
|
|
536
|
+
</Typography>
|
|
537
|
+
</Box>
|
|
538
|
+
}
|
|
539
|
+
>
|
|
540
|
+
<Stack spacing={2}>
|
|
541
|
+
<Typography variant="h6">Advanced React Patterns</Typography>
|
|
542
|
+
<Typography>
|
|
543
|
+
React has evolved significantly over the years, and with it, the patterns and practices
|
|
544
|
+
that help developers build maintainable, scalable applications. In this comprehensive
|
|
545
|
+
guide, we'll explore some of the most powerful advanced patterns.
|
|
546
|
+
</Typography>
|
|
547
|
+
<Typography variant="h6">1. Compound Components</Typography>
|
|
548
|
+
<Typography>
|
|
549
|
+
Compound components provide a flexible and intuitive API for components that need to
|
|
550
|
+
work together. They allow you to express relationships between components more clearly.
|
|
551
|
+
</Typography>
|
|
552
|
+
<Typography variant="h6">2. Render Props Pattern</Typography>
|
|
553
|
+
<Typography>
|
|
554
|
+
The render props pattern is a technique for sharing code between React components using
|
|
555
|
+
a prop whose value is a function.
|
|
556
|
+
</Typography>
|
|
557
|
+
<Button variant="outlined" sx={{ alignSelf: 'flex-start' }}>
|
|
558
|
+
Read More
|
|
559
|
+
</Button>
|
|
560
|
+
</Stack>
|
|
561
|
+
</CollapsibleLayout>
|
|
562
|
+
</QwickApp>
|
|
563
|
+
),
|
|
564
|
+
parameters: {
|
|
565
|
+
docs: {
|
|
566
|
+
description: {
|
|
567
|
+
story: 'CollapsibleLayout with preview content shown when collapsed and full content when expanded.',
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
export const ComplexContent: Story = {
|
|
574
|
+
render: () => (
|
|
575
|
+
<QwickApp appId="collapsible-complex" appName='Complex Content'>
|
|
576
|
+
<CollapsibleLayout
|
|
577
|
+
title="User Management Dashboard"
|
|
578
|
+
subtitle="Manage users, roles, and permissions"
|
|
579
|
+
defaultCollapsed={false}
|
|
580
|
+
variant="elevated"
|
|
581
|
+
headerActions={
|
|
582
|
+
<Button size="small" variant="contained" startIcon={<PersonIcon />}>
|
|
583
|
+
Add User
|
|
584
|
+
</Button>
|
|
585
|
+
}
|
|
586
|
+
>
|
|
587
|
+
<Stack spacing={3}>
|
|
588
|
+
{/* Quick Stats */}
|
|
589
|
+
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))', gap: 2 }}>
|
|
590
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
591
|
+
<Typography variant="h4" color="primary">142</Typography>
|
|
592
|
+
<Typography variant="caption">Total Users</Typography>
|
|
593
|
+
</Paper>
|
|
594
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
595
|
+
<Typography variant="h4" color="success.main">98</Typography>
|
|
596
|
+
<Typography variant="caption">Active</Typography>
|
|
597
|
+
</Paper>
|
|
598
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
599
|
+
<Typography variant="h4" color="warning.main">12</Typography>
|
|
600
|
+
<Typography variant="caption">Pending</Typography>
|
|
601
|
+
</Paper>
|
|
602
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
603
|
+
<Typography variant="h4" color="error.main">3</Typography>
|
|
604
|
+
<Typography variant="caption">Inactive</Typography>
|
|
605
|
+
</Paper>
|
|
606
|
+
</Box>
|
|
607
|
+
|
|
608
|
+
{/* User Table */}
|
|
609
|
+
<TableContainer component={Paper}>
|
|
610
|
+
<Table size="small">
|
|
611
|
+
<TableHead>
|
|
612
|
+
<TableRow>
|
|
613
|
+
<TableCell>User</TableCell>
|
|
614
|
+
<TableCell>Role</TableCell>
|
|
615
|
+
<TableCell>Status</TableCell>
|
|
616
|
+
<TableCell align="right">Actions</TableCell>
|
|
617
|
+
</TableRow>
|
|
618
|
+
</TableHead>
|
|
619
|
+
<TableBody>
|
|
620
|
+
<TableRow>
|
|
621
|
+
<TableCell>
|
|
622
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
623
|
+
<Avatar sx={{ width: 32, height: 32 }}>JD</Avatar>
|
|
624
|
+
<Box>
|
|
625
|
+
<Typography variant="body2">John Doe</Typography>
|
|
626
|
+
<Typography variant="caption" color="text.secondary">john@example.com</Typography>
|
|
627
|
+
</Box>
|
|
628
|
+
</Box>
|
|
629
|
+
</TableCell>
|
|
630
|
+
<TableCell>Admin</TableCell>
|
|
631
|
+
<TableCell>
|
|
632
|
+
<Chip label="Active" color="success" size="small" />
|
|
633
|
+
</TableCell>
|
|
634
|
+
<TableCell align="right">
|
|
635
|
+
<Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-end' }}>
|
|
636
|
+
<Button size="small" startIcon={<EditIcon />}>Edit</Button>
|
|
637
|
+
<Button size="small" color="error" startIcon={<DeleteIcon />}>Delete</Button>
|
|
638
|
+
</Box>
|
|
639
|
+
</TableCell>
|
|
640
|
+
</TableRow>
|
|
641
|
+
<TableRow>
|
|
642
|
+
<TableCell>
|
|
643
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
644
|
+
<Avatar sx={{ width: 32, height: 32 }}>JS</Avatar>
|
|
645
|
+
<Box>
|
|
646
|
+
<Typography variant="body2">Jane Smith</Typography>
|
|
647
|
+
<Typography variant="caption" color="text.secondary">jane@example.com</Typography>
|
|
648
|
+
</Box>
|
|
649
|
+
</Box>
|
|
650
|
+
</TableCell>
|
|
651
|
+
<TableCell>Editor</TableCell>
|
|
652
|
+
<TableCell>
|
|
653
|
+
<Chip label="Pending" color="warning" size="small" />
|
|
654
|
+
</TableCell>
|
|
655
|
+
<TableCell align="right">
|
|
656
|
+
<Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-end' }}>
|
|
657
|
+
<Button size="small" startIcon={<EditIcon />}>Edit</Button>
|
|
658
|
+
<Button size="small" color="error" startIcon={<DeleteIcon />}>Delete</Button>
|
|
659
|
+
</Box>
|
|
660
|
+
</TableCell>
|
|
661
|
+
</TableRow>
|
|
662
|
+
</TableBody>
|
|
663
|
+
</Table>
|
|
664
|
+
</TableContainer>
|
|
665
|
+
</Stack>
|
|
666
|
+
</CollapsibleLayout>
|
|
667
|
+
</QwickApp>
|
|
668
|
+
),
|
|
669
|
+
parameters: {
|
|
670
|
+
docs: {
|
|
671
|
+
description: {
|
|
672
|
+
story: 'CollapsibleLayout containing complex content: statistics cards, data table with actions, and mixed layouts.',
|
|
673
|
+
},
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
export const WithHtmlContent: Story = {
|
|
679
|
+
render: () => (
|
|
680
|
+
<QwickApp appId="collapsible-html" appName='HTML Content'>
|
|
681
|
+
<CollapsibleLayout
|
|
682
|
+
title="Rich Content Section"
|
|
683
|
+
subtitle="Supports both React components and HTML strings"
|
|
684
|
+
defaultCollapsed={false}
|
|
685
|
+
variant="outlined"
|
|
686
|
+
leadIcon="🎨"
|
|
687
|
+
collapsedView="<p style='color: #666;'><em>Click to view rich HTML content...</em></p>"
|
|
688
|
+
>
|
|
689
|
+
<div>
|
|
690
|
+
<h3>Mixed Content Support</h3>
|
|
691
|
+
<p>This section demonstrates how CollapsibleLayout can handle various content types:</p>
|
|
692
|
+
<ul>
|
|
693
|
+
<li><strong>React Components:</strong> Full JSX support with interactive elements</li>
|
|
694
|
+
<li><strong>HTML Strings:</strong> Raw HTML content rendered safely</li>
|
|
695
|
+
<li><strong>Mixed Content:</strong> Combination of both types</li>
|
|
696
|
+
</ul>
|
|
697
|
+
|
|
698
|
+
<div style={{ padding: '16px', backgroundColor: '#f5f5f5', borderRadius: '8px', marginTop: '16px' }}>
|
|
699
|
+
<h4>HTML String Example:</h4>
|
|
700
|
+
<p>This content could come from a CMS or markdown processor.</p>
|
|
701
|
+
<code>{'<CollapsibleLayout title="..." children="<div>HTML content</div>" />'}</code>
|
|
702
|
+
</div>
|
|
703
|
+
|
|
704
|
+
<Box sx={{ mt: 2, p: 2, backgroundColor: 'primary.light', borderRadius: 1 }}>
|
|
705
|
+
<Typography variant="body2">
|
|
706
|
+
And this is a React component (Material-UI Box) mixed with the HTML content above.
|
|
707
|
+
</Typography>
|
|
708
|
+
</Box>
|
|
709
|
+
</div>
|
|
710
|
+
</CollapsibleLayout>
|
|
711
|
+
</QwickApp>
|
|
712
|
+
),
|
|
713
|
+
parameters: {
|
|
714
|
+
docs: {
|
|
715
|
+
description: {
|
|
716
|
+
story: 'CollapsibleLayout with mixed HTML string and React component content, demonstrating flexible content support.',
|
|
717
|
+
},
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
// ============================================
|
|
723
|
+
// INTERACTION STORIES
|
|
724
|
+
// ============================================
|
|
725
|
+
|
|
726
|
+
export const TriggerAreas: Story = {
|
|
727
|
+
render: () => (
|
|
728
|
+
<QwickApp appId="collapsible-triggers" appName='Trigger Areas'>
|
|
729
|
+
<Stack spacing={3}>
|
|
730
|
+
<CollapsibleLayout
|
|
731
|
+
title="Header Trigger"
|
|
732
|
+
subtitle="Click anywhere on the header to toggle"
|
|
733
|
+
triggerArea="header"
|
|
734
|
+
defaultCollapsed={false}
|
|
735
|
+
variant="outlined"
|
|
736
|
+
>
|
|
737
|
+
<Typography>
|
|
738
|
+
With triggerArea="header", you can click anywhere on the header area to expand/collapse.
|
|
739
|
+
No separate toggle button is shown.
|
|
740
|
+
</Typography>
|
|
741
|
+
</CollapsibleLayout>
|
|
742
|
+
|
|
743
|
+
<CollapsibleLayout
|
|
744
|
+
title="Button Trigger"
|
|
745
|
+
subtitle="Only the button toggles the content"
|
|
746
|
+
triggerArea="button"
|
|
747
|
+
defaultCollapsed={false}
|
|
748
|
+
variant="outlined"
|
|
749
|
+
>
|
|
750
|
+
<Typography>
|
|
751
|
+
With triggerArea="button", only the toggle button (shown on the right) can expand/collapse.
|
|
752
|
+
Clicking the header text has no effect.
|
|
753
|
+
</Typography>
|
|
754
|
+
</CollapsibleLayout>
|
|
755
|
+
|
|
756
|
+
<CollapsibleLayout
|
|
757
|
+
title="Both Triggers"
|
|
758
|
+
subtitle="Header or button can toggle"
|
|
759
|
+
triggerArea="both"
|
|
760
|
+
defaultCollapsed={false}
|
|
761
|
+
variant="outlined"
|
|
762
|
+
>
|
|
763
|
+
<Typography>
|
|
764
|
+
With triggerArea="both", you can either click the header area OR use the toggle button.
|
|
765
|
+
This provides maximum flexibility for users.
|
|
766
|
+
</Typography>
|
|
767
|
+
</CollapsibleLayout>
|
|
768
|
+
</Stack>
|
|
769
|
+
</QwickApp>
|
|
770
|
+
),
|
|
771
|
+
parameters: {
|
|
772
|
+
docs: {
|
|
773
|
+
description: {
|
|
774
|
+
story: 'Different trigger areas: header only, button only, or both header and button.',
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
export const CustomIcons: Story = {
|
|
781
|
+
render: () => (
|
|
782
|
+
<QwickApp appId="collapsible-icons" appName='Custom Icons'>
|
|
783
|
+
<Stack spacing={3}>
|
|
784
|
+
<CollapsibleLayout
|
|
785
|
+
title="Custom React Icons"
|
|
786
|
+
subtitle="Using Material-UI icons"
|
|
787
|
+
triggerArea="both"
|
|
788
|
+
defaultCollapsed={false}
|
|
789
|
+
variant="outlined"
|
|
790
|
+
collapsedIcon={<ArrowDropDownIcon />}
|
|
791
|
+
expandedIcon={<ArrowDropUpIcon />}
|
|
792
|
+
>
|
|
793
|
+
<Typography>
|
|
794
|
+
This layout uses custom Material-UI icons: ArrowDropDown when collapsed, ArrowDropUp when expanded.
|
|
795
|
+
</Typography>
|
|
796
|
+
</CollapsibleLayout>
|
|
797
|
+
|
|
798
|
+
<CollapsibleLayout
|
|
799
|
+
title="HTML String Icons"
|
|
800
|
+
subtitle="Using emoji and HTML entities"
|
|
801
|
+
triggerArea="both"
|
|
802
|
+
defaultCollapsed={false}
|
|
803
|
+
variant="outlined"
|
|
804
|
+
collapsedIcon="▶️"
|
|
805
|
+
expandedIcon="🔽"
|
|
806
|
+
>
|
|
807
|
+
<Typography>
|
|
808
|
+
This layout uses emoji strings as icons. You can also use HTML entities, Font Awesome classes,
|
|
809
|
+
or any HTML string for the icons.
|
|
810
|
+
</Typography>
|
|
811
|
+
</CollapsibleLayout>
|
|
812
|
+
|
|
813
|
+
<CollapsibleLayout
|
|
814
|
+
title="No Custom Icons"
|
|
815
|
+
subtitle="Uses default visibility icons"
|
|
816
|
+
triggerArea="both"
|
|
817
|
+
defaultCollapsed={false}
|
|
818
|
+
variant="outlined"
|
|
819
|
+
>
|
|
820
|
+
<Typography>
|
|
821
|
+
Without custom icons, the default Visibility/VisibilityOff icons are used from Material-UI.
|
|
822
|
+
</Typography>
|
|
823
|
+
</CollapsibleLayout>
|
|
824
|
+
</Stack>
|
|
825
|
+
</QwickApp>
|
|
826
|
+
),
|
|
827
|
+
parameters: {
|
|
828
|
+
docs: {
|
|
829
|
+
description: {
|
|
830
|
+
story: 'Custom toggle icons using React components, HTML strings, or default icons.',
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
},
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
export const DisabledState: Story = {
|
|
837
|
+
render: () => {
|
|
838
|
+
const [disabled, setDisabled] = useState(false);
|
|
839
|
+
|
|
840
|
+
return (
|
|
841
|
+
<QwickApp appId="collapsible-disabled" appName='Disabled State'>
|
|
842
|
+
<Stack spacing={2}>
|
|
843
|
+
<Box>
|
|
844
|
+
<FormControlLabel
|
|
845
|
+
control={
|
|
846
|
+
<Switch
|
|
847
|
+
checked={disabled}
|
|
848
|
+
onChange={(e) => setDisabled(e.target.checked)}
|
|
849
|
+
/>
|
|
850
|
+
}
|
|
851
|
+
label="Simulate disabled state"
|
|
852
|
+
/>
|
|
853
|
+
<Typography variant="caption" display="block" color="text.secondary">
|
|
854
|
+
Note: There's no built-in disabled prop, but you can simulate it by removing event handlers
|
|
855
|
+
</Typography>
|
|
856
|
+
</Box>
|
|
857
|
+
|
|
858
|
+
<CollapsibleLayout
|
|
859
|
+
title="Conditional Functionality"
|
|
860
|
+
subtitle={disabled ? "Functionality disabled" : "Click to toggle"}
|
|
861
|
+
defaultCollapsed={false}
|
|
862
|
+
variant="outlined"
|
|
863
|
+
onToggle={disabled ? undefined : (collapsed) => console.log('Toggled:', collapsed)}
|
|
864
|
+
triggerArea={disabled ? undefined : "both"}
|
|
865
|
+
sx={{ opacity: disabled ? 0.6 : 1, cursor: disabled ? 'not-allowed' : 'default' }}
|
|
866
|
+
>
|
|
867
|
+
<Typography>
|
|
868
|
+
{disabled
|
|
869
|
+
? "This content cannot be toggled because the component is in a disabled-like state."
|
|
870
|
+
: "This content can be toggled normally. Use the switch above to simulate a disabled state."
|
|
871
|
+
}
|
|
872
|
+
</Typography>
|
|
873
|
+
</CollapsibleLayout>
|
|
874
|
+
</Stack>
|
|
875
|
+
</QwickApp>
|
|
876
|
+
);
|
|
877
|
+
},
|
|
878
|
+
parameters: {
|
|
879
|
+
docs: {
|
|
880
|
+
description: {
|
|
881
|
+
story: 'Demonstrating how to create a disabled-like state by conditionally removing event handlers.',
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
// ============================================
|
|
888
|
+
// ANIMATION STORIES
|
|
889
|
+
// ============================================
|
|
890
|
+
|
|
891
|
+
export const AnimationStyles: Story = {
|
|
892
|
+
render: () => (
|
|
893
|
+
<QwickApp appId="collapsible-animations" appName='Animation Styles'>
|
|
894
|
+
<Stack spacing={3}>
|
|
895
|
+
<CollapsibleLayout
|
|
896
|
+
title="Fade Animation"
|
|
897
|
+
subtitle="Content fades in/out"
|
|
898
|
+
animationStyle="fade"
|
|
899
|
+
defaultCollapsed={true}
|
|
900
|
+
variant="outlined"
|
|
901
|
+
>
|
|
902
|
+
<Typography>
|
|
903
|
+
This content uses fade animation. The opacity transitions smoothly when expanding/collapsing.
|
|
904
|
+
Great for subtle, elegant transitions.
|
|
905
|
+
</Typography>
|
|
906
|
+
</CollapsibleLayout>
|
|
907
|
+
|
|
908
|
+
<CollapsibleLayout
|
|
909
|
+
title="Slide Animation (Default)"
|
|
910
|
+
subtitle="Content slides down/up"
|
|
911
|
+
animationStyle="slide"
|
|
912
|
+
defaultCollapsed={true}
|
|
913
|
+
variant="outlined"
|
|
914
|
+
>
|
|
915
|
+
<Typography>
|
|
916
|
+
This content uses slide animation (the default). Height transitions create a smooth
|
|
917
|
+
sliding effect. Most commonly used animation style.
|
|
918
|
+
</Typography>
|
|
919
|
+
</CollapsibleLayout>
|
|
920
|
+
|
|
921
|
+
<CollapsibleLayout
|
|
922
|
+
title="Scale Animation"
|
|
923
|
+
subtitle="Content scales and fades"
|
|
924
|
+
animationStyle="scale"
|
|
925
|
+
defaultCollapsed={true}
|
|
926
|
+
variant="outlined"
|
|
927
|
+
>
|
|
928
|
+
<Typography>
|
|
929
|
+
This content uses scale animation. It combines scaling and fading for a dynamic,
|
|
930
|
+
attention-grabbing transition effect.
|
|
931
|
+
</Typography>
|
|
932
|
+
</CollapsibleLayout>
|
|
933
|
+
|
|
934
|
+
<CollapsibleLayout
|
|
935
|
+
title="No Animation"
|
|
936
|
+
subtitle="Instant toggle"
|
|
937
|
+
animationStyle="slide"
|
|
938
|
+
disableAnimations={true}
|
|
939
|
+
defaultCollapsed={true}
|
|
940
|
+
variant="outlined"
|
|
941
|
+
>
|
|
942
|
+
<Typography>
|
|
943
|
+
This content has animations disabled with disableAnimations={true}.
|
|
944
|
+
The content appears/disappears instantly without any transition.
|
|
945
|
+
</Typography>
|
|
946
|
+
</CollapsibleLayout>
|
|
947
|
+
</Stack>
|
|
948
|
+
</QwickApp>
|
|
949
|
+
),
|
|
950
|
+
parameters: {
|
|
951
|
+
docs: {
|
|
952
|
+
description: {
|
|
953
|
+
story: 'Different animation styles: fade, slide (default), scale, and disabled animations.',
|
|
954
|
+
},
|
|
955
|
+
},
|
|
956
|
+
},
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
export const CustomAnimationDuration: Story = {
|
|
960
|
+
render: () => (
|
|
961
|
+
<QwickApp appId="collapsible-duration" appName='Animation Duration'>
|
|
962
|
+
<Stack spacing={3}>
|
|
963
|
+
<CollapsibleLayout
|
|
964
|
+
title="Fast Animation (150ms)"
|
|
965
|
+
subtitle="Quick transitions"
|
|
966
|
+
animationDuration={150}
|
|
967
|
+
defaultCollapsed={true}
|
|
968
|
+
variant="outlined"
|
|
969
|
+
>
|
|
970
|
+
<Typography>
|
|
971
|
+
This section uses a fast animation duration of 150ms for snappy, responsive transitions.
|
|
972
|
+
Good for frequently toggled sections.
|
|
973
|
+
</Typography>
|
|
974
|
+
</CollapsibleLayout>
|
|
975
|
+
|
|
976
|
+
<CollapsibleLayout
|
|
977
|
+
title="Default Animation (300ms)"
|
|
978
|
+
subtitle="Standard timing"
|
|
979
|
+
animationDuration={300}
|
|
980
|
+
defaultCollapsed={true}
|
|
981
|
+
variant="outlined"
|
|
982
|
+
>
|
|
983
|
+
<Typography>
|
|
984
|
+
This section uses the default animation duration of 300ms. This provides a good balance
|
|
985
|
+
between perceived performance and smooth visual feedback.
|
|
986
|
+
</Typography>
|
|
987
|
+
</CollapsibleLayout>
|
|
988
|
+
|
|
989
|
+
<CollapsibleLayout
|
|
990
|
+
title="Slow Animation (800ms)"
|
|
991
|
+
subtitle="Deliberate transitions"
|
|
992
|
+
animationDuration={800}
|
|
993
|
+
defaultCollapsed={true}
|
|
994
|
+
variant="outlined"
|
|
995
|
+
>
|
|
996
|
+
<Typography>
|
|
997
|
+
This section uses a slow animation duration of 800ms for more deliberate, dramatic transitions.
|
|
998
|
+
Can be used for emphasis or when the content change is significant.
|
|
999
|
+
</Typography>
|
|
1000
|
+
</CollapsibleLayout>
|
|
1001
|
+
</Stack>
|
|
1002
|
+
</QwickApp>
|
|
1003
|
+
),
|
|
1004
|
+
parameters: {
|
|
1005
|
+
docs: {
|
|
1006
|
+
description: {
|
|
1007
|
+
story: 'Different animation durations: fast (150ms), default (300ms), and slow (800ms).',
|
|
1008
|
+
},
|
|
1009
|
+
},
|
|
1010
|
+
},
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
// ============================================
|
|
1014
|
+
// SPACING STORIES
|
|
1015
|
+
// ============================================
|
|
1016
|
+
|
|
1017
|
+
export const SpacingVariations: Story = {
|
|
1018
|
+
render: () => (
|
|
1019
|
+
<QwickApp appId="collapsible-spacing" appName='Spacing Variations'>
|
|
1020
|
+
<Stack spacing={3}>
|
|
1021
|
+
<CollapsibleLayout
|
|
1022
|
+
title="Compact Spacing"
|
|
1023
|
+
subtitle="Minimal padding for dense layouts"
|
|
1024
|
+
headerSpacing="compact"
|
|
1025
|
+
contentSpacing="compact"
|
|
1026
|
+
defaultCollapsed={false}
|
|
1027
|
+
variant="outlined"
|
|
1028
|
+
>
|
|
1029
|
+
<Typography>
|
|
1030
|
+
This layout uses compact spacing for both header and content. Perfect for dense interfaces,
|
|
1031
|
+
dashboards, or when you need to fit more content in limited space.
|
|
1032
|
+
</Typography>
|
|
1033
|
+
</CollapsibleLayout>
|
|
1034
|
+
|
|
1035
|
+
<CollapsibleLayout
|
|
1036
|
+
title="Comfortable Spacing (Default)"
|
|
1037
|
+
subtitle="Balanced padding for most use cases"
|
|
1038
|
+
headerSpacing="comfortable"
|
|
1039
|
+
contentSpacing="comfortable"
|
|
1040
|
+
defaultCollapsed={false}
|
|
1041
|
+
variant="outlined"
|
|
1042
|
+
>
|
|
1043
|
+
<Typography>
|
|
1044
|
+
This layout uses comfortable spacing (the default). This provides a good balance between
|
|
1045
|
+
content density and visual breathing room, suitable for most applications.
|
|
1046
|
+
</Typography>
|
|
1047
|
+
</CollapsibleLayout>
|
|
1048
|
+
|
|
1049
|
+
<CollapsibleLayout
|
|
1050
|
+
title="Spacious Layout"
|
|
1051
|
+
subtitle="Generous padding for premium feel"
|
|
1052
|
+
headerSpacing="spacious"
|
|
1053
|
+
contentSpacing="spacious"
|
|
1054
|
+
defaultCollapsed={false}
|
|
1055
|
+
variant="outlined"
|
|
1056
|
+
>
|
|
1057
|
+
<Typography>
|
|
1058
|
+
This layout uses spacious padding for both header and content. Creates a more premium,
|
|
1059
|
+
luxurious feel with plenty of whitespace. Good for marketing pages or feature highlights.
|
|
1060
|
+
</Typography>
|
|
1061
|
+
</CollapsibleLayout>
|
|
1062
|
+
|
|
1063
|
+
<CollapsibleLayout
|
|
1064
|
+
title="Mixed Spacing"
|
|
1065
|
+
subtitle="Compact header with spacious content"
|
|
1066
|
+
headerSpacing="compact"
|
|
1067
|
+
contentSpacing="spacious"
|
|
1068
|
+
defaultCollapsed={false}
|
|
1069
|
+
variant="outlined"
|
|
1070
|
+
>
|
|
1071
|
+
<Typography>
|
|
1072
|
+
This layout demonstrates mixed spacing: compact header to save vertical space,
|
|
1073
|
+
but spacious content for better readability. You can mix and match as needed.
|
|
1074
|
+
</Typography>
|
|
1075
|
+
</CollapsibleLayout>
|
|
1076
|
+
</Stack>
|
|
1077
|
+
</QwickApp>
|
|
1078
|
+
),
|
|
1079
|
+
parameters: {
|
|
1080
|
+
docs: {
|
|
1081
|
+
description: {
|
|
1082
|
+
story: 'Different spacing options: compact, comfortable (default), spacious, and mixed combinations.',
|
|
1083
|
+
},
|
|
1084
|
+
},
|
|
1085
|
+
},
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
// ============================================
|
|
1089
|
+
// ADVANCED STORIES
|
|
1090
|
+
// ============================================
|
|
1091
|
+
|
|
1092
|
+
export const MultipleCollapsibleLayouts: Story = {
|
|
1093
|
+
render: () => (
|
|
1094
|
+
<QwickApp appId="collapsible-multiple" appName='Multiple CollapsibleLayouts'>
|
|
1095
|
+
<Stack spacing={2}>
|
|
1096
|
+
<Typography variant="h5" gutterBottom>
|
|
1097
|
+
Settings Dashboard
|
|
1098
|
+
</Typography>
|
|
1099
|
+
|
|
1100
|
+
<CollapsibleLayout
|
|
1101
|
+
title="Account Settings"
|
|
1102
|
+
subtitle="Profile, security, and preferences"
|
|
1103
|
+
defaultCollapsed={false}
|
|
1104
|
+
variant="outlined"
|
|
1105
|
+
leadIcon={<PersonIcon color="primary" />}
|
|
1106
|
+
>
|
|
1107
|
+
<Stack spacing={2}>
|
|
1108
|
+
<TextField label="Display Name" defaultValue="John Doe" size="small" />
|
|
1109
|
+
<TextField label="Email" defaultValue="john@example.com" size="small" />
|
|
1110
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Email notifications" />
|
|
1111
|
+
</Stack>
|
|
1112
|
+
</CollapsibleLayout>
|
|
1113
|
+
|
|
1114
|
+
<CollapsibleLayout
|
|
1115
|
+
title="Privacy Settings"
|
|
1116
|
+
subtitle="Data usage and visibility preferences"
|
|
1117
|
+
defaultCollapsed={true}
|
|
1118
|
+
variant="outlined"
|
|
1119
|
+
leadIcon={<VisibilityIcon color="secondary" />}
|
|
1120
|
+
>
|
|
1121
|
+
<Stack spacing={2}>
|
|
1122
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Public profile" />
|
|
1123
|
+
<FormControlLabel control={<Switch />} label="Show online status" />
|
|
1124
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Allow friend requests" />
|
|
1125
|
+
</Stack>
|
|
1126
|
+
</CollapsibleLayout>
|
|
1127
|
+
|
|
1128
|
+
<CollapsibleLayout
|
|
1129
|
+
title="Advanced Settings"
|
|
1130
|
+
subtitle="Developer and system options"
|
|
1131
|
+
defaultCollapsed={true}
|
|
1132
|
+
variant="outlined"
|
|
1133
|
+
leadIcon={<SettingsIcon color="action" />}
|
|
1134
|
+
headerActions={
|
|
1135
|
+
<Chip label="Expert" color="warning" size="small" />
|
|
1136
|
+
}
|
|
1137
|
+
>
|
|
1138
|
+
<Stack spacing={2}>
|
|
1139
|
+
<Alert severity="warning">
|
|
1140
|
+
These settings are for advanced users only. Changing these may affect application behavior.
|
|
1141
|
+
</Alert>
|
|
1142
|
+
<FormControlLabel control={<Switch />} label="Debug mode" />
|
|
1143
|
+
<FormControlLabel control={<Switch />} label="Beta features" />
|
|
1144
|
+
<TextField label="API Endpoint" defaultValue="https://api.example.com" size="small" fullWidth />
|
|
1145
|
+
</Stack>
|
|
1146
|
+
</CollapsibleLayout>
|
|
1147
|
+
</Stack>
|
|
1148
|
+
</QwickApp>
|
|
1149
|
+
),
|
|
1150
|
+
parameters: {
|
|
1151
|
+
docs: {
|
|
1152
|
+
description: {
|
|
1153
|
+
story: 'Multiple CollapsibleLayout sections working together in a settings dashboard interface.',
|
|
1154
|
+
},
|
|
1155
|
+
},
|
|
1156
|
+
},
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
export const NestedCollapsibleLayouts: Story = {
|
|
1160
|
+
render: () => (
|
|
1161
|
+
<QwickApp appId="collapsible-nested" appName='Nested CollapsibleLayouts'>
|
|
1162
|
+
<CollapsibleLayout
|
|
1163
|
+
title="Project Configuration"
|
|
1164
|
+
subtitle="Comprehensive project settings and options"
|
|
1165
|
+
defaultCollapsed={false}
|
|
1166
|
+
variant="elevated"
|
|
1167
|
+
leadIcon={<BusinessIcon />}
|
|
1168
|
+
>
|
|
1169
|
+
<Stack spacing={2}>
|
|
1170
|
+
<Typography variant="h6">Basic Information</Typography>
|
|
1171
|
+
<TextField label="Project Name" defaultValue="My Awesome Project" fullWidth />
|
|
1172
|
+
|
|
1173
|
+
<CollapsibleLayout
|
|
1174
|
+
title="Build Settings"
|
|
1175
|
+
subtitle="Compilation and deployment options"
|
|
1176
|
+
defaultCollapsed={true}
|
|
1177
|
+
variant="outlined"
|
|
1178
|
+
headerSpacing="compact"
|
|
1179
|
+
contentSpacing="compact"
|
|
1180
|
+
>
|
|
1181
|
+
<Stack spacing={1}>
|
|
1182
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Enable minification" />
|
|
1183
|
+
<FormControlLabel control={<Switch />} label="Source maps" />
|
|
1184
|
+
<TextField label="Output directory" defaultValue="./dist" size="small" />
|
|
1185
|
+
</Stack>
|
|
1186
|
+
</CollapsibleLayout>
|
|
1187
|
+
|
|
1188
|
+
<CollapsibleLayout
|
|
1189
|
+
title="Environment Variables"
|
|
1190
|
+
subtitle="Configure environment-specific values"
|
|
1191
|
+
defaultCollapsed={true}
|
|
1192
|
+
variant="outlined"
|
|
1193
|
+
headerSpacing="compact"
|
|
1194
|
+
contentSpacing="compact"
|
|
1195
|
+
>
|
|
1196
|
+
<Stack spacing={1}>
|
|
1197
|
+
<TextField label="API_URL" defaultValue="https://api.prod.example.com" size="small" />
|
|
1198
|
+
<TextField label="APP_ENV" defaultValue="production" size="small" />
|
|
1199
|
+
|
|
1200
|
+
<CollapsibleLayout
|
|
1201
|
+
title="Development Overrides"
|
|
1202
|
+
subtitle="Values for development environment"
|
|
1203
|
+
defaultCollapsed={true}
|
|
1204
|
+
variant="default"
|
|
1205
|
+
headerSpacing="compact"
|
|
1206
|
+
contentSpacing="compact"
|
|
1207
|
+
showDivider={false}
|
|
1208
|
+
>
|
|
1209
|
+
<Stack spacing={1}>
|
|
1210
|
+
<TextField label="DEV_API_URL" defaultValue="http://localhost:3000" size="small" />
|
|
1211
|
+
<TextField label="DEBUG_LEVEL" defaultValue="verbose" size="small" />
|
|
1212
|
+
</Stack>
|
|
1213
|
+
</CollapsibleLayout>
|
|
1214
|
+
</Stack>
|
|
1215
|
+
</CollapsibleLayout>
|
|
1216
|
+
|
|
1217
|
+
<CollapsibleLayout
|
|
1218
|
+
title="Security Settings"
|
|
1219
|
+
subtitle="Authentication and authorization"
|
|
1220
|
+
defaultCollapsed={true}
|
|
1221
|
+
variant="outlined"
|
|
1222
|
+
headerSpacing="compact"
|
|
1223
|
+
contentSpacing="compact"
|
|
1224
|
+
>
|
|
1225
|
+
<Stack spacing={1}>
|
|
1226
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Require authentication" />
|
|
1227
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Enable CORS" />
|
|
1228
|
+
<TextField label="Allowed origins" defaultValue="*.example.com" size="small" />
|
|
1229
|
+
</Stack>
|
|
1230
|
+
</CollapsibleLayout>
|
|
1231
|
+
</Stack>
|
|
1232
|
+
</CollapsibleLayout>
|
|
1233
|
+
</QwickApp>
|
|
1234
|
+
),
|
|
1235
|
+
parameters: {
|
|
1236
|
+
docs: {
|
|
1237
|
+
description: {
|
|
1238
|
+
story: 'Nested CollapsibleLayout sections creating a hierarchical configuration interface with multiple levels.',
|
|
1239
|
+
},
|
|
1240
|
+
},
|
|
1241
|
+
},
|
|
1242
|
+
};
|
|
1243
|
+
|
|
1244
|
+
export const WithDataBinding: Story = {
|
|
1245
|
+
render: () => (
|
|
1246
|
+
<QwickApp appId="collapsible-databinding" appName='Data Binding' dataSource={{ dataProvider }}>
|
|
1247
|
+
<Stack spacing={3}>
|
|
1248
|
+
<Box sx={{ p: 3, backgroundColor: 'background.paper', borderRadius: 1 }}>
|
|
1249
|
+
<Typography variant="h5" gutterBottom>📊 Data-Driven CollapsibleLayouts</Typography>
|
|
1250
|
+
<Typography variant="body1" sx={{ mb: 2, opacity: 0.8 }}>
|
|
1251
|
+
CollapsibleLayout components can be completely driven by CMS data, loading configuration
|
|
1252
|
+
and content from your data source.
|
|
1253
|
+
</Typography>
|
|
1254
|
+
|
|
1255
|
+
<Code title="Usage" language="tsx">{`<CollapsibleLayout dataSource="collapsible-layouts.simple-card" />`}</Code>
|
|
1256
|
+
</Box>
|
|
1257
|
+
|
|
1258
|
+
<CollapsibleLayout dataSource="collapsible-layouts.simple-card">
|
|
1259
|
+
<Stack spacing={2}>
|
|
1260
|
+
<TextField label="Full Name" defaultValue="John Doe" />
|
|
1261
|
+
<TextField label="Email Address" defaultValue="john.doe@example.com" />
|
|
1262
|
+
<TextField label="Phone Number" defaultValue="+1 (555) 123-4567" />
|
|
1263
|
+
<TextField label="Company" defaultValue="Acme Corporation" />
|
|
1264
|
+
</Stack>
|
|
1265
|
+
</CollapsibleLayout>
|
|
1266
|
+
|
|
1267
|
+
<CollapsibleLayout dataSource="collapsible-layouts.settings-panel">
|
|
1268
|
+
<Stack spacing={2}>
|
|
1269
|
+
<FormControlLabel control={<Switch />} label="Enable advanced features" />
|
|
1270
|
+
<FormControlLabel control={<Switch defaultChecked />} label="Auto-save changes" />
|
|
1271
|
+
<TextField label="Session timeout (minutes)" defaultValue="30" type="number" />
|
|
1272
|
+
<TextField
|
|
1273
|
+
label="Notification preferences"
|
|
1274
|
+
select
|
|
1275
|
+
defaultValue="email"
|
|
1276
|
+
SelectProps={{ native: true }}
|
|
1277
|
+
>
|
|
1278
|
+
<option value="email">Email only</option>
|
|
1279
|
+
<option value="push">Push only</option>
|
|
1280
|
+
<option value="both">Both</option>
|
|
1281
|
+
<option value="none">None</option>
|
|
1282
|
+
</TextField>
|
|
1283
|
+
</Stack>
|
|
1284
|
+
</CollapsibleLayout>
|
|
1285
|
+
|
|
1286
|
+
<CollapsibleLayout dataSource="collapsible-layouts.notification-center">
|
|
1287
|
+
<List dense>
|
|
1288
|
+
<ListItem>
|
|
1289
|
+
<ListItemAvatar>
|
|
1290
|
+
<Avatar>
|
|
1291
|
+
<InfoIcon />
|
|
1292
|
+
</Avatar>
|
|
1293
|
+
</ListItemAvatar>
|
|
1294
|
+
<ListItemText
|
|
1295
|
+
primary="System Update Available"
|
|
1296
|
+
secondary="Version 2.1.0 includes bug fixes and performance improvements"
|
|
1297
|
+
/>
|
|
1298
|
+
</ListItem>
|
|
1299
|
+
<ListItem>
|
|
1300
|
+
<ListItemAvatar>
|
|
1301
|
+
<Avatar>
|
|
1302
|
+
<CheckCircleIcon />
|
|
1303
|
+
</Avatar>
|
|
1304
|
+
</ListItemAvatar>
|
|
1305
|
+
<ListItemText
|
|
1306
|
+
primary="Backup Completed"
|
|
1307
|
+
secondary="Daily backup completed successfully at 3:00 AM"
|
|
1308
|
+
/>
|
|
1309
|
+
</ListItem>
|
|
1310
|
+
<ListItem>
|
|
1311
|
+
<ListItemAvatar>
|
|
1312
|
+
<Avatar>
|
|
1313
|
+
<WarningIcon />
|
|
1314
|
+
</Avatar>
|
|
1315
|
+
</ListItemAvatar>
|
|
1316
|
+
<ListItemText
|
|
1317
|
+
primary="Storage Usage Warning"
|
|
1318
|
+
secondary="You are using 85% of your storage quota"
|
|
1319
|
+
/>
|
|
1320
|
+
</ListItem>
|
|
1321
|
+
</List>
|
|
1322
|
+
</CollapsibleLayout>
|
|
1323
|
+
</Stack>
|
|
1324
|
+
</QwickApp>
|
|
1325
|
+
),
|
|
1326
|
+
parameters: {
|
|
1327
|
+
docs: {
|
|
1328
|
+
description: {
|
|
1329
|
+
story: 'CollapsibleLayout components configured entirely through data binding with CMS data sources.',
|
|
1330
|
+
},
|
|
1331
|
+
},
|
|
1332
|
+
},
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
export const RealWorldExamples: Story = {
|
|
1336
|
+
render: () => (
|
|
1337
|
+
<QwickApp appId="collapsible-realworld" appName='Real World Examples'>
|
|
1338
|
+
<Stack spacing={4}>
|
|
1339
|
+
{/* FAQ Section */}
|
|
1340
|
+
<Box>
|
|
1341
|
+
<Typography variant="h4" gutterBottom>Frequently Asked Questions</Typography>
|
|
1342
|
+
<Stack spacing={2}>
|
|
1343
|
+
<CollapsibleLayout
|
|
1344
|
+
title="How do I integrate CollapsibleLayout with my CMS?"
|
|
1345
|
+
subtitle="Click to view integration steps"
|
|
1346
|
+
defaultCollapsed={true}
|
|
1347
|
+
variant="outlined"
|
|
1348
|
+
collapsedView={
|
|
1349
|
+
<Typography variant="body2" color="text.secondary" sx={{ fontStyle: 'italic' }}>
|
|
1350
|
+
Integration involves setting up data providers and configuring data sources...
|
|
1351
|
+
</Typography>
|
|
1352
|
+
}
|
|
1353
|
+
>
|
|
1354
|
+
<Stack spacing={2}>
|
|
1355
|
+
<Typography>
|
|
1356
|
+
Integration with CMS systems is straightforward using the dataSource prop:
|
|
1357
|
+
</Typography>
|
|
1358
|
+
<Code language="tsx">{`// 1. Set up your data provider
|
|
1359
|
+
const cmsProvider = new JsonDataProvider({
|
|
1360
|
+
data: yourCmsData
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
// 2. Use CollapsibleLayout with data binding
|
|
1364
|
+
<CollapsibleLayout dataSource="faq.integration" />`}</Code>
|
|
1365
|
+
<Typography>
|
|
1366
|
+
The component will automatically load title, content, styling, and behavior
|
|
1367
|
+
configuration from your CMS data structure.
|
|
1368
|
+
</Typography>
|
|
1369
|
+
</Stack>
|
|
1370
|
+
</CollapsibleLayout>
|
|
1371
|
+
|
|
1372
|
+
<CollapsibleLayout
|
|
1373
|
+
title="Can I customize the animations and styling?"
|
|
1374
|
+
subtitle="Comprehensive customization options"
|
|
1375
|
+
defaultCollapsed={true}
|
|
1376
|
+
variant="outlined"
|
|
1377
|
+
>
|
|
1378
|
+
<Typography>
|
|
1379
|
+
Yes! CollapsibleLayout offers extensive customization options:
|
|
1380
|
+
</Typography>
|
|
1381
|
+
<ul>
|
|
1382
|
+
<li><strong>Animation styles:</strong> fade, slide, scale, or disabled</li>
|
|
1383
|
+
<li><strong>Visual variants:</strong> default, outlined, elevated, filled</li>
|
|
1384
|
+
<li><strong>Spacing options:</strong> compact, comfortable, spacious</li>
|
|
1385
|
+
<li><strong>Custom icons:</strong> React components or HTML strings</li>
|
|
1386
|
+
<li><strong>Trigger areas:</strong> header, button, or both</li>
|
|
1387
|
+
</ul>
|
|
1388
|
+
</CollapsibleLayout>
|
|
1389
|
+
|
|
1390
|
+
<CollapsibleLayout
|
|
1391
|
+
title="How does state persistence work?"
|
|
1392
|
+
subtitle="LocalStorage integration details"
|
|
1393
|
+
defaultCollapsed={true}
|
|
1394
|
+
variant="outlined"
|
|
1395
|
+
>
|
|
1396
|
+
<Typography>
|
|
1397
|
+
State persistence uses localStorage to remember collapsed/expanded state:
|
|
1398
|
+
</Typography>
|
|
1399
|
+
<Code language="tsx">{`<CollapsibleLayout
|
|
1400
|
+
persistState={true}
|
|
1401
|
+
storageKey="unique-section-id"
|
|
1402
|
+
title="Remembered Section"
|
|
1403
|
+
/>`}</Code>
|
|
1404
|
+
<Typography sx={{ mt: 2 }}>
|
|
1405
|
+
The component will automatically save state changes and restore them when the page reloads.
|
|
1406
|
+
Each section needs a unique storageKey to avoid conflicts.
|
|
1407
|
+
</Typography>
|
|
1408
|
+
</CollapsibleLayout>
|
|
1409
|
+
</Stack>
|
|
1410
|
+
</Box>
|
|
1411
|
+
|
|
1412
|
+
{/* Dashboard Widget */}
|
|
1413
|
+
<Box>
|
|
1414
|
+
<Typography variant="h4" gutterBottom>Dashboard Widget Example</Typography>
|
|
1415
|
+
<Card>
|
|
1416
|
+
<CollapsibleLayout
|
|
1417
|
+
title="Sales Performance"
|
|
1418
|
+
subtitle="Q4 2024 metrics and trends"
|
|
1419
|
+
variant="default"
|
|
1420
|
+
headerActions={
|
|
1421
|
+
<Box sx={{ display: 'flex', gap: 1 }}>
|
|
1422
|
+
<Chip label="Live" color="success" size="small" />
|
|
1423
|
+
<Button size="small" variant="text">Export</Button>
|
|
1424
|
+
</Box>
|
|
1425
|
+
}
|
|
1426
|
+
leadIcon={<Box sx={{ color: 'success.main' }}>📈</Box>}
|
|
1427
|
+
defaultCollapsed={false}
|
|
1428
|
+
>
|
|
1429
|
+
<CardContent>
|
|
1430
|
+
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 2, mb: 3 }}>
|
|
1431
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
1432
|
+
<Typography variant="h5" color="success.main">$124K</Typography>
|
|
1433
|
+
<Typography variant="caption">Revenue</Typography>
|
|
1434
|
+
</Paper>
|
|
1435
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
1436
|
+
<Typography variant="h5" color="primary.main">856</Typography>
|
|
1437
|
+
<Typography variant="caption">Orders</Typography>
|
|
1438
|
+
</Paper>
|
|
1439
|
+
<Paper sx={{ p: 2, textAlign: 'center' }}>
|
|
1440
|
+
<Typography variant="h5" color="warning.main">12%</Typography>
|
|
1441
|
+
<Typography variant="caption">Growth</Typography>
|
|
1442
|
+
</Paper>
|
|
1443
|
+
</Box>
|
|
1444
|
+
<LinearProgress variant="determinate" value={78} sx={{ mb: 1 }} />
|
|
1445
|
+
<Typography variant="body2" color="text.secondary">
|
|
1446
|
+
78% of quarterly target achieved
|
|
1447
|
+
</Typography>
|
|
1448
|
+
</CardContent>
|
|
1449
|
+
</CollapsibleLayout>
|
|
1450
|
+
</Card>
|
|
1451
|
+
</Box>
|
|
1452
|
+
|
|
1453
|
+
{/* Form Section */}
|
|
1454
|
+
<Box>
|
|
1455
|
+
<Typography variant="h4" gutterBottom>Form Organization</Typography>
|
|
1456
|
+
<Paper sx={{ p: 2 }}>
|
|
1457
|
+
<CollapsibleLayout
|
|
1458
|
+
title="Personal Information"
|
|
1459
|
+
subtitle="Basic details and contact information"
|
|
1460
|
+
defaultCollapsed={false}
|
|
1461
|
+
variant="default"
|
|
1462
|
+
showDivider={true}
|
|
1463
|
+
>
|
|
1464
|
+
<Stack spacing={2} sx={{ pt: 2 }}>
|
|
1465
|
+
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 2 }}>
|
|
1466
|
+
<TextField label="First Name" defaultValue="John" />
|
|
1467
|
+
<TextField label="Last Name" defaultValue="Doe" />
|
|
1468
|
+
</Box>
|
|
1469
|
+
<TextField label="Email Address" defaultValue="john.doe@example.com" fullWidth />
|
|
1470
|
+
<TextField label="Phone Number" defaultValue="+1 (555) 123-4567" fullWidth />
|
|
1471
|
+
</Stack>
|
|
1472
|
+
</CollapsibleLayout>
|
|
1473
|
+
|
|
1474
|
+
<CollapsibleLayout
|
|
1475
|
+
title="Address Information"
|
|
1476
|
+
subtitle="Billing and shipping addresses"
|
|
1477
|
+
defaultCollapsed={true}
|
|
1478
|
+
variant="default"
|
|
1479
|
+
showDivider={true}
|
|
1480
|
+
>
|
|
1481
|
+
<Stack spacing={2} sx={{ pt: 2 }}>
|
|
1482
|
+
<TextField label="Street Address" fullWidth />
|
|
1483
|
+
<Box sx={{ display: 'grid', gridTemplateColumns: '2fr 1fr 1fr', gap: 2 }}>
|
|
1484
|
+
<TextField label="City" />
|
|
1485
|
+
<TextField label="State" />
|
|
1486
|
+
<TextField label="ZIP Code" />
|
|
1487
|
+
</Box>
|
|
1488
|
+
<TextField label="Country" fullWidth />
|
|
1489
|
+
</Stack>
|
|
1490
|
+
</CollapsibleLayout>
|
|
1491
|
+
|
|
1492
|
+
<CollapsibleLayout
|
|
1493
|
+
title="Additional Options"
|
|
1494
|
+
subtitle="Preferences and special requests"
|
|
1495
|
+
defaultCollapsed={true}
|
|
1496
|
+
variant="default"
|
|
1497
|
+
>
|
|
1498
|
+
<Stack spacing={2} sx={{ pt: 2 }}>
|
|
1499
|
+
<FormControlLabel control={<Switch />} label="Subscribe to newsletter" />
|
|
1500
|
+
<FormControlLabel control={<Switch />} label="Receive SMS notifications" />
|
|
1501
|
+
<TextField
|
|
1502
|
+
label="Special Instructions"
|
|
1503
|
+
multiline
|
|
1504
|
+
rows={3}
|
|
1505
|
+
fullWidth
|
|
1506
|
+
placeholder="Any special requests or instructions..."
|
|
1507
|
+
/>
|
|
1508
|
+
</Stack>
|
|
1509
|
+
</CollapsibleLayout>
|
|
1510
|
+
|
|
1511
|
+
<Box sx={{ mt: 3, display: 'flex', gap: 2 }}>
|
|
1512
|
+
<Button variant="contained" size="large">
|
|
1513
|
+
Save Information
|
|
1514
|
+
</Button>
|
|
1515
|
+
<Button variant="outlined" size="large">
|
|
1516
|
+
Cancel
|
|
1517
|
+
</Button>
|
|
1518
|
+
</Box>
|
|
1519
|
+
</Paper>
|
|
1520
|
+
</Box>
|
|
1521
|
+
</Stack>
|
|
1522
|
+
</QwickApp>
|
|
1523
|
+
),
|
|
1524
|
+
parameters: {
|
|
1525
|
+
docs: {
|
|
1526
|
+
description: {
|
|
1527
|
+
story: 'Real-world examples: FAQ sections, dashboard widgets, and organized form layouts.',
|
|
1528
|
+
},
|
|
1529
|
+
},
|
|
1530
|
+
},
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
// ============================================
|
|
1534
|
+
// PLAYGROUND STORY
|
|
1535
|
+
// ============================================
|
|
1536
|
+
|
|
1537
|
+
export const Playground: Story = {
|
|
1538
|
+
args: {
|
|
1539
|
+
title: 'Playground CollapsibleLayout',
|
|
1540
|
+
subtitle: 'Experiment with all the props and see the results',
|
|
1541
|
+
children: 'This is the main content area. You can customize all aspects of this CollapsibleLayout using the controls panel on the right. Try changing the variant, animation style, spacing, and other properties to see how they affect the appearance and behavior.',
|
|
1542
|
+
defaultCollapsed: false,
|
|
1543
|
+
variant: 'outlined',
|
|
1544
|
+
headerSpacing: 'comfortable',
|
|
1545
|
+
contentSpacing: 'comfortable',
|
|
1546
|
+
animationStyle: 'slide',
|
|
1547
|
+
animationDuration: 300,
|
|
1548
|
+
triggerArea: 'header',
|
|
1549
|
+
showDivider: true,
|
|
1550
|
+
disableAnimations: false,
|
|
1551
|
+
persistState: false,
|
|
1552
|
+
toggleAriaLabel: 'Toggle content visibility',
|
|
1553
|
+
},
|
|
1554
|
+
render: (args) => (
|
|
1555
|
+
<QwickApp appId="collapsible-playground" appName='CollapsibleLayout Playground'>
|
|
1556
|
+
<CollapsibleLayout {...args} />
|
|
1557
|
+
</QwickApp>
|
|
1558
|
+
),
|
|
1559
|
+
parameters: {
|
|
1560
|
+
docs: {
|
|
1561
|
+
description: {
|
|
1562
|
+
story: 'Interactive playground to experiment with all CollapsibleLayout props and see real-time results.',
|
|
1563
|
+
},
|
|
1564
|
+
},
|
|
1565
|
+
},
|
|
1566
|
+
};
|