@delightui/components 0.1.107 → 0.1.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/utils/index.d.ts +2 -0
- package/dist/cjs/components/utils/useInflateView/index.d.ts +2 -0
- package/dist/cjs/components/utils/useInflateView/useInflateView.d.ts +42 -0
- package/dist/cjs/components/utils/useInflateView/useInflateView.types.d.ts +12 -0
- package/dist/cjs/library.js +1 -1
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/utils/index.d.ts +2 -0
- package/dist/esm/components/utils/useInflateView/index.d.ts +2 -0
- package/dist/esm/components/utils/useInflateView/useInflateView.d.ts +42 -0
- package/dist/esm/components/utils/useInflateView/useInflateView.types.d.ts +12 -0
- package/dist/esm/library.js +1 -1
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +55 -2
- package/docs/README.md +3 -0
- package/docs/components/utils/useInflateView.md +442 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
|
-
import React__default, { ImgHTMLAttributes, SyntheticEvent, HTMLAttributes, ReactNode, MouseEvent, FormHTMLAttributes, Ref, InputHTMLAttributes, TextareaHTMLAttributes, ComponentType, LiHTMLAttributes, CSSProperties, RefObject, TableHTMLAttributes, TdHTMLAttributes, AriaRole, KeyboardEventHandler } from 'react';
|
|
3
|
+
import React__default, { ImgHTMLAttributes, SyntheticEvent, HTMLAttributes, ReactNode, MouseEvent, FormHTMLAttributes, Ref, InputHTMLAttributes, TextareaHTMLAttributes, ComponentType, LiHTMLAttributes, CSSProperties, RefObject, TableHTMLAttributes, TdHTMLAttributes, ReactElement, AriaRole, KeyboardEventHandler } from 'react';
|
|
4
4
|
import { LinkProps } from 'react-router-dom';
|
|
5
5
|
import { Plugin } from 'flatpickr/dist/types/options';
|
|
6
6
|
import FlatPickr from 'react-flatpickr';
|
|
@@ -2328,6 +2328,59 @@ type RenderStateViewProps<T = unknown, P = any> = {
|
|
|
2328
2328
|
|
|
2329
2329
|
declare const RenderStateView: <T = unknown, P = any>(props: RenderStateViewProps<T, P>) => react_jsx_runtime.JSX.Element;
|
|
2330
2330
|
|
|
2331
|
+
/**
|
|
2332
|
+
* A hook that takes a component type and props and returns a memoized React element.
|
|
2333
|
+
* This is useful for creating reusable component instances with memoization to prevent
|
|
2334
|
+
* unnecessary re-renders when props haven't changed.
|
|
2335
|
+
*
|
|
2336
|
+
* @template T - The props type for the component
|
|
2337
|
+
* @param Component - React component to render
|
|
2338
|
+
* @param props - Props to pass to the component
|
|
2339
|
+
* @returns Memoized React element
|
|
2340
|
+
*
|
|
2341
|
+
* @example
|
|
2342
|
+
* ```tsx
|
|
2343
|
+
* const MyComponent = ({ title, count }) => (
|
|
2344
|
+
* <div>
|
|
2345
|
+
* <h1>{title}</h1>
|
|
2346
|
+
* <p>Count: {count}</p>
|
|
2347
|
+
* </div>
|
|
2348
|
+
* );
|
|
2349
|
+
*
|
|
2350
|
+
* function ParentComponent() {
|
|
2351
|
+
* const [count, setCount] = useState(0);
|
|
2352
|
+
*
|
|
2353
|
+
* // This view will only re-render when title or count changes
|
|
2354
|
+
* const inflatedView = useInflateView(MyComponent, {
|
|
2355
|
+
* title: 'My Title',
|
|
2356
|
+
* count: count
|
|
2357
|
+
* });
|
|
2358
|
+
*
|
|
2359
|
+
* return (
|
|
2360
|
+
* <div>
|
|
2361
|
+
* {inflatedView}
|
|
2362
|
+
* <button onClick={() => setCount(c => c + 1)}>
|
|
2363
|
+
* Increment
|
|
2364
|
+
* </button>
|
|
2365
|
+
* </div>
|
|
2366
|
+
* );
|
|
2367
|
+
* }
|
|
2368
|
+
* ```
|
|
2369
|
+
*/
|
|
2370
|
+
declare const useInflateView: <T extends Record<string, unknown>>(Component: ComponentType<T>, props: T) => ReactElement;
|
|
2371
|
+
|
|
2372
|
+
/**
|
|
2373
|
+
* Return type for the useInflateView hook.
|
|
2374
|
+
*/
|
|
2375
|
+
type UseInflateViewReturn = ReactElement;
|
|
2376
|
+
/**
|
|
2377
|
+
* Parameters for the useInflateView hook.
|
|
2378
|
+
*/
|
|
2379
|
+
type UseInflateViewParams<T extends Record<string, unknown>> = {
|
|
2380
|
+
Component: ComponentType<T>;
|
|
2381
|
+
props: T;
|
|
2382
|
+
};
|
|
2383
|
+
|
|
2331
2384
|
type ArrowDirectionEnum = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight';
|
|
2332
2385
|
type AccessibilityActions = {
|
|
2333
2386
|
onClick?: (event?: SyntheticEvent) => void;
|
|
@@ -2425,4 +2478,4 @@ declare const NotificationContext: React__default.Context<NotificationContextVal
|
|
|
2425
2478
|
declare const NotificationProvider: React__default.FC<NotificationProviderProps>;
|
|
2426
2479
|
declare const useNotification: () => NotificationContextValue;
|
|
2427
2480
|
|
|
2428
|
-
export { type AccessibilityActions, type AccessibilityProps, Accordion, AccordionDetails, AccordionGroup, AccordionSummary, ActionCard, type ActionCardProps, ActionImage, type ActionImageProps, Breadcrumb, type BreadcrumbProps, Breadcrumbs, type BreadcrumbsProps, Breakpoint, type BreakpointProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, Card, type CardProps, Checkbox, CheckboxItem, type CheckboxItemProps, type CheckboxLabelAlignmentEnum, type CheckboxProps, type CheckboxSizeEnum, type CheckboxTypeEnum, Chip, _default as ChipInput, type ChipInputProps, type ChipListItemProps, type ChipListItemTypeEnum, type ChipProps, ConditionalView, type ConditionalViewProps, ContextMenu, type ContextMenuProps, type CustomTimePickerConfig, CustomToggle, type CustomToggleProps, DatePicker, type DatePickerProps, SortableItem as DraggableItem, SortableTrigger as DraggableItemTrigger, Dropzone, DropzoneClear, DropzoneContent, type DropzoneContentProps, type DropzoneContentTypeEnum, DropzoneFilename, DropzoneFilename as DropzonePreview, type DropzoneProps, DropzoneSupportedFormats as DropzoneReject, DropzoneTrigger as DropzoneRoot, DropzoneSupportedFormats, DropzoneTrigger, type FieldValidationFunction, type FieldValidators, type FieldValue, Form, type FormContextValues, type FormErrors, FormField, type FormFieldProps, type FormProps, type FormProviderProps, type FormState, type FormStateChangeHandler, type FormSubmitHandler, type FormValidator, Grid, GridItem, type GridItemProps, GridList, type GridListProps, type GridProps, Icon, IconButton, type IconButtonProps, type IconButtonStyleEnum, type IconProps, type IconSizeEnum, type IconStyleEnum, Image, type ImageFitEnum, type ImageProps, Input, type InputProps, type InputTypeEnum, List, ListItem, type ListItemProps$1 as ListItemProps, type ListProps, Modal, type ModalComponentProps, ModalFooter, type ModalFooterProps, ModalHeader, type ModalHeaderProps, type ModalProps, ModalProvider, type ModalProviderProps, Nav, NavItem, type NavItemProps, NavLink, type NavLinkProps, type NavProps, type NotificationContainerProps, NotificationContext, NotificationProvider, Option, type OptionProps, type OverlayDirectionEnum, Pagination, PaginationNumberField, type PaginationNumberFieldProps, type PaginationProps, Password, Popover, type PopoverHandle, type PopoverProps, ProgressBar, type ProgressBarProps, RadioButton, RadioButtonItem, type RadioButtonItemProps, type RadioButtonLabelAlignmentEnum, type RadioButtonProps, type RadioButtonSizeEnum, RadioGroup, type RadioGroupProps, RenderStateView, type RenderStateViewProps, RepeaterList, type RepeaterListProps, type RequiredFields, ResponsiveComponent, type ResponsiveComponentProps, Select, SelectListItem, type SelectListItemProps, type SelectProps, SelectProvider, SlideOutPanel, type SlideOutPanelDirectionEnum, type SlideOutPanelProps, type SlideOutPanelSizeEnum, Slider, type SliderProps, Spinner, type SpinnerProps, TabContent, type TabContentProps, TabItem, type TabItemProps, Table, TableBody, type TableBodyProps, TableCell, type TableCellProps, TableHeader, TableHeaderCell, type TableHeaderCellProps, type TableHeaderProps, type TableProps, TableRow, type TableRowProps, Tabs, type TabsProps, Text, TextArea, type TextAreaProps, type TextDecorationEnum, type TextProps, type TextTypeEnum, type TextWeightEnum, ThemeContext, type ThemeContextType, ThemeProvider, type ThemeProviderProps, Toggle, ToggleButton, type ToggleButtonProps, type ToggleLabelAlignmentEnum, type ToggleProps, Tooltip, type TooltipProps, type UseModalReturn, WrapTextNodes, type WrapTextNodesProps, applyPropsToChildren, getClickAccessibilityProps, mergeRefs, useDropzoneContext, useModal, useNotification, useSelectContext, useTab };
|
|
2481
|
+
export { type AccessibilityActions, type AccessibilityProps, Accordion, AccordionDetails, AccordionGroup, AccordionSummary, ActionCard, type ActionCardProps, ActionImage, type ActionImageProps, Breadcrumb, type BreadcrumbProps, Breadcrumbs, type BreadcrumbsProps, Breakpoint, type BreakpointProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, Card, type CardProps, Checkbox, CheckboxItem, type CheckboxItemProps, type CheckboxLabelAlignmentEnum, type CheckboxProps, type CheckboxSizeEnum, type CheckboxTypeEnum, Chip, _default as ChipInput, type ChipInputProps, type ChipListItemProps, type ChipListItemTypeEnum, type ChipProps, ConditionalView, type ConditionalViewProps, ContextMenu, type ContextMenuProps, type CustomTimePickerConfig, CustomToggle, type CustomToggleProps, DatePicker, type DatePickerProps, SortableItem as DraggableItem, SortableTrigger as DraggableItemTrigger, Dropzone, DropzoneClear, DropzoneContent, type DropzoneContentProps, type DropzoneContentTypeEnum, DropzoneFilename, DropzoneFilename as DropzonePreview, type DropzoneProps, DropzoneSupportedFormats as DropzoneReject, DropzoneTrigger as DropzoneRoot, DropzoneSupportedFormats, DropzoneTrigger, type FieldValidationFunction, type FieldValidators, type FieldValue, Form, type FormContextValues, type FormErrors, FormField, type FormFieldProps, type FormProps, type FormProviderProps, type FormState, type FormStateChangeHandler, type FormSubmitHandler, type FormValidator, Grid, GridItem, type GridItemProps, GridList, type GridListProps, type GridProps, Icon, IconButton, type IconButtonProps, type IconButtonStyleEnum, type IconProps, type IconSizeEnum, type IconStyleEnum, Image, type ImageFitEnum, type ImageProps, Input, type InputProps, type InputTypeEnum, List, ListItem, type ListItemProps$1 as ListItemProps, type ListProps, Modal, type ModalComponentProps, ModalFooter, type ModalFooterProps, ModalHeader, type ModalHeaderProps, type ModalProps, ModalProvider, type ModalProviderProps, Nav, NavItem, type NavItemProps, NavLink, type NavLinkProps, type NavProps, type NotificationContainerProps, NotificationContext, NotificationProvider, Option, type OptionProps, type OverlayDirectionEnum, Pagination, PaginationNumberField, type PaginationNumberFieldProps, type PaginationProps, Password, Popover, type PopoverHandle, type PopoverProps, ProgressBar, type ProgressBarProps, RadioButton, RadioButtonItem, type RadioButtonItemProps, type RadioButtonLabelAlignmentEnum, type RadioButtonProps, type RadioButtonSizeEnum, RadioGroup, type RadioGroupProps, RenderStateView, type RenderStateViewProps, RepeaterList, type RepeaterListProps, type RequiredFields, ResponsiveComponent, type ResponsiveComponentProps, Select, SelectListItem, type SelectListItemProps, type SelectProps, SelectProvider, SlideOutPanel, type SlideOutPanelDirectionEnum, type SlideOutPanelProps, type SlideOutPanelSizeEnum, Slider, type SliderProps, Spinner, type SpinnerProps, TabContent, type TabContentProps, TabItem, type TabItemProps, Table, TableBody, type TableBodyProps, TableCell, type TableCellProps, TableHeader, TableHeaderCell, type TableHeaderCellProps, type TableHeaderProps, type TableProps, TableRow, type TableRowProps, Tabs, type TabsProps, Text, TextArea, type TextAreaProps, type TextDecorationEnum, type TextProps, type TextTypeEnum, type TextWeightEnum, ThemeContext, type ThemeContextType, ThemeProvider, type ThemeProviderProps, Toggle, ToggleButton, type ToggleButtonProps, type ToggleLabelAlignmentEnum, type ToggleProps, Tooltip, type TooltipProps, type UseInflateViewParams, type UseInflateViewReturn, type UseModalReturn, WrapTextNodes, type WrapTextNodesProps, applyPropsToChildren, getClickAccessibilityProps, mergeRefs, useDropzoneContext, useInflateView, useModal, useNotification, useSelectContext, useTab };
|
package/docs/README.md
CHANGED
|
@@ -251,6 +251,9 @@ React hooks for enhanced functionality:
|
|
|
251
251
|
- **[useModal](./docs/components/molecules/useModal.md)** - A React hook that provides programmatic modal management with automatic ID generation and simplified modal state handling. Takes a modal component as a parameter and returns functions to open and close that specific modal, along with automatic unique identifier generation for each modal instance.
|
|
252
252
|
- *Aliases: useModal, Modal Hook, Modal Manager*
|
|
253
253
|
|
|
254
|
+
- **[useInflateView](./docs/components/utils/useInflateView.md)** - A React hook that takes a component type and props and returns a memoized React element. This hook is useful for creating reusable component instances with built-in memoization to prevent unnecessary re-renders when props haven't changed.
|
|
255
|
+
- *Aliases: useInflateView, Component Inflater, Memoized View Hook, Dynamic Component Hook*
|
|
256
|
+
|
|
254
257
|
### Utilities
|
|
255
258
|
Helper components and utilities:
|
|
256
259
|
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# useInflateView
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A React hook that takes a component type and props and returns a memoized React element. This hook is useful for creating reusable component instances with built-in memoization to prevent unnecessary re-renders when props haven't changed. It's particularly effective in scenarios where you need to create component instances dynamically or repeatedly.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- useInflateView
|
|
10
|
+
- Component Inflater
|
|
11
|
+
- Memoized View Hook
|
|
12
|
+
- Dynamic Component Hook
|
|
13
|
+
|
|
14
|
+
## Hook Signature
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
function useInflateView<T extends Record<string, unknown>>(
|
|
18
|
+
Component: ComponentType<T>,
|
|
19
|
+
props: T
|
|
20
|
+
): ReactElement
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Parameters
|
|
24
|
+
|
|
25
|
+
| Parameter | Type | Required | Description |
|
|
26
|
+
|-----------|------|----------|-------------|
|
|
27
|
+
| `Component` | `ComponentType<T>` | Yes | React component to render |
|
|
28
|
+
| `props` | `T` | Yes | Props to pass to the component |
|
|
29
|
+
|
|
30
|
+
## Return Value
|
|
31
|
+
|
|
32
|
+
Returns a memoized `ReactElement` that will only re-render when the component or props change.
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
### Basic Usage
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import React, { useState } from 'react';
|
|
40
|
+
import { useInflateView, Button, Text } from '@delightui/components';
|
|
41
|
+
|
|
42
|
+
const UserCard = ({ name, email, age }) => (
|
|
43
|
+
<div style={{ padding: '16px', border: '1px solid #ccc', borderRadius: '8px' }}>
|
|
44
|
+
<Text type="Heading4">{name}</Text>
|
|
45
|
+
<Text type="BodyMedium">{email}</Text>
|
|
46
|
+
<Text type="BodySmall">Age: {age}</Text>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
function BasicExample() {
|
|
51
|
+
const [userData, setUserData] = useState({
|
|
52
|
+
name: 'John Doe',
|
|
53
|
+
email: 'john@example.com',
|
|
54
|
+
age: 30
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// This view will only re-render when userData changes
|
|
58
|
+
const userCardView = useInflateView(UserCard, userData);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
{userCardView}
|
|
63
|
+
|
|
64
|
+
<Button onClick={() => setUserData(prev => ({
|
|
65
|
+
...prev,
|
|
66
|
+
age: prev.age + 1
|
|
67
|
+
}))}>
|
|
68
|
+
Increment Age
|
|
69
|
+
</Button>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Dynamic Component Selection
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import React, { useState } from 'react';
|
|
79
|
+
import { useInflateView, Button, Text } from '@delightui/components';
|
|
80
|
+
|
|
81
|
+
const SuccessMessage = ({ message }) => (
|
|
82
|
+
<div style={{ color: 'green', padding: '8px' }}>
|
|
83
|
+
✅ {message}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const ErrorMessage = ({ message }) => (
|
|
88
|
+
<div style={{ color: 'red', padding: '8px' }}>
|
|
89
|
+
❌ {message}
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const InfoMessage = ({ message }) => (
|
|
94
|
+
<div style={{ color: 'blue', padding: '8px' }}>
|
|
95
|
+
ℹ️ {message}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
function DynamicExample() {
|
|
100
|
+
const [messageType, setMessageType] = useState('info');
|
|
101
|
+
const [message] = useState('This is a dynamic message');
|
|
102
|
+
|
|
103
|
+
const getComponent = () => {
|
|
104
|
+
switch (messageType) {
|
|
105
|
+
case 'success': return SuccessMessage;
|
|
106
|
+
case 'error': return ErrorMessage;
|
|
107
|
+
default: return InfoMessage;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Dynamically inflate different components based on type
|
|
112
|
+
const messageView = useInflateView(getComponent(), { message });
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div>
|
|
116
|
+
{messageView}
|
|
117
|
+
|
|
118
|
+
<div style={{ marginTop: '16px', display: 'flex', gap: '8px' }}>
|
|
119
|
+
<Button onClick={() => setMessageType('success')}>
|
|
120
|
+
Success
|
|
121
|
+
</Button>
|
|
122
|
+
<Button onClick={() => setMessageType('error')}>
|
|
123
|
+
Error
|
|
124
|
+
</Button>
|
|
125
|
+
<Button onClick={() => setMessageType('info')}>
|
|
126
|
+
Info
|
|
127
|
+
</Button>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### List Rendering with Memoization
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import React, { useState } from 'react';
|
|
138
|
+
import { useInflateView, Button, Text, Card } from '@delightui/components';
|
|
139
|
+
|
|
140
|
+
const ProductCard = ({ id, name, price, inStock }) => (
|
|
141
|
+
<Card style={{ padding: '16px', margin: '8px 0' }}>
|
|
142
|
+
<Text type="Heading5">{name}</Text>
|
|
143
|
+
<Text type="BodyMedium">${price}</Text>
|
|
144
|
+
<Text type="BodySmall" style={{
|
|
145
|
+
color: inStock ? 'green' : 'red'
|
|
146
|
+
}}>
|
|
147
|
+
{inStock ? 'In Stock' : 'Out of Stock'}
|
|
148
|
+
</Text>
|
|
149
|
+
</Card>
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
function ListExample() {
|
|
153
|
+
const [products] = useState([
|
|
154
|
+
{ id: 1, name: 'Laptop', price: 999, inStock: true },
|
|
155
|
+
{ id: 2, name: 'Mouse', price: 29, inStock: false },
|
|
156
|
+
{ id: 3, name: 'Keyboard', price: 79, inStock: true }
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<div>
|
|
161
|
+
<Text type="Heading3">Product List</Text>
|
|
162
|
+
{products.map(product => {
|
|
163
|
+
// Each product card is memoized individually
|
|
164
|
+
const ProductView = () => useInflateView(ProductCard, product);
|
|
165
|
+
return <ProductView key={product.id} />;
|
|
166
|
+
})}
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Configuration-Based Component
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import React, { useState } from 'react';
|
|
176
|
+
import { useInflateView, Button, Text, Input, Toggle } from '@delightui/components';
|
|
177
|
+
|
|
178
|
+
const ConfigurableForm = ({ fields, onSubmit }) => (
|
|
179
|
+
<form onSubmit={onSubmit}>
|
|
180
|
+
{fields.map(field => (
|
|
181
|
+
<div key={field.name} style={{ marginBottom: '16px' }}>
|
|
182
|
+
<Text type="BodyMedium">{field.label}</Text>
|
|
183
|
+
{field.type === 'text' && (
|
|
184
|
+
<Input
|
|
185
|
+
name={field.name}
|
|
186
|
+
placeholder={field.placeholder}
|
|
187
|
+
required={field.required}
|
|
188
|
+
/>
|
|
189
|
+
)}
|
|
190
|
+
{field.type === 'toggle' && (
|
|
191
|
+
<Toggle name={field.name}>
|
|
192
|
+
{field.label}
|
|
193
|
+
</Toggle>
|
|
194
|
+
)}
|
|
195
|
+
</div>
|
|
196
|
+
))}
|
|
197
|
+
<Button actionType="submit">Submit</Button>
|
|
198
|
+
</form>
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
function ConfigurationExample() {
|
|
202
|
+
const [formConfig] = useState({
|
|
203
|
+
fields: [
|
|
204
|
+
{
|
|
205
|
+
name: 'username',
|
|
206
|
+
type: 'text',
|
|
207
|
+
label: 'Username',
|
|
208
|
+
placeholder: 'Enter username',
|
|
209
|
+
required: true
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: 'email',
|
|
213
|
+
type: 'text',
|
|
214
|
+
label: 'Email',
|
|
215
|
+
placeholder: 'Enter email',
|
|
216
|
+
required: true
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'notifications',
|
|
220
|
+
type: 'toggle',
|
|
221
|
+
label: 'Enable Notifications'
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const handleSubmit = (e) => {
|
|
227
|
+
e.preventDefault();
|
|
228
|
+
console.log('Form submitted');
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// Form structure is memoized based on configuration
|
|
232
|
+
const formView = useInflateView(ConfigurableForm, {
|
|
233
|
+
...formConfig,
|
|
234
|
+
onSubmit: handleSubmit
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<div>
|
|
239
|
+
<Text type="Heading3">Dynamic Form</Text>
|
|
240
|
+
{formView}
|
|
241
|
+
</div>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Performance Optimization Example
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
import React, { useState, useCallback } from 'react';
|
|
250
|
+
import { useInflateView, Button, Text } from '@delightui/components';
|
|
251
|
+
|
|
252
|
+
const ExpensiveComponent = ({ data, onProcess }) => {
|
|
253
|
+
// Simulate expensive computation
|
|
254
|
+
const processedData = React.useMemo(() => {
|
|
255
|
+
console.log('Processing data...'); // This should only log when data changes
|
|
256
|
+
return data.map(item => item * 2);
|
|
257
|
+
}, [data]);
|
|
258
|
+
|
|
259
|
+
return (
|
|
260
|
+
<div>
|
|
261
|
+
<Text type="Heading4">Processed Results</Text>
|
|
262
|
+
<Text type="BodyMedium">
|
|
263
|
+
Results: {processedData.join(', ')}
|
|
264
|
+
</Text>
|
|
265
|
+
<Button onClick={onProcess}>
|
|
266
|
+
Process Again
|
|
267
|
+
</Button>
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
function PerformanceExample() {
|
|
273
|
+
const [data] = useState([1, 2, 3, 4, 5]);
|
|
274
|
+
const [counter, setCounter] = useState(0);
|
|
275
|
+
|
|
276
|
+
const handleProcess = useCallback(() => {
|
|
277
|
+
console.log('Process clicked');
|
|
278
|
+
}, []);
|
|
279
|
+
|
|
280
|
+
// Component is memoized - won't re-render when counter changes
|
|
281
|
+
const expensiveView = useInflateView(ExpensiveComponent, {
|
|
282
|
+
data,
|
|
283
|
+
onProcess: handleProcess
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<div>
|
|
288
|
+
<Text type="Heading3">Performance Test</Text>
|
|
289
|
+
<Text type="BodyMedium">Counter: {counter}</Text>
|
|
290
|
+
|
|
291
|
+
<Button onClick={() => setCounter(c => c + 1)}>
|
|
292
|
+
Increment Counter (won't affect expensive component)
|
|
293
|
+
</Button>
|
|
294
|
+
|
|
295
|
+
{expensiveView}
|
|
296
|
+
</div>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Conditional Component Rendering
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
import React, { useState } from 'react';
|
|
305
|
+
import { useInflateView, Button, Text, Spinner } from '@delightui/components';
|
|
306
|
+
|
|
307
|
+
const LoadingView = ({ message }) => (
|
|
308
|
+
<div style={{ textAlign: 'center', padding: '40px' }}>
|
|
309
|
+
<Spinner />
|
|
310
|
+
<Text type="BodyMedium" style={{ marginTop: '16px' }}>
|
|
311
|
+
{message}
|
|
312
|
+
</Text>
|
|
313
|
+
</div>
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const ContentView = ({ title, content }) => (
|
|
317
|
+
<div>
|
|
318
|
+
<Text type="Heading3">{title}</Text>
|
|
319
|
+
<Text type="BodyMedium">{content}</Text>
|
|
320
|
+
</div>
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const ErrorView = ({ error, onRetry }) => (
|
|
324
|
+
<div style={{ textAlign: 'center', padding: '40px' }}>
|
|
325
|
+
<Text type="Heading4" style={{ color: 'red' }}>
|
|
326
|
+
Error Occurred
|
|
327
|
+
</Text>
|
|
328
|
+
<Text type="BodyMedium">{error}</Text>
|
|
329
|
+
<Button onClick={onRetry} style={{ marginTop: '16px' }}>
|
|
330
|
+
Retry
|
|
331
|
+
</Button>
|
|
332
|
+
</div>
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
function ConditionalExample() {
|
|
336
|
+
const [state, setState] = useState('loading'); // loading, success, error
|
|
337
|
+
const [data, setData] = useState(null);
|
|
338
|
+
|
|
339
|
+
const loadData = () => {
|
|
340
|
+
setState('loading');
|
|
341
|
+
setTimeout(() => {
|
|
342
|
+
if (Math.random() > 0.3) {
|
|
343
|
+
setData({
|
|
344
|
+
title: 'Success!',
|
|
345
|
+
content: 'Data loaded successfully.'
|
|
346
|
+
});
|
|
347
|
+
setState('success');
|
|
348
|
+
} else {
|
|
349
|
+
setState('error');
|
|
350
|
+
}
|
|
351
|
+
}, 2000);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const getView = () => {
|
|
355
|
+
switch (state) {
|
|
356
|
+
case 'loading':
|
|
357
|
+
return useInflateView(LoadingView, {
|
|
358
|
+
message: 'Loading data...'
|
|
359
|
+
});
|
|
360
|
+
case 'success':
|
|
361
|
+
return useInflateView(ContentView, data);
|
|
362
|
+
case 'error':
|
|
363
|
+
return useInflateView(ErrorView, {
|
|
364
|
+
error: 'Failed to load data',
|
|
365
|
+
onRetry: loadData
|
|
366
|
+
});
|
|
367
|
+
default:
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
<div>
|
|
374
|
+
<Button onClick={loadData}>
|
|
375
|
+
Load Data
|
|
376
|
+
</Button>
|
|
377
|
+
<div style={{ marginTop: '20px' }}>
|
|
378
|
+
{getView()}
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Performance Benefits
|
|
386
|
+
|
|
387
|
+
1. **Memoization**: Component instances are memoized based on props, preventing unnecessary re-renders
|
|
388
|
+
2. **Efficient Dependency Tracking**: Only re-renders when component or props actually change
|
|
389
|
+
3. **Memory Optimization**: Reuses component instances when props are unchanged
|
|
390
|
+
4. **Computation Reduction**: Reduces the overhead of recreating React elements
|
|
391
|
+
|
|
392
|
+
## Best Practices
|
|
393
|
+
|
|
394
|
+
1. **Stable References**: Use stable component references to maximize memoization benefits
|
|
395
|
+
2. **Prop Optimization**: Keep props objects shallow when possible for better comparison
|
|
396
|
+
3. **Callback Memoization**: Use `useCallback` for function props to maintain memoization
|
|
397
|
+
4. **Avoid Inline Objects**: Don't create new objects in props unless necessary
|
|
398
|
+
|
|
399
|
+
## Common Patterns
|
|
400
|
+
|
|
401
|
+
### Configuration-Driven UI
|
|
402
|
+
```tsx
|
|
403
|
+
const configBasedView = useInflateView(DynamicForm, formConfiguration);
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Conditional Rendering
|
|
407
|
+
```tsx
|
|
408
|
+
const conditionalView = useInflateView(
|
|
409
|
+
isLoading ? LoadingSpinner : ContentComponent,
|
|
410
|
+
componentProps
|
|
411
|
+
);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## TypeScript Support
|
|
415
|
+
|
|
416
|
+
The hook is fully typed and provides excellent TypeScript support:
|
|
417
|
+
|
|
418
|
+
```tsx
|
|
419
|
+
interface MyComponentProps {
|
|
420
|
+
title: string;
|
|
421
|
+
count: number;
|
|
422
|
+
onAction: (value: string) => void;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const MyComponent: React.FC<MyComponentProps> = ({ title, count, onAction }) => {
|
|
426
|
+
// Component implementation
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
// TypeScript will enforce correct prop types
|
|
430
|
+
const view = useInflateView(MyComponent, {
|
|
431
|
+
title: "Required string", // ✅ Required
|
|
432
|
+
count: 42, // ✅ Required number
|
|
433
|
+
onAction: (val) => {...} // ✅ Required function
|
|
434
|
+
// Missing any required prop will cause TypeScript error
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Related Hooks
|
|
439
|
+
|
|
440
|
+
- **[React.useMemo](https://reactjs.org/docs/hooks-reference.html#usememo)** - Base memoization hook
|
|
441
|
+
- **[React.useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback)** - Memoization for functions
|
|
442
|
+
- **[useModal](../molecules/useModal.md)** - For programmatic modal management
|