@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.
Files changed (66) hide show
  1. package/README.md +326 -0
  2. package/dist/components/AccessibilityProvider.d.ts +64 -0
  3. package/dist/components/AccessibilityProvider.d.ts.map +1 -0
  4. package/dist/components/Breadcrumbs.d.ts +39 -0
  5. package/dist/components/Breadcrumbs.d.ts.map +1 -0
  6. package/dist/components/ErrorBoundary.d.ts +39 -0
  7. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  8. package/dist/components/QwickApp.d.ts.map +1 -1
  9. package/dist/components/forms/FormBlock.d.ts +1 -1
  10. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  11. package/dist/components/index.d.ts +3 -0
  12. package/dist/components/index.d.ts.map +1 -1
  13. package/dist/components/input/SwitchInputField.d.ts +28 -0
  14. package/dist/components/input/SwitchInputField.d.ts.map +1 -0
  15. package/dist/components/input/index.d.ts +2 -0
  16. package/dist/components/input/index.d.ts.map +1 -1
  17. package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
  18. package/dist/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
  19. package/dist/components/layout/CollapsibleLayout/index.d.ts +9 -0
  20. package/dist/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
  21. package/dist/components/layout/index.d.ts +2 -0
  22. package/dist/components/layout/index.d.ts.map +1 -1
  23. package/dist/index.bundled.css +12 -0
  24. package/dist/index.esm.js +1678 -25
  25. package/dist/index.js +1689 -21
  26. package/dist/schemas/CollapsibleLayoutSchema.d.ts +31 -0
  27. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
  28. package/dist/schemas/SwitchInputFieldSchema.d.ts +18 -0
  29. package/dist/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
  30. package/dist/types/CollapsibleLayout.d.ts +142 -0
  31. package/dist/types/CollapsibleLayout.d.ts.map +1 -0
  32. package/dist/types/index.d.ts +1 -0
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/components/AccessibilityProvider.tsx +466 -0
  36. package/src/components/Breadcrumbs.tsx +223 -0
  37. package/src/components/ErrorBoundary.tsx +216 -0
  38. package/src/components/QwickApp.tsx +17 -11
  39. package/src/components/__tests__/AccessibilityProvider.test.tsx +330 -0
  40. package/src/components/__tests__/Breadcrumbs.test.tsx +268 -0
  41. package/src/components/__tests__/ErrorBoundary.test.tsx +163 -0
  42. package/src/components/forms/FormBlock.tsx +2 -2
  43. package/src/components/index.ts +3 -0
  44. package/src/components/input/SwitchInputField.tsx +165 -0
  45. package/src/components/input/index.ts +2 -0
  46. package/src/components/layout/CollapsibleLayout/CollapsibleLayout.tsx +554 -0
  47. package/src/components/layout/CollapsibleLayout/__tests__/CollapsibleLayout.test.tsx +1469 -0
  48. package/src/components/layout/CollapsibleLayout/index.tsx +17 -0
  49. package/src/components/layout/index.ts +4 -1
  50. package/src/components/pages/FormPage.tsx +1 -1
  51. package/src/schemas/CollapsibleLayoutSchema.ts +276 -0
  52. package/src/schemas/SwitchInputFieldSchema.ts +99 -0
  53. package/src/stories/AccessibilityProvider.stories.tsx +284 -0
  54. package/src/stories/Breadcrumbs.stories.tsx +304 -0
  55. package/src/stories/CollapsibleLayout.stories.tsx +1566 -0
  56. package/src/stories/ErrorBoundary.stories.tsx +159 -0
  57. package/src/types/CollapsibleLayout.ts +231 -0
  58. package/src/types/index.ts +1 -0
  59. package/dist/schemas/Builders.d.ts +0 -7
  60. package/dist/schemas/Builders.d.ts.map +0 -1
  61. package/dist/schemas/types.d.ts +0 -7
  62. package/dist/schemas/types.d.ts.map +0 -1
  63. package/dist/types/DataBinding.d.ts +0 -7
  64. package/dist/types/DataBinding.d.ts.map +0 -1
  65. package/dist/types/DataProvider.d.ts +0 -7
  66. package/dist/types/DataProvider.d.ts.map +0 -1
