@delightui/components 0.1.105 → 0.1.107
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 +104 -1
- package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/library.css +19 -6
- package/dist/cjs/library.js +3 -3
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/library.css +19 -6
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +108 -2
- package/docs/README.md +264 -0
- package/docs/components/atoms/ActionImage.md +119 -0
- package/docs/components/atoms/Button.md +197 -0
- package/docs/components/atoms/Checkbox.md +299 -0
- package/docs/components/atoms/CheckboxItem.md +314 -0
- package/docs/components/atoms/Chip.md +380 -0
- package/docs/components/atoms/CustomToggle.md +270 -0
- package/docs/components/atoms/Icon.md +365 -0
- package/docs/components/atoms/IconButton.md +407 -0
- package/docs/components/atoms/Image.md +448 -0
- package/docs/components/atoms/Input.md +430 -0
- package/docs/components/atoms/ListItem.md +502 -0
- package/docs/components/atoms/Password.md +472 -0
- package/docs/components/atoms/RadioButton.md +614 -0
- package/docs/components/atoms/RadioButtonItem.md +588 -0
- package/docs/components/atoms/ResponsiveComponent.md +612 -0
- package/docs/components/atoms/SelectListItem.md +609 -0
- package/docs/components/atoms/Slider.md +605 -0
- package/docs/components/atoms/Spinner.md +605 -0
- package/docs/components/atoms/Text.md +463 -0
- package/docs/components/atoms/TextArea.md +670 -0
- package/docs/components/atoms/ToastNotification.md +668 -0
- package/docs/components/atoms/Toggle.md +737 -0
- package/docs/components/atoms/ToggleButton.md +751 -0
- package/docs/components/atoms/Tooltip.md +391 -0
- package/docs/components/molecules/Accordion.md +440 -0
- package/docs/components/molecules/AccordionGroup.md +547 -0
- package/docs/components/molecules/ActionCard.md +546 -0
- package/docs/components/molecules/Breadcrumb.md +403 -0
- package/docs/components/molecules/Breadcrumbs.md +485 -0
- package/docs/components/molecules/ButtonGroup.md +383 -0
- package/docs/components/molecules/Card.md +298 -0
- package/docs/components/molecules/ChipInput.md +646 -0
- package/docs/components/molecules/ContextMenu.md +768 -0
- package/docs/components/molecules/CustomTimeSelector.md +116 -0
- package/docs/components/molecules/DatePicker.md +516 -0
- package/docs/components/molecules/DateTimeSelector.md +166 -0
- package/docs/components/molecules/FormField.md +312 -0
- package/docs/components/molecules/Grid.md +577 -0
- package/docs/components/molecules/GridItem.md +834 -0
- package/docs/components/molecules/GridList.md +244 -0
- package/docs/components/molecules/List.md +485 -0
- package/docs/components/molecules/Modal.md +470 -0
- package/docs/components/molecules/ModalFooter.md +702 -0
- package/docs/components/molecules/ModalHeader.md +756 -0
- package/docs/components/molecules/ModalProvider.md +205 -0
- package/docs/components/molecules/Nav.md +530 -0
- package/docs/components/molecules/NavItem.md +572 -0
- package/docs/components/molecules/NavLink.md +499 -0
- package/docs/components/molecules/Option.md +521 -0
- package/docs/components/molecules/Pagination.md +592 -0
- package/docs/components/molecules/PaginationNumberField.md +722 -0
- package/docs/components/molecules/Popover.md +516 -0
- package/docs/components/molecules/ProgressBar.md +624 -0
- package/docs/components/molecules/RadioGroup.md +831 -0
- package/docs/components/molecules/RepeaterList.md +185 -0
- package/docs/components/molecules/Select.md +402 -0
- package/docs/components/molecules/SortableTrigger.md +82 -0
- package/docs/components/molecules/useModal.md +379 -0
- package/docs/components/organisms/Dropzone.md +346 -0
- package/docs/components/organisms/DropzoneClear.md +135 -0
- package/docs/components/organisms/DropzoneContent.md +216 -0
- package/docs/components/organisms/DropzoneFilename.md +191 -0
- package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
- package/docs/components/organisms/DropzoneTrigger.md +209 -0
- package/docs/components/organisms/Form.md +533 -0
- package/docs/components/organisms/SlideOutPanel.md +662 -0
- package/docs/components/organisms/TabContent.md +902 -0
- package/docs/components/organisms/TabItem.md +1091 -0
- package/docs/components/organisms/Table.md +611 -0
- package/docs/components/organisms/TableBody.md +679 -0
- package/docs/components/organisms/TableCell.md +482 -0
- package/docs/components/organisms/TableHeader.md +513 -0
- package/docs/components/organisms/TableHeaderCell.md +661 -0
- package/docs/components/organisms/TableRow.md +715 -0
- package/docs/components/organisms/Tabs.md +1330 -0
- package/docs/components/utils/ConditionalView.md +568 -0
- package/docs/components/utils/RenderStateView.md +726 -0
- package/docs/components/utils/WrapTextNodes.md +614 -0
- package/package.json +3 -2
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
# ConditionalView
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A utility component that provides conditional rendering capabilities based on a boolean condition. ConditionalView simplifies the common pattern of conditionally displaying content by wrapping it in a clean, reusable component that only renders its children when a specified condition is met.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- ConditionalView
|
|
10
|
+
- Conditional Renderer
|
|
11
|
+
- If Component
|
|
12
|
+
- Show Component
|
|
13
|
+
|
|
14
|
+
## Props Breakdown
|
|
15
|
+
|
|
16
|
+
**Extends:** Standalone interface (no HTML element inheritance)
|
|
17
|
+
|
|
18
|
+
| Prop | Type | Default | Required | Description |
|
|
19
|
+
|------|------|---------|----------|-------------|
|
|
20
|
+
| `condition` | `ReactNode \| undefined` | - | Yes | The condition that determines if children should render |
|
|
21
|
+
| `children` | `ReactNode` | - | Yes | Content to render when condition is truthy |
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### Basic Conditional Rendering
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { ConditionalView, Button, Text } from '@delightui/components';
|
|
29
|
+
|
|
30
|
+
function BasicConditionalExample() {
|
|
31
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div>
|
|
35
|
+
<ConditionalView condition={isLoggedIn}>
|
|
36
|
+
<Text>Welcome back! You are logged in.</Text>
|
|
37
|
+
</ConditionalView>
|
|
38
|
+
|
|
39
|
+
<ConditionalView condition={!isLoggedIn}>
|
|
40
|
+
<Text>Please log in to continue.</Text>
|
|
41
|
+
</ConditionalView>
|
|
42
|
+
|
|
43
|
+
<Button onClick={() => setIsLoggedIn(!isLoggedIn)}>
|
|
44
|
+
{isLoggedIn ? 'Log Out' : 'Log In'}
|
|
45
|
+
</Button>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### User Permission Based Rendering
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { ConditionalView, Button, Text } from '@delightui/components';
|
|
55
|
+
|
|
56
|
+
function PermissionBasedExample() {
|
|
57
|
+
const [user, setUser] = useState({
|
|
58
|
+
name: 'John Doe',
|
|
59
|
+
role: 'admin',
|
|
60
|
+
permissions: ['read', 'write', 'delete']
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const hasPermission = (permission: string) => {
|
|
64
|
+
return user.permissions.includes(permission);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div style={{ padding: '20px' }}>
|
|
69
|
+
<Text size="large">User Dashboard</Text>
|
|
70
|
+
|
|
71
|
+
<ConditionalView condition={hasPermission('read')}>
|
|
72
|
+
<div style={{ marginTop: '16px' }}>
|
|
73
|
+
<Text>📊 View Reports</Text>
|
|
74
|
+
</div>
|
|
75
|
+
</ConditionalView>
|
|
76
|
+
|
|
77
|
+
<ConditionalView condition={hasPermission('write')}>
|
|
78
|
+
<div style={{ marginTop: '16px' }}>
|
|
79
|
+
<Button>Create New Report</Button>
|
|
80
|
+
</div>
|
|
81
|
+
</ConditionalView>
|
|
82
|
+
|
|
83
|
+
<ConditionalView condition={hasPermission('delete')}>
|
|
84
|
+
<div style={{ marginTop: '16px' }}>
|
|
85
|
+
<Button style="Destructive">Delete Data</Button>
|
|
86
|
+
</div>
|
|
87
|
+
</ConditionalView>
|
|
88
|
+
|
|
89
|
+
<ConditionalView condition={user.role === 'admin'}>
|
|
90
|
+
<div style={{ marginTop: '16px', padding: '12px', backgroundColor: '#fff3cd' }}>
|
|
91
|
+
<Text weight="Bold">Admin Panel Access</Text>
|
|
92
|
+
</div>
|
|
93
|
+
</ConditionalView>
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Loading State Management
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import { ConditionalView, Spinner, Button, Text } from '@delightui/components';
|
|
103
|
+
|
|
104
|
+
function LoadingStateExample() {
|
|
105
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
106
|
+
const [data, setData] = useState<string[]>([]);
|
|
107
|
+
const [error, setError] = useState<string>('');
|
|
108
|
+
|
|
109
|
+
const fetchData = async () => {
|
|
110
|
+
setIsLoading(true);
|
|
111
|
+
setError('');
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
// Simulate API call
|
|
115
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
116
|
+
setData(['Item 1', 'Item 2', 'Item 3']);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
setError('Failed to load data');
|
|
119
|
+
} finally {
|
|
120
|
+
setIsLoading(false);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div style={{ padding: '20px' }}>
|
|
126
|
+
<Button onClick={fetchData} disabled={isLoading}>
|
|
127
|
+
Load Data
|
|
128
|
+
</Button>
|
|
129
|
+
|
|
130
|
+
<ConditionalView condition={isLoading}>
|
|
131
|
+
<div style={{ textAlign: 'center', padding: '40px' }}>
|
|
132
|
+
<Spinner />
|
|
133
|
+
<Text>Loading data...</Text>
|
|
134
|
+
</div>
|
|
135
|
+
</ConditionalView>
|
|
136
|
+
|
|
137
|
+
<ConditionalView condition={error}>
|
|
138
|
+
<div style={{
|
|
139
|
+
marginTop: '16px',
|
|
140
|
+
padding: '12px',
|
|
141
|
+
backgroundColor: '#f8d7da',
|
|
142
|
+
borderRadius: '4px'
|
|
143
|
+
}}>
|
|
144
|
+
<Text color="error">{error}</Text>
|
|
145
|
+
</div>
|
|
146
|
+
</ConditionalView>
|
|
147
|
+
|
|
148
|
+
<ConditionalView condition={data.length > 0 && !isLoading}>
|
|
149
|
+
<div style={{ marginTop: '16px' }}>
|
|
150
|
+
<Text weight="Bold">Data:</Text>
|
|
151
|
+
{data.map((item, index) => (
|
|
152
|
+
<Text key={index}>• {item}</Text>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
</ConditionalView>
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Form Field Visibility
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import { ConditionalView, Form, FormField, Input, Select, Button, RadioButton } from '@delightui/components';
|
|
165
|
+
|
|
166
|
+
function FormFieldVisibilityExample() {
|
|
167
|
+
const [formData, setFormData] = useState({
|
|
168
|
+
accountType: '',
|
|
169
|
+
hasCompany: false,
|
|
170
|
+
preferredContact: ''
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const handleSubmit = (data: any) => {
|
|
174
|
+
console.log('Form submitted:', data);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<Form onSubmit={handleSubmit}>
|
|
179
|
+
<FormField name="accountType" label="Account Type" required>
|
|
180
|
+
<Select
|
|
181
|
+
value={formData.accountType}
|
|
182
|
+
onValueChange={(value) => setFormData(prev => ({ ...prev, accountType: value }))}
|
|
183
|
+
>
|
|
184
|
+
<option value="">Select account type</option>
|
|
185
|
+
<option value="personal">Personal</option>
|
|
186
|
+
<option value="business">Business</option>
|
|
187
|
+
</Select>
|
|
188
|
+
</FormField>
|
|
189
|
+
|
|
190
|
+
<ConditionalView condition={formData.accountType === 'business'}>
|
|
191
|
+
<FormField name="companyName" label="Company Name" required>
|
|
192
|
+
<Input placeholder="Enter company name" />
|
|
193
|
+
</FormField>
|
|
194
|
+
|
|
195
|
+
<FormField name="taxId" label="Tax ID">
|
|
196
|
+
<Input placeholder="Enter tax identification number" />
|
|
197
|
+
</FormField>
|
|
198
|
+
</ConditionalView>
|
|
199
|
+
|
|
200
|
+
<FormField name="preferredContact" label="Preferred Contact Method">
|
|
201
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
202
|
+
<RadioButton
|
|
203
|
+
name="contact"
|
|
204
|
+
value="email"
|
|
205
|
+
checked={formData.preferredContact === 'email'}
|
|
206
|
+
onValueChange={(value) => setFormData(prev => ({ ...prev, preferredContact: value }))}
|
|
207
|
+
>
|
|
208
|
+
Email
|
|
209
|
+
</RadioButton>
|
|
210
|
+
<RadioButton
|
|
211
|
+
name="contact"
|
|
212
|
+
value="phone"
|
|
213
|
+
checked={formData.preferredContact === 'phone'}
|
|
214
|
+
onValueChange={(value) => setFormData(prev => ({ ...prev, preferredContact: value }))}
|
|
215
|
+
>
|
|
216
|
+
Phone
|
|
217
|
+
</RadioButton>
|
|
218
|
+
</div>
|
|
219
|
+
</FormField>
|
|
220
|
+
|
|
221
|
+
<ConditionalView condition={formData.preferredContact === 'phone'}>
|
|
222
|
+
<FormField name="phoneNumber" label="Phone Number" required>
|
|
223
|
+
<Input inputType="Text" placeholder="Enter phone number" />
|
|
224
|
+
</FormField>
|
|
225
|
+
</ConditionalView>
|
|
226
|
+
|
|
227
|
+
<Button actionType="submit">Create Account</Button>
|
|
228
|
+
</Form>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Feature Flag Implementation
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
import { ConditionalView, Button, Text, Card } from '@delightui/components';
|
|
237
|
+
|
|
238
|
+
function FeatureFlagExample() {
|
|
239
|
+
const [featureFlags, setFeatureFlags] = useState({
|
|
240
|
+
newDesign: true,
|
|
241
|
+
betaFeatures: false,
|
|
242
|
+
advancedSettings: true,
|
|
243
|
+
experimentalUi: false
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const toggleFeature = (feature: keyof typeof featureFlags) => {
|
|
247
|
+
setFeatureFlags(prev => ({
|
|
248
|
+
...prev,
|
|
249
|
+
[feature]: !prev[feature]
|
|
250
|
+
}));
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
<div style={{ padding: '20px' }}>
|
|
255
|
+
<Text size="large" weight="Bold">Feature Flags Demo</Text>
|
|
256
|
+
|
|
257
|
+
<div style={{ marginTop: '20px', display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
|
|
258
|
+
{Object.entries(featureFlags).map(([feature, enabled]) => (
|
|
259
|
+
<Button
|
|
260
|
+
key={feature}
|
|
261
|
+
size="Small"
|
|
262
|
+
type={enabled ? 'Filled' : 'Outlined'}
|
|
263
|
+
onClick={() => toggleFeature(feature as keyof typeof featureFlags)}
|
|
264
|
+
>
|
|
265
|
+
{feature}: {enabled ? 'ON' : 'OFF'}
|
|
266
|
+
</Button>
|
|
267
|
+
))}
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<ConditionalView condition={featureFlags.newDesign}>
|
|
271
|
+
<Card style={{ marginTop: '20px', backgroundColor: '#e3f2fd' }}>
|
|
272
|
+
<Text weight="Bold">🎨 New Design System</Text>
|
|
273
|
+
<Text>You're seeing the new design system interface!</Text>
|
|
274
|
+
</Card>
|
|
275
|
+
</ConditionalView>
|
|
276
|
+
|
|
277
|
+
<ConditionalView condition={featureFlags.betaFeatures}>
|
|
278
|
+
<Card style={{ marginTop: '20px', backgroundColor: '#fff3e0' }}>
|
|
279
|
+
<Text weight="Bold">🧪 Beta Features</Text>
|
|
280
|
+
<Text>Beta features are now available in your account.</Text>
|
|
281
|
+
<Button size="Small" style={{ marginTop: '8px' }}>
|
|
282
|
+
Try Beta Feature
|
|
283
|
+
</Button>
|
|
284
|
+
</Card>
|
|
285
|
+
</ConditionalView>
|
|
286
|
+
|
|
287
|
+
<ConditionalView condition={featureFlags.advancedSettings}>
|
|
288
|
+
<Card style={{ marginTop: '20px', backgroundColor: '#f3e5f5' }}>
|
|
289
|
+
<Text weight="Bold">⚙️ Advanced Settings</Text>
|
|
290
|
+
<Text>Advanced configuration options are enabled.</Text>
|
|
291
|
+
</Card>
|
|
292
|
+
</ConditionalView>
|
|
293
|
+
|
|
294
|
+
<ConditionalView condition={featureFlags.experimentalUi}>
|
|
295
|
+
<Card style={{ marginTop: '20px', backgroundColor: '#ffebee' }}>
|
|
296
|
+
<Text weight="Bold">🚀 Experimental UI</Text>
|
|
297
|
+
<Text>Warning: Experimental features may be unstable.</Text>
|
|
298
|
+
</Card>
|
|
299
|
+
</ConditionalView>
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Responsive Content Display
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
import { ConditionalView, Text, Button, Card } from '@delightui/components';
|
|
309
|
+
|
|
310
|
+
function ResponsiveContentExample() {
|
|
311
|
+
const [screenSize, setScreenSize] = useState({
|
|
312
|
+
width: window.innerWidth,
|
|
313
|
+
height: window.innerHeight
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
useEffect(() => {
|
|
317
|
+
const handleResize = () => {
|
|
318
|
+
setScreenSize({
|
|
319
|
+
width: window.innerWidth,
|
|
320
|
+
height: window.innerHeight
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
window.addEventListener('resize', handleResize);
|
|
325
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
326
|
+
}, []);
|
|
327
|
+
|
|
328
|
+
const isMobile = screenSize.width < 768;
|
|
329
|
+
const isTablet = screenSize.width >= 768 && screenSize.width < 1024;
|
|
330
|
+
const isDesktop = screenSize.width >= 1024;
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
<div style={{ padding: '20px' }}>
|
|
334
|
+
<Text size="large">Responsive Content Demo</Text>
|
|
335
|
+
<Text size="small">Screen width: {screenSize.width}px</Text>
|
|
336
|
+
|
|
337
|
+
<ConditionalView condition={isMobile}>
|
|
338
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#e8f5e8' }}>
|
|
339
|
+
<Text weight="Bold">📱 Mobile View</Text>
|
|
340
|
+
<Text>Optimized for mobile devices</Text>
|
|
341
|
+
<Button size="Small" style={{ marginTop: '8px', width: '100%' }}>
|
|
342
|
+
Mobile Action
|
|
343
|
+
</Button>
|
|
344
|
+
</Card>
|
|
345
|
+
</ConditionalView>
|
|
346
|
+
|
|
347
|
+
<ConditionalView condition={isTablet}>
|
|
348
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#fff3e0' }}>
|
|
349
|
+
<Text weight="Bold">📱 Tablet View</Text>
|
|
350
|
+
<Text>Medium screen layout</Text>
|
|
351
|
+
<div style={{ display: 'flex', gap: '8px', marginTop: '8px' }}>
|
|
352
|
+
<Button size="Small">Action 1</Button>
|
|
353
|
+
<Button size="Small">Action 2</Button>
|
|
354
|
+
</div>
|
|
355
|
+
</Card>
|
|
356
|
+
</ConditionalView>
|
|
357
|
+
|
|
358
|
+
<ConditionalView condition={isDesktop}>
|
|
359
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#e3f2fd' }}>
|
|
360
|
+
<Text weight="Bold">🖥️ Desktop View</Text>
|
|
361
|
+
<Text>Full desktop experience with all features</Text>
|
|
362
|
+
<div style={{ display: 'flex', gap: '8px', marginTop: '8px' }}>
|
|
363
|
+
<Button>Primary Action</Button>
|
|
364
|
+
<Button type="Outlined">Secondary</Button>
|
|
365
|
+
<Button type="Ghost">Tertiary</Button>
|
|
366
|
+
</div>
|
|
367
|
+
</Card>
|
|
368
|
+
</ConditionalView>
|
|
369
|
+
</div>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Error Boundary with Conditional Recovery
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import { ConditionalView, Button, Text, Card } from '@delightui/components';
|
|
378
|
+
|
|
379
|
+
function ErrorBoundaryExample() {
|
|
380
|
+
const [hasError, setHasError] = useState(false);
|
|
381
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
382
|
+
const [retryCount, setRetryCount] = useState(0);
|
|
383
|
+
|
|
384
|
+
const triggerError = () => {
|
|
385
|
+
setHasError(true);
|
|
386
|
+
setErrorMessage('Something went wrong while processing your request.');
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const handleRetry = () => {
|
|
390
|
+
setRetryCount(prev => prev + 1);
|
|
391
|
+
setHasError(false);
|
|
392
|
+
setErrorMessage('');
|
|
393
|
+
|
|
394
|
+
// Simulate operation that might fail
|
|
395
|
+
if (Math.random() > 0.7) {
|
|
396
|
+
setHasError(true);
|
|
397
|
+
setErrorMessage('Operation failed again. Please try later.');
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const handleReset = () => {
|
|
402
|
+
setHasError(false);
|
|
403
|
+
setErrorMessage('');
|
|
404
|
+
setRetryCount(0);
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
return (
|
|
408
|
+
<div style={{ padding: '20px' }}>
|
|
409
|
+
<Text size="large">Error Handling Demo</Text>
|
|
410
|
+
|
|
411
|
+
<ConditionalView condition={!hasError}>
|
|
412
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#e8f5e8' }}>
|
|
413
|
+
<Text>✅ Everything is working correctly!</Text>
|
|
414
|
+
<Button
|
|
415
|
+
onClick={triggerError}
|
|
416
|
+
style={{ marginTop: '12px' }}
|
|
417
|
+
size="Small"
|
|
418
|
+
>
|
|
419
|
+
Trigger Error
|
|
420
|
+
</Button>
|
|
421
|
+
</Card>
|
|
422
|
+
</ConditionalView>
|
|
423
|
+
|
|
424
|
+
<ConditionalView condition={hasError}>
|
|
425
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#ffebee' }}>
|
|
426
|
+
<Text weight="Bold" color="error">❌ Error Occurred</Text>
|
|
427
|
+
<Text>{errorMessage}</Text>
|
|
428
|
+
|
|
429
|
+
<ConditionalView condition={retryCount < 3}>
|
|
430
|
+
<Button
|
|
431
|
+
onClick={handleRetry}
|
|
432
|
+
style={{ marginTop: '12px', marginRight: '8px' }}
|
|
433
|
+
size="Small"
|
|
434
|
+
>
|
|
435
|
+
Retry ({retryCount}/3)
|
|
436
|
+
</Button>
|
|
437
|
+
</ConditionalView>
|
|
438
|
+
|
|
439
|
+
<Button
|
|
440
|
+
onClick={handleReset}
|
|
441
|
+
type="Outlined"
|
|
442
|
+
size="Small"
|
|
443
|
+
style={{ marginTop: '12px' }}
|
|
444
|
+
>
|
|
445
|
+
Reset
|
|
446
|
+
</Button>
|
|
447
|
+
</Card>
|
|
448
|
+
</ConditionalView>
|
|
449
|
+
|
|
450
|
+
<ConditionalView condition={retryCount >= 3 && hasError}>
|
|
451
|
+
<Card style={{ marginTop: '16px', backgroundColor: '#fff3e0' }}>
|
|
452
|
+
<Text weight="Bold">⚠️ Maximum Retries Reached</Text>
|
|
453
|
+
<Text>Please contact support if the problem persists.</Text>
|
|
454
|
+
<Button
|
|
455
|
+
size="Small"
|
|
456
|
+
style={{ marginTop: '8px' }}
|
|
457
|
+
>
|
|
458
|
+
Contact Support
|
|
459
|
+
</Button>
|
|
460
|
+
</Card>
|
|
461
|
+
</ConditionalView>
|
|
462
|
+
</div>
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Multi-step Wizard Navigation
|
|
468
|
+
|
|
469
|
+
```tsx
|
|
470
|
+
import { ConditionalView, Button, Text, Card, ProgressBar } from '@delightui/components';
|
|
471
|
+
|
|
472
|
+
function WizardNavigationExample() {
|
|
473
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
474
|
+
const [completedSteps, setCompletedSteps] = useState<number[]>([]);
|
|
475
|
+
|
|
476
|
+
const totalSteps = 4;
|
|
477
|
+
const progress = (currentStep / totalSteps) * 100;
|
|
478
|
+
|
|
479
|
+
const markStepComplete = (step: number) => {
|
|
480
|
+
if (!completedSteps.includes(step)) {
|
|
481
|
+
setCompletedSteps(prev => [...prev, step]);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const goToNextStep = () => {
|
|
486
|
+
markStepComplete(currentStep);
|
|
487
|
+
if (currentStep < totalSteps) {
|
|
488
|
+
setCurrentStep(prev => prev + 1);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
const goToPreviousStep = () => {
|
|
493
|
+
if (currentStep > 1) {
|
|
494
|
+
setCurrentStep(prev => prev - 1);
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
return (
|
|
499
|
+
<div style={{ padding: '20px', maxWidth: '600px' }}>
|
|
500
|
+
<Text size="large" weight="Bold">Setup Wizard</Text>
|
|
501
|
+
|
|
502
|
+
<ProgressBar
|
|
503
|
+
value={progress}
|
|
504
|
+
max={100}
|
|
505
|
+
style={{ marginTop: '16px' }}
|
|
506
|
+
/>
|
|
507
|
+
|
|
508
|
+
<Text size="small" style={{ marginTop: '8px' }}>
|
|
509
|
+
Step {currentStep} of {totalSteps}
|
|
510
|
+
</Text>
|
|
511
|
+
|
|
512
|
+
<ConditionalView condition={currentStep === 1}>
|
|
513
|
+
<Card style={{ marginTop: '20px' }}>
|
|
514
|
+
<Text weight="Bold">Step 1: Personal Information</Text>
|
|
515
|
+
<Text>Please provide your personal details to get started.</Text>
|
|
516
|
+
</Card>
|
|
517
|
+
</ConditionalView>
|
|
518
|
+
|
|
519
|
+
<ConditionalView condition={currentStep === 2}>
|
|
520
|
+
<Card style={{ marginTop: '20px' }}>
|
|
521
|
+
<Text weight="Bold">Step 2: Account Preferences</Text>
|
|
522
|
+
<Text>Configure your account settings and preferences.</Text>
|
|
523
|
+
</Card>
|
|
524
|
+
</ConditionalView>
|
|
525
|
+
|
|
526
|
+
<ConditionalView condition={currentStep === 3}>
|
|
527
|
+
<Card style={{ marginTop: '20px' }}>
|
|
528
|
+
<Text weight="Bold">Step 3: Security Setup</Text>
|
|
529
|
+
<Text>Set up two-factor authentication and security options.</Text>
|
|
530
|
+
</Card>
|
|
531
|
+
</ConditionalView>
|
|
532
|
+
|
|
533
|
+
<ConditionalView condition={currentStep === 4}>
|
|
534
|
+
<Card style={{ marginTop: '20px', backgroundColor: '#e8f5e8' }}>
|
|
535
|
+
<Text weight="Bold">Step 4: Complete Setup</Text>
|
|
536
|
+
<Text>Review your information and complete the setup process.</Text>
|
|
537
|
+
</Card>
|
|
538
|
+
</ConditionalView>
|
|
539
|
+
|
|
540
|
+
<div style={{ marginTop: '20px', display: 'flex', gap: '12px' }}>
|
|
541
|
+
<ConditionalView condition={currentStep > 1}>
|
|
542
|
+
<Button
|
|
543
|
+
type="Outlined"
|
|
544
|
+
onClick={goToPreviousStep}
|
|
545
|
+
>
|
|
546
|
+
Previous
|
|
547
|
+
</Button>
|
|
548
|
+
</ConditionalView>
|
|
549
|
+
|
|
550
|
+
<ConditionalView condition={currentStep < totalSteps}>
|
|
551
|
+
<Button onClick={goToNextStep}>
|
|
552
|
+
Next
|
|
553
|
+
</Button>
|
|
554
|
+
</ConditionalView>
|
|
555
|
+
|
|
556
|
+
<ConditionalView condition={currentStep === totalSteps}>
|
|
557
|
+
<Button
|
|
558
|
+
style="Primary"
|
|
559
|
+
onClick={() => console.log('Setup complete!')}
|
|
560
|
+
>
|
|
561
|
+
Complete Setup
|
|
562
|
+
</Button>
|
|
563
|
+
</ConditionalView>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
```
|