@pushwoosh/dumb-components 1.1.148 → 1.1.149
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/AccessForbidden/AccessForbidden.d.ts +3 -0
- package/AccessForbidden/AccessForbidden.js +3 -0
- package/Alert/Alert.d.ts +7 -0
- package/Alert/Alert.js +7 -0
- package/Alert/types.d.ts +6 -0
- package/ApplicationPreloader/ApplicationPreloader.d.ts +8 -0
- package/ApplicationPreloader/ApplicationPreloader.js +6 -0
- package/Badge/Badge.d.ts +6 -0
- package/Badge/Badge.js +6 -0
- package/Badge/types.d.ts +6 -0
- package/Banner/Banner.d.ts +7 -0
- package/Banner/Banner.js +7 -0
- package/Banner/types.d.ts +16 -0
- package/Button/Button.d.ts +19 -0
- package/Button/GhostButton.d.ts +1 -0
- package/Button/GhostButton.js +1 -0
- package/Button/RemoveButton.d.ts +6 -0
- package/Button/RemoveButton.js +6 -0
- package/Button/types.d.ts +21 -0
- package/Calendar/CalendarDropdown/CalendarDropdown.d.ts +12 -0
- package/Calendar/CalendarDropdown/CalendarDropdown.js +12 -0
- package/Calendar/CalendarDropdown/helpers.d.ts +4 -0
- package/Calendar/CalendarDropdown/helpers.js +4 -0
- package/Calendar/CalendarDropdown/types.d.ts +33 -0
- package/Calendar/CalendarSuperForm/CalendarSuperForm.d.ts +7 -0
- package/Calendar/CalendarSuperForm/CalendarSuperForm.js +7 -0
- package/Calendar/CalendarSuperForm/types.d.ts +36 -10
- package/Calendar/helpers.d.ts +10 -0
- package/Calendar/helpers.js +10 -0
- package/Calendar/types.d.ts +16 -1
- package/CardMetric/CardMetric.d.ts +7 -0
- package/CardMetric/CardMetric.js +7 -0
- package/CardMetric/types.d.ts +13 -0
- package/Checkbox/Checkbox.d.ts +6 -0
- package/Checkbox/Checkbox.js +6 -0
- package/Checkbox/types.d.ts +13 -0
- package/Chip/Chip.d.ts +7 -0
- package/Chip/Chip.js +7 -0
- package/Chip/Chip.types.d.ts +9 -0
- package/CodeEditor/CodeEditor.d.ts +7 -0
- package/CodeEditor/CodeEditor.js +7 -0
- package/CodeEditor/languages/html.d.ts +1 -0
- package/CodeEditor/languages/html.js +1 -0
- package/CodeEditor/languages/json.d.ts +1 -0
- package/CodeEditor/languages/json.js +1 -0
- package/CodeEditor/languages/liquid.d.ts +1 -0
- package/CodeEditor/languages/liquid.js +1 -0
- package/CodeEditor/types.d.ts +11 -0
- package/CrashScreen/CrashScreen.d.ts +4 -0
- package/CrashScreen/CrashScreen.js +4 -0
- package/DateTimePicker/components/DatePicker/DatePicker.d.ts +5 -0
- package/DateTimePicker/components/DatePicker/DatePicker.js +5 -0
- package/DateTimePicker/components/DatePicker/types.d.ts +9 -0
- package/DateTimePicker/components/DatePickerField/DatePickerField.d.ts +5 -0
- package/DateTimePicker/components/DatePickerField/DatePickerField.js +5 -0
- package/DateTimePicker/components/DatePickerField/types.d.ts +9 -0
- package/DateTimePicker/components/DateTimePicker/DateTimePicker.d.ts +5 -0
- package/DateTimePicker/components/DateTimePicker/DateTimePicker.js +5 -0
- package/DateTimePicker/components/DateTimePicker/types.d.ts +6 -0
- package/DateTimePicker/components/DateTimePickerField/DateTimePickerField.d.ts +5 -0
- package/DateTimePicker/components/DateTimePickerField/DateTimePickerField.js +5 -0
- package/DateTimePicker/components/DateTimePickerField/types.d.ts +9 -0
- package/DateTimePicker/types.d.ts +5 -0
- package/Drawer/components/Drawer/Drawer.d.ts +11 -0
- package/Drawer/components/Drawer/Drawer.js +11 -0
- package/Drawer/components/Drawer/types.d.ts +9 -0
- package/Drawer/components/DrawerContent/styles.d.ts +3 -0
- package/Drawer/components/DrawerContent/styles.js +3 -0
- package/Drawer/components/DrawerDocs/DrawerDocs.d.ts +7 -0
- package/Drawer/components/DrawerDocs/DrawerDocs.js +7 -0
- package/Drawer/components/DrawerDocs/hooks.d.ts +4 -0
- package/Drawer/components/DrawerDocs/hooks.js +4 -0
- package/Drawer/components/DrawerDocs/types.d.ts +4 -0
- package/DropdownMenu/components/DropdownMenu/DropdownMenu.d.ts +12 -0
- package/DropdownMenu/components/DropdownMenu/DropdownMenu.js +12 -0
- package/DropdownMenu/components/DropdownMenu/types.d.ts +15 -0
- package/DropdownMenu/components/DropdownMenuButton/DropdownMenuButton.d.ts +8 -0
- package/DropdownMenu/components/DropdownMenuButton/DropdownMenuButton.js +8 -0
- package/DropdownMenu/components/DropdownMenuButton/types.d.ts +16 -0
- package/DropdownMenu/components/DropdownMenuItem/DropdownMenuItem.d.ts +7 -0
- package/DropdownMenu/components/DropdownMenuItem/DropdownMenuItem.js +7 -0
- package/DropdownMenu/components/DropdownMenuItem/types.d.ts +6 -0
- package/DropdownMenu/components/DropdownMenuSection/DropdownMenuSection.d.ts +8 -0
- package/DropdownMenu/components/DropdownMenuSection/DropdownMenuSection.js +8 -0
- package/DropdownMenu/components/DropdownMenuSection/types.d.ts +3 -0
- package/DropdownMenu/components/DropdownMenuSubmenu/DropdownMenuSubmenu.d.ts +9 -0
- package/DropdownMenu/components/DropdownMenuSubmenu/DropdownMenuSubmenu.js +9 -0
- package/DropdownMenu/components/DropdownMenuSubmenu/types.d.ts +5 -0
- package/EditableField/EditableField.d.ts +9 -0
- package/EditableField/EditableField.js +9 -0
- package/EditableField/types.d.ts +12 -0
- package/EmailTemplatePreview/EmailTemplatePreview.d.ts +7 -0
- package/EmailTemplatePreview/EmailTemplatePreview.js +7 -0
- package/EmailTemplatePreview/components/NoEmailTemplatePreview/NoEmailTemplatePreview.d.ts +4 -0
- package/EmailTemplatePreview/components/NoEmailTemplatePreview/NoEmailTemplatePreview.js +4 -0
- package/EmailTemplatePreview/helpers.d.ts +8 -0
- package/EmailTemplatePreview/helpers.js +8 -0
- package/EmailTemplatePreview/types.d.ts +7 -0
- package/EnhancedInput/EnhancedInput.d.ts +7 -0
- package/EnhancedInput/EnhancedInput.js +7 -0
- package/EnhancedInput/SearchInput.d.ts +6 -0
- package/EnhancedInput/SearchInput.js +6 -0
- package/EnhancedInput/types.d.ts +5 -0
- package/ExportResult/ExportResult.d.ts +7 -0
- package/ExportResult/ExportResult.js +7 -0
- package/ExportResult/types.d.ts +7 -0
- package/ExternalImagePreview/ExternalImagePreview.d.ts +7 -0
- package/ExternalImagePreview/ExternalImagePreview.js +7 -0
- package/ExternalImagePreview/types.d.ts +7 -0
- package/FieldBox/FieldBox.d.ts +9 -0
- package/FieldBox/FieldBox.js +9 -0
- package/FieldBox/types.d.ts +10 -0
- package/FrequencyCapping/FrequencyCappingEdit.d.ts +7 -0
- package/FrequencyCapping/FrequencyCappingEdit.js +7 -0
- package/FrequencyCapping/FrequencyCappingInApps.d.ts +7 -0
- package/FrequencyCapping/FrequencyCappingInApps.js +7 -0
- package/FrequencyCapping/FrequencyCappingReadonly.d.ts +3 -0
- package/FrequencyCapping/FrequencyCappingReadonly.js +3 -0
- package/FrequencyCapping/types.d.ts +37 -0
- package/FrequencyCapping/types.js +1 -0
- package/GetStartedPage/GetStartedPage.d.ts +7 -0
- package/GetStartedPage/GetStartedPage.js +7 -0
- package/GetStartedPage/types.d.ts +7 -0
- package/InputFile/InputFile.d.ts +7 -0
- package/InputFile/InputFile.js +7 -0
- package/InputFile/types.d.ts +18 -0
- package/Link/Link.d.ts +18 -0
- package/Link/types.d.ts +17 -0
- package/Modal/components/Modal/Modal.d.ts +11 -0
- package/Modal/components/Modal/Modal.js +11 -0
- package/Modal/components/Modal/types.d.ts +6 -0
- package/Modal/components/ModalConfirm/ModalConfirm.d.ts +8 -0
- package/Modal/components/ModalConfirm/ModalConfirm.js +8 -0
- package/Modal/components/ModalConfirm/ModalConfirmProvider.d.ts +7 -0
- package/Modal/components/ModalConfirm/ModalConfirmProvider.js +7 -0
- package/Modal/components/ModalConfirm/hooks.d.ts +8 -0
- package/Modal/components/ModalConfirm/hooks.js +8 -0
- package/Modal/components/ModalConfirm/types.d.ts +16 -0
- package/Modal/components/ModalContent/styles.d.ts +5 -0
- package/Modal/components/ModalContent/styles.js +5 -0
- package/Modal/components/ModalTitle/ModalTitle.d.ts +6 -0
- package/Modal/components/ModalTitle/ModalTitle.js +6 -0
- package/Modal/components/ModalTitle/types.d.ts +3 -0
- package/NotificationInbox/NotificationBar.d.ts +7 -0
- package/NotificationInbox/NotificationBar.js +7 -0
- package/NotificationInbox/NotificationBell.d.ts +7 -0
- package/NotificationInbox/NotificationBell.js +7 -0
- package/NotificationInbox/NotificationInbox.d.ts +7 -0
- package/NotificationInbox/NotificationInbox.js +7 -0
- package/NotificationInbox/types.d.ts +31 -0
- package/NumberPicker/NumberPicker.d.ts +7 -0
- package/NumberPicker/NumberPicker.js +7 -0
- package/NumberPicker/types.d.ts +12 -0
- package/PageHeader/components/AutosizeInput/AutosizeInput.d.ts +7 -0
- package/PageHeader/components/AutosizeInput/AutosizeInput.js +7 -0
- package/PageHeader/components/AutosizeInput/types.d.ts +7 -0
- package/PageHeader/components/PageHeader/PageHeader.d.ts +7 -0
- package/PageHeader/components/PageHeader/PageHeader.js +7 -0
- package/PageHeader/components/PageHeader/types.d.ts +13 -0
- package/PageHeader/components/PageHeaderEditable/PageHeaderEditable.d.ts +7 -0
- package/PageHeader/components/PageHeaderEditable/PageHeaderEditable.js +7 -0
- package/PageHeader/components/PageHeaderEditable/types.d.ts +19 -0
- package/Pagination/Pagination.d.ts +7 -0
- package/Pagination/Pagination.js +7 -0
- package/Pagination/types.d.ts +7 -0
- package/Popover/Popover.d.ts +10 -0
- package/Popover/Popover.js +10 -0
- package/Popover/styles.d.ts +1 -0
- package/Popover/styles.js +1 -0
- package/Popover/types.d.ts +9 -0
- package/ProgressBar/ProgressBar.d.ts +6 -0
- package/ProgressBar/ProgressBar.js +6 -0
- package/ProgressBar/types.d.ts +7 -0
- package/PushPreview/PushPreview.d.ts +7 -0
- package/PushPreview/PushPreview.js +7 -0
- package/PushPreview/types.d.ts +17 -0
- package/Radio/Radio.d.ts +7 -0
- package/Radio/Radio.js +7 -0
- package/Radio/types.d.ts +14 -0
- package/RadioCard/RadioCard.d.ts +7 -0
- package/RadioCard/RadioCard.js +7 -0
- package/RadioCard/types.d.ts +7 -0
- package/ReCaptcha/ReCaptcha.d.ts +8 -0
- package/ReCaptcha/ReCaptcha.js +8 -0
- package/ReCaptcha/helpers.d.ts +4 -0
- package/ReCaptcha/helpers.js +4 -0
- package/ReCaptcha/hooks.d.ts +4 -0
- package/ReCaptcha/hooks.js +4 -0
- package/ReCaptcha/types.d.ts +5 -0
- package/RichMessageEditor/RichMessageEditor.d.ts +8 -0
- package/RichMessageEditor/RichMessageEditor.js +8 -0
- package/RichMessageEditor/RichMessageEditor.types.d.ts +10 -0
- package/RichMessageEditor/RichMessageViewer.d.ts +10 -0
- package/RichMessageEditor/RichMessageViewer.js +7 -0
- package/RichMessageEditor/slate/types.d.ts +5 -0
- package/RichMessageEditor/types.d.ts +1 -0
- package/RichmediaPreview/RichmediaPreview.d.ts +7 -0
- package/RichmediaPreview/RichmediaPreview.js +7 -0
- package/RichmediaPreview/hooks.d.ts +4 -0
- package/RichmediaPreview/hooks.js +4 -0
- package/RichmediaPreview/types.d.ts +13 -0
- package/Select/Select.d.ts +22 -0
- package/Select/Select.js +22 -0
- package/Select/constants.d.ts +1 -0
- package/Select/constants.js +1 -0
- package/Select/types.d.ts +19 -0
- package/SendRate/SendRateEdit.d.ts +7 -0
- package/SendRate/SendRateEdit.js +7 -0
- package/SendRate/SendRateReadonly.d.ts +3 -0
- package/SendRate/SendRateReadonly.js +3 -0
- package/SendRate/types.d.ts +20 -0
- package/Skeleton/TextSkeleton.d.ts +6 -0
- package/Skeleton/TextSkeleton.js +6 -0
- package/Skeleton/styles.d.ts +2 -0
- package/Skeleton/styles.js +2 -0
- package/Skeleton/types.d.ts +11 -0
- package/SortButton/SortButton.d.ts +6 -0
- package/SortButton/SortButton.js +6 -0
- package/SortButton/types.d.ts +11 -0
- package/Spinner/Spinner.d.ts +6 -0
- package/Spinner/Spinner.js +6 -0
- package/Spinner/types.d.ts +4 -0
- package/StatisticCard/StatisticCard.d.ts +7 -0
- package/StatisticCard/StatisticCard.js +7 -0
- package/StatisticCard/types.d.ts +21 -0
- package/Switch/Switch.d.ts +6 -0
- package/Switch/Switch.js +6 -0
- package/Switch/types.d.ts +8 -0
- package/Tabs/components/Tab/Tab.d.ts +4 -0
- package/Tabs/components/Tab/Tab.js +4 -0
- package/Tabs/components/Tab/types.d.ts +6 -0
- package/Tabs/components/TabBar/TabBar.d.ts +3 -0
- package/Tabs/components/TabBar/TabBar.js +3 -0
- package/Tabs/components/TabBar/types.d.ts +2 -0
- package/Tabs/components/TabPanel/TabPanel.d.ts +4 -0
- package/Tabs/components/TabPanel/TabPanel.js +4 -0
- package/Tabs/components/TabPanel/types.d.ts +3 -0
- package/Tabs/components/Tabs/Tabs.d.ts +11 -0
- package/Tabs/components/Tabs/Tabs.js +11 -0
- package/Tabs/components/Tabs/types.d.ts +4 -0
- package/Tabs/types.d.ts +4 -0
- package/Toast/Toast.d.ts +5 -0
- package/Toast/Toast.js +5 -0
- package/Toast/ToastProvider.d.ts +7 -0
- package/Toast/ToastProvider.js +7 -0
- package/Toast/hooks.d.ts +8 -0
- package/Toast/hooks.js +8 -0
- package/Toast/types.d.ts +24 -0
- package/Tooltip/Tooltip.d.ts +7 -0
- package/Tooltip/Tooltip.js +7 -0
- package/Tooltip/TooltipTrigger.d.ts +13 -0
- package/Tooltip/TooltipTrigger.js +7 -0
- package/Tooltip/types.d.ts +12 -0
- package/hooks/useElementWidth.d.ts +4 -3
- package/hooks/useElementWidth.js +4 -3
- package/hooks/useLayer.d.ts +7 -0
- package/hooks/useLayer.js +7 -0
- package/hooks/useOnClickOutside.d.ts +7 -0
- package/hooks/useOnClickOutside.js +7 -0
- package/native/Input.d.ts +3 -0
- package/native/Input.js +1 -0
- package/native/NativeTimeInput.d.ts +1 -0
- package/native/NativeTimeInput.js +1 -0
- package/native/Select.d.ts +1 -0
- package/native/Select.js +1 -0
- package/native/Textarea.d.ts +1 -0
- package/native/Textarea.js +1 -0
- package/package.json +2 -3
- package/polyglot/react.d.ts +19 -0
- package/polyglot/react.js +19 -0
- package/polyglot/types.d.ts +4 -0
- package/shared/dropdownField/FieldInput.d.ts +1 -0
- package/shared/dropdownField/FieldInput.js +1 -0
- package/shared/dropdownField/FieldShell.d.ts +4 -0
- package/shared/dropdownField/FieldShell.js +4 -0
- package/shared/dropdownField/SuggestionsDropdown.d.ts +4 -0
- package/shared/dropdownField/SuggestionsDropdown.js +4 -0
- package/shared/dropdownField/constants.d.ts +1 -0
- package/shared/dropdownField/constants.js +1 -0
- package/shared/dropdownField/shared.d.ts +7 -0
- package/shared/dropdownField/shared.js +7 -0
- package/shared/dropdownField/types.d.ts +7 -0
- package/shared/dropdownField/useActiveIndex.d.ts +4 -0
- package/shared/dropdownField/useActiveIndex.js +4 -0
- package/shared/dropdownField/useAsyncItems.d.ts +4 -0
- package/shared/dropdownField/useAsyncItems.js +4 -0
- package/shared/dropdownField/useDebouncedValue.d.ts +1 -0
- package/shared/dropdownField/useDebouncedValue.js +1 -0
- package/shared/dropdownField/useDropdownItems.d.ts +4 -0
- package/shared/dropdownField/useDropdownItems.js +4 -0
- package/shared/dropdownField/useDropdownPosition.d.ts +4 -0
- package/shared/dropdownField/useDropdownPosition.js +4 -0
- package/shared/dropdownField/useFieldOpenEffects.d.ts +4 -0
- package/shared/dropdownField/useFieldOpenEffects.js +4 -0
- package/shared/dropdownField/useListNavigation.d.ts +5 -0
- package/shared/dropdownField/useListNavigation.js +5 -0
- package/Alert/ai-documentation.md +0 -132
- package/Badge/ai-documentation.md +0 -155
- package/Banner/ai-documentation.md +0 -285
- package/Button/ai-documentation.md +0 -247
- package/CardMetric/ai-documentation.md +0 -277
- package/Checkbox/ai-documentation.md +0 -231
- package/Chip/ai-documentation.md +0 -281
- package/CodeEditor/ai-documentation.md +0 -350
- package/DateTimePicker/ai-documentation.md +0 -400
- package/Drawer/ai-documentation.md +0 -417
- package/EnhancedInput/ai-documentation.md +0 -352
- package/InputFile/ai-documentation.md +0 -420
- package/Modal/ai-documentation.md +0 -285
- package/PageHeader/ai-documentation.md +0 -511
- package/Pagination/ai-documentation.md +0 -509
- package/Popover/ai-documentation.md +0 -625
- package/ProgressBar/ai-documentation.md +0 -533
- package/Radio/ai-documentation.md +0 -243
- package/Select/ai-documentation.md +0 -374
- package/Skeleton/ai-documentation.md +0 -574
- package/Spinner/ai-documentation.md +0 -607
- package/Switch/ai-documentation.md +0 -312
- package/Tabs/ai-documentation.md +0 -475
- package/Toast/ai-documentation.md +0 -220
- package/Tooltip/ai-documentation.md +0 -340
- package/ai-documentation.md +0 -124
- package/native/ai-documentation.md +0 -485
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
# InputFile Component - @pushwoosh/dumb-components
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
- **Component Name**: InputFile
|
|
6
|
-
- **Import Path**: `@pushwoosh/dumb-components`
|
|
7
|
-
- **Files**:
|
|
8
|
-
- `/src/InputFile/InputFile.tsx` - Main component implementation
|
|
9
|
-
- `/src/InputFile/types.ts` - TypeScript type definitions
|
|
10
|
-
- `/src/InputFile/styles.ts` - Styled components
|
|
11
|
-
- `/src/InputFile/index.ts` - Component exports
|
|
12
|
-
- **Type**: Form Control
|
|
13
|
-
- **Description**: A file upload input component with file size validation, error handling, and custom button styling. Provides a text input display with an attachment button for file selection.
|
|
14
|
-
|
|
15
|
-
## TypeScript Interfaces
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
export type InputFileProps = {
|
|
19
|
-
name: string;
|
|
20
|
-
fileName?: string;
|
|
21
|
-
errorText?: string;
|
|
22
|
-
fileId?: string;
|
|
23
|
-
textId?: string;
|
|
24
|
-
buttonId?: string;
|
|
25
|
-
accept?: string;
|
|
26
|
-
label?: string;
|
|
27
|
-
buttonText?: string;
|
|
28
|
-
buttonWidth?: string;
|
|
29
|
-
placeholder?: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
maxSize?: number; // in megabytes
|
|
32
|
-
isIgnoreFileSize?: boolean;
|
|
33
|
-
onChange: (result: any) => void;
|
|
34
|
-
onError?: (message: string, field: string) => void;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
type FileProp = { file: File };
|
|
38
|
-
|
|
39
|
-
export type InputFileData = FileProp & {
|
|
40
|
-
[name: string]: string;
|
|
41
|
-
};
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Import & Usage
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
import { InputFile } from '@pushwoosh/dumb-components';
|
|
48
|
-
|
|
49
|
-
// Basic usage
|
|
50
|
-
function MyComponent() {
|
|
51
|
-
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
|
52
|
-
const [fileName, setFileName] = useState('');
|
|
53
|
-
const [error, setError] = useState('');
|
|
54
|
-
|
|
55
|
-
const handleFileChange = (result: any) => {
|
|
56
|
-
setSelectedFile(result.file);
|
|
57
|
-
setFileName(result.file.name);
|
|
58
|
-
setError('');
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const handleError = (message: string, field: string) => {
|
|
62
|
-
setError(message);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<InputFile
|
|
67
|
-
name="document"
|
|
68
|
-
fileName={fileName}
|
|
69
|
-
errorText={error}
|
|
70
|
-
label="Upload Document"
|
|
71
|
-
buttonText="Browse"
|
|
72
|
-
placeholder="No file selected"
|
|
73
|
-
onChange={handleFileChange}
|
|
74
|
-
onError={handleError}
|
|
75
|
-
/>
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Image upload with restrictions
|
|
80
|
-
function ImageUpload() {
|
|
81
|
-
const [imageData, setImageData] = useState('');
|
|
82
|
-
const [fileName, setFileName] = useState('');
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<InputFile
|
|
86
|
-
name="image"
|
|
87
|
-
fileName={fileName}
|
|
88
|
-
accept="image/*"
|
|
89
|
-
maxSize={5} // 5MB limit
|
|
90
|
-
label="Profile Picture"
|
|
91
|
-
buttonText="Choose Image"
|
|
92
|
-
placeholder="Select an image file"
|
|
93
|
-
onChange={(result) => {
|
|
94
|
-
setImageData(result.image);
|
|
95
|
-
setFileName(result.file.name);
|
|
96
|
-
}}
|
|
97
|
-
onError={(message) => console.error(message)}
|
|
98
|
-
/>
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Advanced Examples
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
// Document upload with validation
|
|
107
|
-
function DocumentUpload() {
|
|
108
|
-
const [uploadState, setUploadState] = useState({
|
|
109
|
-
fileName: '',
|
|
110
|
-
errorText: '',
|
|
111
|
-
isUploading: false,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
const handleFileChange = async (result: any) => {
|
|
115
|
-
setUploadState(prev => ({
|
|
116
|
-
...prev,
|
|
117
|
-
fileName: result.file.name,
|
|
118
|
-
errorText: '',
|
|
119
|
-
isUploading: true,
|
|
120
|
-
}));
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
// Simulate upload process
|
|
124
|
-
await uploadToServer(result.file);
|
|
125
|
-
setUploadState(prev => ({ ...prev, isUploading: false }));
|
|
126
|
-
} catch (error) {
|
|
127
|
-
setUploadState(prev => ({
|
|
128
|
-
...prev,
|
|
129
|
-
errorText: 'Upload failed. Please try again.',
|
|
130
|
-
isUploading: false,
|
|
131
|
-
}));
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const handleError = (message: string, field: string) => {
|
|
136
|
-
setUploadState(prev => ({ ...prev, errorText: message }));
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
return (
|
|
140
|
-
<InputFile
|
|
141
|
-
name="document"
|
|
142
|
-
fileName={uploadState.fileName}
|
|
143
|
-
errorText={uploadState.errorText}
|
|
144
|
-
disabled={uploadState.isUploading}
|
|
145
|
-
accept=".pdf,.doc,.docx"
|
|
146
|
-
maxSize={10}
|
|
147
|
-
label="Contract Document"
|
|
148
|
-
buttonText={uploadState.isUploading ? "Uploading..." : "Upload File"}
|
|
149
|
-
placeholder="PDF, DOC, or DOCX files only"
|
|
150
|
-
onChange={handleFileChange}
|
|
151
|
-
onError={handleError}
|
|
152
|
-
/>
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Multiple file types with custom validation
|
|
157
|
-
function MultiTypeUpload() {
|
|
158
|
-
const [files, setFiles] = useState<{[key: string]: any}>({});
|
|
159
|
-
const [errors, setErrors] = useState<{[key: string]: string}>({});
|
|
160
|
-
|
|
161
|
-
const createFileHandler = (fieldName: string) => (result: any) => {
|
|
162
|
-
setFiles(prev => ({ ...prev, [fieldName]: result }));
|
|
163
|
-
setErrors(prev => ({ ...prev, [fieldName]: '' }));
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const createErrorHandler = (fieldName: string) => (message: string) => {
|
|
167
|
-
setErrors(prev => ({ ...prev, [fieldName]: message }));
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<div>
|
|
172
|
-
<InputFile
|
|
173
|
-
name="resume"
|
|
174
|
-
fileName={files.resume?.file?.name || ''}
|
|
175
|
-
errorText={errors.resume}
|
|
176
|
-
accept=".pdf"
|
|
177
|
-
maxSize={2}
|
|
178
|
-
label="Resume (PDF)"
|
|
179
|
-
buttonText="Upload Resume"
|
|
180
|
-
placeholder="Select your resume"
|
|
181
|
-
onChange={createFileHandler('resume')}
|
|
182
|
-
onError={createErrorHandler('resume')}
|
|
183
|
-
/>
|
|
184
|
-
|
|
185
|
-
<InputFile
|
|
186
|
-
name="portfolio"
|
|
187
|
-
fileName={files.portfolio?.file?.name || ''}
|
|
188
|
-
errorText={errors.portfolio}
|
|
189
|
-
accept=".zip,.rar"
|
|
190
|
-
maxSize={50}
|
|
191
|
-
label="Portfolio (ZIP/RAR)"
|
|
192
|
-
buttonText="Upload Portfolio"
|
|
193
|
-
placeholder="Select your portfolio archive"
|
|
194
|
-
onChange={createFileHandler('portfolio')}
|
|
195
|
-
onError={createErrorHandler('portfolio')}
|
|
196
|
-
/>
|
|
197
|
-
|
|
198
|
-
<InputFile
|
|
199
|
-
name="photo"
|
|
200
|
-
fileName={files.photo?.file?.name || ''}
|
|
201
|
-
errorText={errors.photo}
|
|
202
|
-
accept="image/jpeg,image/png"
|
|
203
|
-
maxSize={1}
|
|
204
|
-
label="Profile Photo"
|
|
205
|
-
buttonText="Choose Photo"
|
|
206
|
-
placeholder="JPEG or PNG only"
|
|
207
|
-
onChange={createFileHandler('photo')}
|
|
208
|
-
onError={createErrorHandler('photo')}
|
|
209
|
-
/>
|
|
210
|
-
</div>
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Form integration with React Hook Form
|
|
215
|
-
function FormWithFileUpload() {
|
|
216
|
-
const { register, handleSubmit, setValue, watch, formState: { errors } } = useForm();
|
|
217
|
-
const [fileErrors, setFileErrors] = useState<{[key: string]: string}>({});
|
|
218
|
-
|
|
219
|
-
const attachmentFile = watch('attachment');
|
|
220
|
-
|
|
221
|
-
const onSubmit = (data: any) => {
|
|
222
|
-
console.log('Form data:', data);
|
|
223
|
-
// Handle form submission with file data
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
const handleFileChange = (result: any) => {
|
|
227
|
-
setValue('attachment', result);
|
|
228
|
-
setFileErrors(prev => ({ ...prev, attachment: '' }));
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const handleFileError = (message: string, field: string) => {
|
|
232
|
-
setFileErrors(prev => ({ ...prev, [field]: message }));
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
return (
|
|
236
|
-
<form onSubmit={handleSubmit(onSubmit)}>
|
|
237
|
-
<div>
|
|
238
|
-
<label>Title</label>
|
|
239
|
-
<input
|
|
240
|
-
{...register('title', { required: 'Title is required' })}
|
|
241
|
-
type="text"
|
|
242
|
-
/>
|
|
243
|
-
{errors.title && <span>{errors.title.message}</span>}
|
|
244
|
-
</div>
|
|
245
|
-
|
|
246
|
-
<InputFile
|
|
247
|
-
name="attachment"
|
|
248
|
-
fileName={attachmentFile?.file?.name || ''}
|
|
249
|
-
errorText={fileErrors.attachment}
|
|
250
|
-
label="Supporting Document"
|
|
251
|
-
buttonText="Attach File"
|
|
252
|
-
placeholder="Optional file attachment"
|
|
253
|
-
maxSize={5}
|
|
254
|
-
onChange={handleFileChange}
|
|
255
|
-
onError={handleFileError}
|
|
256
|
-
/>
|
|
257
|
-
|
|
258
|
-
<button type="submit">Submit</button>
|
|
259
|
-
</form>
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Drag and drop enhancement (conceptual)
|
|
264
|
-
function EnhancedFileUpload() {
|
|
265
|
-
const [isDragOver, setIsDragOver] = useState(false);
|
|
266
|
-
const [fileData, setFileData] = useState({ fileName: '', error: '' });
|
|
267
|
-
|
|
268
|
-
const handleFileChange = (result: any) => {
|
|
269
|
-
setFileData({ fileName: result.file.name, error: '' });
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
const handleError = (message: string) => {
|
|
273
|
-
setFileData(prev => ({ ...prev, error: message }));
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
return (
|
|
277
|
-
<div
|
|
278
|
-
style={{
|
|
279
|
-
border: isDragOver ? '2px dashed #007bff' : '2px dashed #ccc',
|
|
280
|
-
padding: '20px',
|
|
281
|
-
borderRadius: '8px',
|
|
282
|
-
backgroundColor: isDragOver ? '#f8f9fa' : 'transparent',
|
|
283
|
-
}}
|
|
284
|
-
onDragOver={(e) => {
|
|
285
|
-
e.preventDefault();
|
|
286
|
-
setIsDragOver(true);
|
|
287
|
-
}}
|
|
288
|
-
onDragLeave={() => setIsDragOver(false)}
|
|
289
|
-
onDrop={(e) => {
|
|
290
|
-
e.preventDefault();
|
|
291
|
-
setIsDragOver(false);
|
|
292
|
-
// Handle dropped files here
|
|
293
|
-
}}
|
|
294
|
-
>
|
|
295
|
-
<InputFile
|
|
296
|
-
name="dropFile"
|
|
297
|
-
fileName={fileData.fileName}
|
|
298
|
-
errorText={fileData.error}
|
|
299
|
-
label="Drag & Drop or Browse"
|
|
300
|
-
buttonText="Browse Files"
|
|
301
|
-
placeholder="Drop files here or click to browse"
|
|
302
|
-
onChange={handleFileChange}
|
|
303
|
-
onError={handleError}
|
|
304
|
-
/>
|
|
305
|
-
</div>
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
## Props Reference
|
|
311
|
-
|
|
312
|
-
| Prop | Type | Default | Required | Description |
|
|
313
|
-
|------|------|---------|----------|-------------|
|
|
314
|
-
| `name` | `string` | - | Yes | Name attribute for the file input |
|
|
315
|
-
| `fileName` | `string` | `undefined` | No | Display name of the selected file |
|
|
316
|
-
| `errorText` | `string` | `undefined` | No | Error message to display |
|
|
317
|
-
| `fileId` | `string` | `undefined` | No | ID for the hidden file input |
|
|
318
|
-
| `textId` | `string` | `undefined` | No | ID for the text display input |
|
|
319
|
-
| `buttonId` | `string` | `undefined` | No | ID for the browse button |
|
|
320
|
-
| `accept` | `string` | `undefined` | No | File types to accept (MIME types or extensions) |
|
|
321
|
-
| `label` | `string` | `undefined` | No | Label text displayed above the input |
|
|
322
|
-
| `buttonText` | `string` | `undefined` | No | Text displayed on the browse button |
|
|
323
|
-
| `buttonWidth` | `string` | `undefined` | No | Custom width for the browse button |
|
|
324
|
-
| `placeholder` | `string` | `undefined` | No | Placeholder text for the display input |
|
|
325
|
-
| `disabled` | `boolean` | `undefined` | No | Whether the input is disabled |
|
|
326
|
-
| `maxSize` | `number` | `undefined` | No | Maximum file size in megabytes |
|
|
327
|
-
| `isIgnoreFileSize` | `boolean` | `false` | No | Whether to skip file size validation |
|
|
328
|
-
| `onChange` | `(result: any) => void` | - | Yes | Callback fired when file is selected |
|
|
329
|
-
| `onError` | `(message: string, field: string) => void` | `() => {}` | No | Callback fired when validation fails |
|
|
330
|
-
|
|
331
|
-
## AI Agent Guidelines
|
|
332
|
-
|
|
333
|
-
### Recommended Patterns
|
|
334
|
-
|
|
335
|
-
1. **File Validation**: Always implement proper file validation
|
|
336
|
-
```typescript
|
|
337
|
-
<InputFile
|
|
338
|
-
name="document"
|
|
339
|
-
accept=".pdf,.doc,.docx"
|
|
340
|
-
maxSize={5}
|
|
341
|
-
onChange={handleFileChange}
|
|
342
|
-
onError={(message, field) => setErrors(prev => ({ ...prev, [field]: message }))}
|
|
343
|
-
/>
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
2. **State Management**: Track file state, errors, and loading states
|
|
347
|
-
```typescript
|
|
348
|
-
const [fileState, setFileState] = useState({
|
|
349
|
-
fileName: '',
|
|
350
|
-
file: null,
|
|
351
|
-
error: '',
|
|
352
|
-
isUploading: false,
|
|
353
|
-
});
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
3. **Error Handling**: Provide meaningful error messages
|
|
357
|
-
```typescript
|
|
358
|
-
const handleError = (message: string, field: string) => {
|
|
359
|
-
// Log error for debugging
|
|
360
|
-
console.error(`File upload error for ${field}:`, message);
|
|
361
|
-
|
|
362
|
-
// Update UI state
|
|
363
|
-
setErrors(prev => ({ ...prev, [field]: message }));
|
|
364
|
-
};
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Common Mistakes to Avoid
|
|
368
|
-
|
|
369
|
-
1. **Missing Error Handling**: Always provide an `onError` callback
|
|
370
|
-
2. **Insufficient Validation**: Don't rely only on client-side validation
|
|
371
|
-
3. **Large File Limits**: Be mindful of server upload limits when setting `maxSize`
|
|
372
|
-
4. **File Type Restrictions**: Use specific MIME types rather than generic patterns
|
|
373
|
-
5. **State Synchronization**: Ensure `fileName` reflects the actual selected file
|
|
374
|
-
|
|
375
|
-
### Integration Tips
|
|
376
|
-
|
|
377
|
-
1. **File Processing**: The component reads files as Data URLs by default
|
|
378
|
-
```typescript
|
|
379
|
-
// Result structure
|
|
380
|
-
{
|
|
381
|
-
file: File, // Original File object
|
|
382
|
-
[name]: string // Base64 data URL
|
|
383
|
-
}
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
2. **Server Upload**: Extract the File object for server uploads
|
|
387
|
-
```typescript
|
|
388
|
-
const handleFileChange = async (result: any) => {
|
|
389
|
-
const formData = new FormData();
|
|
390
|
-
formData.append('file', result.file);
|
|
391
|
-
|
|
392
|
-
try {
|
|
393
|
-
await uploadToServer(formData);
|
|
394
|
-
} catch (error) {
|
|
395
|
-
// Handle upload error
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
3. **Form Integration**: Works well with form libraries
|
|
401
|
-
```typescript
|
|
402
|
-
// With React Hook Form
|
|
403
|
-
setValue('fileField', result.file);
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
4. **Accessibility**: Component includes proper labels and ARIA attributes
|
|
407
|
-
5. **File Size Limits**: Consider both client and server size restrictions
|
|
408
|
-
```typescript
|
|
409
|
-
// Client validation
|
|
410
|
-
maxSize={10} // 10MB
|
|
411
|
-
|
|
412
|
-
// Server validation should also be implemented
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
## Related Components
|
|
416
|
-
|
|
417
|
-
- **Button**: Used internally for the browse functionality
|
|
418
|
-
- **FieldBox**: Used for layout and error display
|
|
419
|
-
- **Input**: For text-based form fields
|
|
420
|
-
- **Modal**: For advanced file management interfaces
|
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
# Modal - AI Documentation
|
|
2
|
-
|
|
3
|
-
> Auto-generated AI agent documentation for Modal component
|
|
4
|
-
> Part of @pushwoosh/dumb-components library
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
**Component:** Modal
|
|
8
|
-
**Import Path:** `import { Modal, ModalTitle, ModalConfirm, ModalConfirmProvider, useModalConfirm, ModalHeader, ModalBodyGroup, ModalBodyItem, ModalBody, ModalFooter } from '@pushwoosh/dumb-components'`
|
|
9
|
-
**Files:**
|
|
10
|
-
- `Modal/components/Modal/Modal.tsx` - Main modal component
|
|
11
|
-
- `Modal/components/Modal/types.ts` - TypeScript interfaces
|
|
12
|
-
- `Modal/components/Modal/maps.ts` - Size mappings
|
|
13
|
-
- `Modal/components/Modal/styles.tsx` - Styled components
|
|
14
|
-
- `Modal/components/ModalTitle/` - Title component
|
|
15
|
-
- `Modal/components/ModalConfirm/` - Confirmation dialog
|
|
16
|
-
- `Modal/components/ModalContent/` - Content layout components
|
|
17
|
-
**Type:** Layout Component / Overlay
|
|
18
|
-
**Description:** Flexible modal dialog system with size variants, confirmation dialogs, and content layout helpers. Supports keyboard navigation (ESC to close) and click-outside-to-close functionality.
|
|
19
|
-
|
|
20
|
-
## TypeScript Interfaces
|
|
21
|
-
|
|
22
|
-
### ModalProps
|
|
23
|
-
```typescript
|
|
24
|
-
interface ModalProps {
|
|
25
|
-
size: 'small' | 'medium' | 'large' | 'full'; // Modal width
|
|
26
|
-
zIndex?: number; // Stack order (default: 10000)
|
|
27
|
-
isOpen: boolean; // Control visibility
|
|
28
|
-
onClose?: () => any; // Close handler
|
|
29
|
-
children: ReactNode; // Modal content
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### ModalTitleProps
|
|
34
|
-
```typescript
|
|
35
|
-
interface ModalTitleProps {
|
|
36
|
-
onClose?: () => void; // Optional close button handler
|
|
37
|
-
children: ReactNode; // Title content
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### ModalConfirmProps
|
|
42
|
-
```typescript
|
|
43
|
-
interface ModalConfirmProps {
|
|
44
|
-
isOpen: boolean;
|
|
45
|
-
title: string;
|
|
46
|
-
size?: 'small' | 'medium' | 'large' | 'full';
|
|
47
|
-
description?: ReactNode;
|
|
48
|
-
confirmButtonText?: string;
|
|
49
|
-
confirmButtonColor?: 'primary' | 'secondary' | 'danger';
|
|
50
|
-
cancelButtonText?: string;
|
|
51
|
-
callback?: () => void;
|
|
52
|
-
onAccept: () => void;
|
|
53
|
-
onCancel: () => void;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Import & Usage
|
|
58
|
-
|
|
59
|
-
### Basic Modal
|
|
60
|
-
```tsx
|
|
61
|
-
import { Modal, ModalTitle, ModalBody, ModalFooter } from '@pushwoosh/dumb-components';
|
|
62
|
-
import { Button } from '@pushwoosh/dumb-components';
|
|
63
|
-
|
|
64
|
-
function MyModal({ isOpen, onClose }) {
|
|
65
|
-
return (
|
|
66
|
-
<Modal size="medium" isOpen={isOpen} onClose={onClose}>
|
|
67
|
-
<ModalTitle onClose={onClose}>
|
|
68
|
-
Modal Title
|
|
69
|
-
</ModalTitle>
|
|
70
|
-
<ModalBody>
|
|
71
|
-
<p>Modal content goes here</p>
|
|
72
|
-
</ModalBody>
|
|
73
|
-
<ModalFooter>
|
|
74
|
-
<Button variant="secondary" onClick={onClose}>Cancel</Button>
|
|
75
|
-
<Button variant="primary">Confirm</Button>
|
|
76
|
-
</ModalFooter>
|
|
77
|
-
</Modal>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Confirmation Dialog
|
|
83
|
-
```tsx
|
|
84
|
-
import { ModalConfirm } from '@pushwoosh/dumb-components';
|
|
85
|
-
|
|
86
|
-
function DeleteConfirmation({ isOpen, onDelete, onCancel }) {
|
|
87
|
-
return (
|
|
88
|
-
<ModalConfirm
|
|
89
|
-
isOpen={isOpen}
|
|
90
|
-
title="Delete Item?"
|
|
91
|
-
description="This action cannot be undone."
|
|
92
|
-
confirmButtonText="Delete"
|
|
93
|
-
confirmButtonColor="danger"
|
|
94
|
-
onAccept={onDelete}
|
|
95
|
-
onCancel={onCancel}
|
|
96
|
-
/>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Using Modal Confirm Provider
|
|
102
|
-
```tsx
|
|
103
|
-
import { ModalConfirmProvider, useModalConfirm } from '@pushwoosh/dumb-components';
|
|
104
|
-
|
|
105
|
-
// Wrap app with provider
|
|
106
|
-
function App() {
|
|
107
|
-
return (
|
|
108
|
-
<ModalConfirmProvider>
|
|
109
|
-
<YourApp />
|
|
110
|
-
</ModalConfirmProvider>
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Use in component
|
|
115
|
-
function DeleteButton() {
|
|
116
|
-
const { openModalConfirm } = useModalConfirm();
|
|
117
|
-
|
|
118
|
-
const handleDelete = () => {
|
|
119
|
-
openModalConfirm({
|
|
120
|
-
title: 'Delete Item?',
|
|
121
|
-
description: 'This cannot be undone.',
|
|
122
|
-
confirmButtonColor: 'danger',
|
|
123
|
-
onAccept: () => {
|
|
124
|
-
// Perform delete
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
return <Button onClick={handleDelete}>Delete</Button>;
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Advanced Examples
|
|
134
|
-
|
|
135
|
-
### Modal with Form
|
|
136
|
-
```tsx
|
|
137
|
-
import { Modal, ModalTitle, ModalBody, ModalFooter } from '@pushwoosh/dumb-components';
|
|
138
|
-
import { EnhancedInput, Button } from '@pushwoosh/dumb-components';
|
|
139
|
-
|
|
140
|
-
function FormModal({ isOpen, onClose, onSubmit }) {
|
|
141
|
-
const [formData, setFormData] = useState({ name: '', email: '' });
|
|
142
|
-
|
|
143
|
-
const handleSubmit = () => {
|
|
144
|
-
onSubmit(formData);
|
|
145
|
-
onClose();
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
return (
|
|
149
|
-
<Modal size="small" isOpen={isOpen} onClose={onClose}>
|
|
150
|
-
<ModalTitle onClose={onClose}>User Details</ModalTitle>
|
|
151
|
-
<ModalBody>
|
|
152
|
-
<ModalBodyGroup>
|
|
153
|
-
<ModalBodyItem>
|
|
154
|
-
<EnhancedInput
|
|
155
|
-
label="Name"
|
|
156
|
-
value={formData.name}
|
|
157
|
-
onChange={(value) => setFormData({ ...formData, name: value })}
|
|
158
|
-
/>
|
|
159
|
-
</ModalBodyItem>
|
|
160
|
-
<ModalBodyItem>
|
|
161
|
-
<EnhancedInput
|
|
162
|
-
label="Email"
|
|
163
|
-
type="email"
|
|
164
|
-
value={formData.email}
|
|
165
|
-
onChange={(value) => setFormData({ ...formData, email: value })}
|
|
166
|
-
/>
|
|
167
|
-
</ModalBodyItem>
|
|
168
|
-
</ModalBodyGroup>
|
|
169
|
-
</ModalBody>
|
|
170
|
-
<ModalFooter>
|
|
171
|
-
<Button variant="secondary" onClick={onClose}>Cancel</Button>
|
|
172
|
-
<Button variant="primary" onClick={handleSubmit}>Save</Button>
|
|
173
|
-
</ModalFooter>
|
|
174
|
-
</Modal>
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Nested Modals
|
|
180
|
-
```tsx
|
|
181
|
-
function ParentModal({ isOpen, onClose }) {
|
|
182
|
-
const [childOpen, setChildOpen] = useState(false);
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<>
|
|
186
|
-
<Modal size="large" isOpen={isOpen} onClose={onClose} zIndex={10000}>
|
|
187
|
-
<ModalTitle onClose={onClose}>Parent Modal</ModalTitle>
|
|
188
|
-
<ModalBody>
|
|
189
|
-
<Button onClick={() => setChildOpen(true)}>
|
|
190
|
-
Open Child Modal
|
|
191
|
-
</Button>
|
|
192
|
-
</ModalBody>
|
|
193
|
-
</Modal>
|
|
194
|
-
|
|
195
|
-
<Modal size="small" isOpen={childOpen} onClose={() => setChildOpen(false)} zIndex={10001}>
|
|
196
|
-
<ModalTitle onClose={() => setChildOpen(false)}>Child Modal</ModalTitle>
|
|
197
|
-
<ModalBody>
|
|
198
|
-
Child content with higher z-index
|
|
199
|
-
</ModalBody>
|
|
200
|
-
</Modal>
|
|
201
|
-
</>
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Full Screen Modal
|
|
207
|
-
```tsx
|
|
208
|
-
function FullScreenModal({ isOpen, onClose, content }) {
|
|
209
|
-
return (
|
|
210
|
-
<Modal size="full" isOpen={isOpen} onClose={onClose}>
|
|
211
|
-
<ModalHeader>
|
|
212
|
-
<ModalTitle onClose={onClose}>Full Screen View</ModalTitle>
|
|
213
|
-
</ModalHeader>
|
|
214
|
-
<ModalBody style={{ height: 'calc(100vh - 120px)', overflow: 'auto' }}>
|
|
215
|
-
{content}
|
|
216
|
-
</ModalBody>
|
|
217
|
-
</Modal>
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
## Props Reference
|
|
223
|
-
|
|
224
|
-
### Modal Props
|
|
225
|
-
| Prop | Type | Required | Default | Description |
|
|
226
|
-
|------|------|----------|---------|-------------|
|
|
227
|
-
| `size` | `'small' \| 'medium' \| 'large' \| 'full'` | ✓ | - | Modal width (380px / 640px / 960px / 100%) |
|
|
228
|
-
| `isOpen` | `boolean` | ✓ | - | Controls modal visibility |
|
|
229
|
-
| `onClose` | `() => void` | - | - | Handler for close events (ESC key, backdrop click) |
|
|
230
|
-
| `zIndex` | `number` | - | 10000 | Stack order for overlapping modals |
|
|
231
|
-
| `children` | `ReactNode \| (() => ReactNode)` | - | - | Modal content (can be function for lazy rendering) |
|
|
232
|
-
|
|
233
|
-
### ModalTitle Props
|
|
234
|
-
| Prop | Type | Required | Default | Description |
|
|
235
|
-
|------|------|----------|---------|-------------|
|
|
236
|
-
| `onClose` | `() => void` | - | - | Shows close button when provided |
|
|
237
|
-
| `children` | `ReactNode` | ✓ | - | Title content |
|
|
238
|
-
|
|
239
|
-
### ModalConfirm Props
|
|
240
|
-
| Prop | Type | Required | Default | Description |
|
|
241
|
-
|------|------|----------|---------|-------------|
|
|
242
|
-
| `isOpen` | `boolean` | ✓ | - | Controls visibility |
|
|
243
|
-
| `title` | `string` | ✓ | - | Confirmation dialog title |
|
|
244
|
-
| `size` | `'small' \| 'medium' \| 'large' \| 'full'` | - | `'small'` | Dialog size |
|
|
245
|
-
| `description` | `ReactNode` | - | - | Additional description text |
|
|
246
|
-
| `confirmButtonText` | `string` | - | `'Confirm'` | Accept button label |
|
|
247
|
-
| `confirmButtonColor` | `'primary' \| 'secondary' \| 'danger'` | - | `'primary'` | Accept button color |
|
|
248
|
-
| `cancelButtonText` | `string` | - | `'Cancel'` | Cancel button label |
|
|
249
|
-
| `onAccept` | `() => void` | ✓ | - | Accept handler |
|
|
250
|
-
| `onCancel` | `() => void` | ✓ | - | Cancel handler |
|
|
251
|
-
| `callback` | `() => void` | - | - | Optional callback after accept |
|
|
252
|
-
|
|
253
|
-
## AI Agent Guidelines
|
|
254
|
-
|
|
255
|
-
### ✅ Recommended Patterns
|
|
256
|
-
- Always provide `onClose` handler for user control
|
|
257
|
-
- Use appropriate modal sizes (prefer `small` for forms, `medium` for content)
|
|
258
|
-
- Implement keyboard navigation (ESC to close is automatic when `onClose` provided)
|
|
259
|
-
- Use `ModalConfirm` for destructive actions
|
|
260
|
-
- Wrap app with `ModalConfirmProvider` when using `useModalConfirm` hook
|
|
261
|
-
- Use lazy rendering (function children) for heavy content
|
|
262
|
-
- Structure content with `ModalTitle`, `ModalBody`, `ModalFooter`
|
|
263
|
-
|
|
264
|
-
### ❌ Common Mistakes to Avoid
|
|
265
|
-
- Don't forget to control `isOpen` state
|
|
266
|
-
- Don't nest modals without proper z-index management
|
|
267
|
-
- Don't use `full` size unless necessary
|
|
268
|
-
- Don't put scrollable content directly in Modal - use ModalBody
|
|
269
|
-
- Don't forget to handle onClose for backdrop clicks
|
|
270
|
-
- Avoid inline styles on Modal component - style inner components instead
|
|
271
|
-
|
|
272
|
-
### Integration Tips
|
|
273
|
-
- Modal uses React Portal - renders outside component tree
|
|
274
|
-
- Body scroll is locked when modal is open (via LockBody component)
|
|
275
|
-
- Click outside and ESC key automatically trigger onClose
|
|
276
|
-
- For forms in modals, handle validation before closing
|
|
277
|
-
- Use `ModalBodyGroup` and `ModalBodyItem` for form layouts
|
|
278
|
-
- Modal animations are handled by styled-components transitions
|
|
279
|
-
|
|
280
|
-
## Related Components
|
|
281
|
-
- **Button** - For modal actions
|
|
282
|
-
- **EnhancedInput** - For modal forms
|
|
283
|
-
- **Toast** - For success/error feedback after modal actions
|
|
284
|
-
- **Drawer** - Alternative overlay for side panels
|
|
285
|
-
- **Alert** - For inline warnings within modals
|