@@ -0,0 +1,304 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Breadcrumbs, useBreadcrumbs, type BreadcrumbItem } from '../components/Breadcrumbs';
3
+ import React from 'react';
4
+
5
+ // Icons for demo
6
+ const HomeIcon = () => (
7
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
8
+ <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
9
+ </svg>
10
+ );
11
+
12
+ const FolderIcon = () => (
13
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
14
+ <path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>
15
+ </svg>
16
+ );
17
+
18
+ const FileIcon = () => (
19
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
20
+ <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"/>
21
+ </svg>
22
+ );
23
+
24
+ // Demo component with navigation simulation
25
+ const BreadcrumbDemo = () => {
26
+ const { breadcrumbs, setBreadcrumbs, addBreadcrumb, removeBreadcrumb, clearBreadcrumbs } = useBreadcrumbs();
27
+ const [currentPath, setCurrentPath] = React.useState('Home > Documents > Projects');
28
+
29
+ const samplePaths = [
30
+ 'Home',
31
+ 'Home > Documents',
32
+ 'Home > Documents > Projects',
33
+ 'Home > Documents > Projects > QwickApps',
34
+ 'Home > Documents > Projects > QwickApps > Framework',
35
+ 'Home > Store > Products',
36
+ 'Home > Store > Products > Electronics > Computers',
37
+ ];
38
+
39
+ const pathToBreadcrumbs = (path: string): BreadcrumbItem[] => {
40
+ const parts = path.split(' > ');
41
+ return parts.map((part, index) => ({
42
+ label: part,
43
+ href: `/${part.toLowerCase().replace(/\s+/g, '-')}`,
44
+ icon: index === 0 ? <HomeIcon /> :
45
+ index === parts.length - 1 ? <FileIcon /> :
46
+ <FolderIcon />,
47
+ current: index === parts.length - 1
48
+ }));
49
+ };
50
+
51
+ React.useEffect(() => {
52
+ setBreadcrumbs(pathToBreadcrumbs(currentPath));
53
+ }, [currentPath, setBreadcrumbs]);
54
+
55
+ const handleNavigate = (item: BreadcrumbItem, index: number) => {
56
+ const newPath = breadcrumbs.slice(0, index + 1).map(b => b.label).join(' > ');
57
+ setCurrentPath(newPath);
58
+ alert(`Navigated to: ${item.label}`);
59
+ };
60
+
61
+ return (
62
+ <div style={{ padding: '2rem' }}>
63
+ <h2>Interactive Breadcrumbs Demo</h2>
64
+
65
+ <div style={{ marginBottom: '2rem' }}>
66
+ <h3>Current Navigation:</h3>
67
+ <Breadcrumbs items={breadcrumbs} onNavigate={handleNavigate} />
68
+ </div>
69
+
70
+ <div style={{ marginBottom: '2rem' }}>
71
+ <h3>Navigate to Different Paths:</h3>
72
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
73
+ {samplePaths.map((path) => (
74
+ <button
75
+ key={path}
76
+ onClick={() => setCurrentPath(path)}
77
+ style={{
78
+ padding: '0.5rem 1rem',
79
+ background: path === currentPath ? '#007cba' : '#f0f0f0',
80
+ color: path === currentPath ? 'white' : 'black',
81
+ border: '1px solid #ddd',
82
+ borderRadius: '4px',
83
+ textAlign: 'left',
84
+ cursor: 'pointer'
85
+ }}
86
+ >
87
+ {path}
88
+ </button>
89
+ ))}
90
+ </div>
91
+ </div>
92
+
93
+ <div>
94
+ <h3>Breadcrumb Controls:</h3>
95
+ <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
96
+ <button
97
+ onClick={() => addBreadcrumb({ label: 'New Item', href: '/new' })}
98
+ style={{ padding: '0.5rem 1rem', background: '#28a745', color: 'white', border: 'none', borderRadius: '4px' }}
99
+ >
100
+ Add Item
101
+ </button>
102
+ <button
103
+ onClick={() => removeBreadcrumb(breadcrumbs.length - 1)}
104
+ style={{ padding: '0.5rem 1rem', background: '#dc3545', color: 'white', border: 'none', borderRadius: '4px' }}
105
+ >
106
+ Remove Last
107
+ </button>
108
+ <button
109
+ onClick={clearBreadcrumbs}
110
+ style={{ padding: '0.5rem 1rem', background: '#6c757d', color: 'white', border: 'none', borderRadius: '4px' }}
111
+ >
112
+ Clear All
113
+ </button>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ );
118
+ };
119
+
120
+ const meta: Meta<typeof Breadcrumbs> = {
121
+ title: 'Components/Breadcrumbs',
122
+ component: Breadcrumbs,
123
+ parameters: {
124
+ layout: 'centered',
125
+ docs: {
126
+ description: {
127
+ component: 'A navigation breadcrumb component that shows the current page location within the application hierarchy. Supports accessibility, keyboard navigation, and customization.',
128
+ },
129
+ },
130
+ },
131
+ tags: ['autodocs'],
132
+ argTypes: {
133
+ items: {
134
+ description: 'Array of breadcrumb items to display',
135
+ },
136
+ separator: {
137
+ description: 'Custom separator between breadcrumb items',
138
+ control: 'text',
139
+ },
140
+ className: {
141
+ description: 'Additional CSS classes to apply',
142
+ control: 'text',
143
+ },
144
+ onNavigate: {
145
+ description: 'Callback function when a breadcrumb is clicked',
146
+ action: 'navigate',
147
+ },
148
+ maxItems: {
149
+ description: 'Maximum number of items to show (truncates with ellipsis)',
150
+ control: { type: 'number', min: 1, max: 10 },
151
+ },
152
+ showRoot: {
153
+ description: 'Whether to show the root (first) item',
154
+ control: 'boolean',
155
+ },
156
+ },
157
+ };
158
+
159
+ export default meta;
160
+ type Story = StoryObj<typeof meta>;
161
+
162
+ // Sample breadcrumb data
163
+ const sampleBreadcrumbs: BreadcrumbItem[] = [
164
+ { label: 'Home', href: '/', icon: <HomeIcon /> },
165
+ { label: 'Products', href: '/products', icon: <FolderIcon /> },
166
+ { label: 'Electronics', href: '/products/electronics', icon: <FolderIcon /> },
167
+ { label: 'Laptop', href: '/products/electronics/laptop', icon: <FileIcon />, current: true },
168
+ ];
169
+
170
+ // Default story
171
+ export const Default: Story = {
172
+ args: {
173
+ items: sampleBreadcrumbs,
174
+ },
175
+ };
176
+
177
+ // Story with custom separator
178
+ export const CustomSeparator: Story = {
179
+ args: {
180
+ items: sampleBreadcrumbs,
181
+ separator: '→',
182
+ },
183
+ parameters: {
184
+ docs: {
185
+ description: {
186
+ story: 'Breadcrumbs with a custom arrow separator instead of the default slash.',
187
+ },
188
+ },
189
+ },
190
+ };
191
+
192
+ // Story with emoji separator
193
+ export const EmojiSeparator: Story = {
194
+ args: {
195
+ items: sampleBreadcrumbs,
196
+ separator: '🏠',
197
+ },
198
+ parameters: {
199
+ docs: {
200
+ description: {
201
+ story: 'Breadcrumbs with an emoji separator for a more playful look.',
202
+ },
203
+ },
204
+ },
205
+ };
206
+
207
+ // Story with max items (truncation)
208
+ export const TruncatedItems: Story = {
209
+ args: {
210
+ items: [
211
+ { label: 'Home', href: '/' },
212
+ { label: 'Level 1', href: '/level1' },
213
+ { label: 'Level 2', href: '/level1/level2' },
214
+ { label: 'Level 3', href: '/level1/level2/level3' },
215
+ { label: 'Level 4', href: '/level1/level2/level3/level4' },
216
+ { label: 'Current Page', href: '/level1/level2/level3/level4/current', current: true },
217
+ ],
218
+ maxItems: 4,
219
+ },
220
+ parameters: {
221
+ docs: {
222
+ description: {
223
+ story: 'When there are too many items, middle items are replaced with ellipsis.',
224
+ },
225
+ },
226
+ },
227
+ };
228
+
229
+ // Story without root item
230
+ export const WithoutRoot: Story = {
231
+ args: {
232
+ items: sampleBreadcrumbs,
233
+ showRoot: false,
234
+ },
235
+ parameters: {
236
+ docs: {
237
+ description: {
238
+ story: 'Breadcrumbs without showing the root (first) item.',
239
+ },
240
+ },
241
+ },
242
+ };
243
+
244
+ // Story without icons
245
+ export const WithoutIcons: Story = {
246
+ args: {
247
+ items: [
248
+ { label: 'Home', href: '/' },
249
+ { label: 'Products', href: '/products' },
250
+ { label: 'Electronics', href: '/products/electronics' },
251
+ { label: 'Laptop', href: '/products/electronics/laptop', current: true },
252
+ ],
253
+ },
254
+ parameters: {
255
+ docs: {
256
+ description: {
257
+ story: 'Simple breadcrumbs without icons, just text navigation.',
258
+ },
259
+ },
260
+ },
261
+ };
262
+
263
+ // Story with navigation handler
264
+ export const WithNavigation: Story = {
265
+ args: {
266
+ items: sampleBreadcrumbs,
267
+ onNavigate: (item, index) => {
268
+ alert(`Clicked on "${item.label}" at index ${index}`);
269
+ },
270
+ },
271
+ parameters: {
272
+ docs: {
273
+ description: {
274
+ story: 'Breadcrumbs with a navigation handler that prevents default link behavior.',
275
+ },
276
+ },
277
+ },
278
+ };
279
+
280
+ // Interactive demo story
281
+ export const InteractiveDemo: Story = {
282
+ render: () => <BreadcrumbDemo />,
283
+ parameters: {
284
+ docs: {
285
+ description: {
286
+ story: 'Interactive demo showing breadcrumb navigation with the useBreadcrumbs hook.',
287
+ },
288
+ },
289
+ },
290
+ };
291
+
292
+ // Accessibility showcase
293
+ export const AccessibilityShowcase: Story = {
294
+ args: {
295
+ items: sampleBreadcrumbs,
296
+ },
297
+ parameters: {
298
+ docs: {
299
+ description: {
300
+ story: 'This breadcrumb component includes proper ARIA labels, keyboard navigation, and screen reader support. Try using Tab and Enter keys to navigate.',
301
+ },
302
+ },
303
+ },
304
+ };