@pushwoosh/dumb-components 1.1.148 → 1.1.150
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 +12 -1
- package/Drawer/components/Drawer/types.d.ts +10 -1
- 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,607 +0,0 @@
|
|
|
1
|
-
# Spinner Component - @pushwoosh/dumb-components
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
- **Component Name**: Spinner
|
|
6
|
-
- **Import Path**: `@pushwoosh/dumb-components`
|
|
7
|
-
- **Files**:
|
|
8
|
-
- `/src/Spinner/Spinner.tsx` - Main component implementation
|
|
9
|
-
- `/src/Spinner/types.ts` - TypeScript type definitions
|
|
10
|
-
- `/src/Spinner/styles.ts` - Styled components and animations
|
|
11
|
-
- `/src/Spinner/maps.ts` - Size mapping utilities
|
|
12
|
-
- `/src/Spinner/assets/` - SVG icon assets
|
|
13
|
-
- `/src/Spinner/index.ts` - Component exports
|
|
14
|
-
- **Type**: Feedback/Loading
|
|
15
|
-
- **Description**: A spinning loading indicator component available in small and medium sizes. Features smooth CSS animations and customizable colors to indicate loading or processing states.
|
|
16
|
-
|
|
17
|
-
## TypeScript Interfaces
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
export interface SpinnerProps {
|
|
21
|
-
readonly boxRef?: Ref<HTMLDivElement>;
|
|
22
|
-
readonly color?: string;
|
|
23
|
-
readonly size: 'small' | 'medium';
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Import & Usage
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { Spinner } from '@pushwoosh/dumb-components';
|
|
31
|
-
|
|
32
|
-
// Basic usage
|
|
33
|
-
function MyComponent() {
|
|
34
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
35
|
-
|
|
36
|
-
const handleLoad = async () => {
|
|
37
|
-
setIsLoading(true);
|
|
38
|
-
try {
|
|
39
|
-
await fetchData();
|
|
40
|
-
} finally {
|
|
41
|
-
setIsLoading(false);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div>
|
|
47
|
-
<button onClick={handleLoad} disabled={isLoading}>
|
|
48
|
-
{isLoading ? 'Loading...' : 'Load Data'}
|
|
49
|
-
</button>
|
|
50
|
-
|
|
51
|
-
{isLoading && (
|
|
52
|
-
<div style={{ marginTop: '16px' }}>
|
|
53
|
-
<Spinner size="medium" />
|
|
54
|
-
</div>
|
|
55
|
-
)}
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Different sizes
|
|
61
|
-
function SpinnerSizes() {
|
|
62
|
-
return (
|
|
63
|
-
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
|
64
|
-
<div>
|
|
65
|
-
<p>Small:</p>
|
|
66
|
-
<Spinner size="small" />
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<div>
|
|
70
|
-
<p>Medium:</p>
|
|
71
|
-
<Spinner size="medium" />
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Custom colors
|
|
78
|
-
function ColoredSpinners() {
|
|
79
|
-
return (
|
|
80
|
-
<div style={{ display: 'flex', gap: '16px' }}>
|
|
81
|
-
<Spinner size="medium" color="#007bff" />
|
|
82
|
-
<Spinner size="medium" color="#28a745" />
|
|
83
|
-
<Spinner size="medium" color="#dc3545" />
|
|
84
|
-
<Spinner size="medium" color="#ffc107" />
|
|
85
|
-
</div>
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Advanced Examples
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// Loading button
|
|
94
|
-
function LoadingButton() {
|
|
95
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
96
|
-
|
|
97
|
-
const handleClick = async () => {
|
|
98
|
-
setIsLoading(true);
|
|
99
|
-
try {
|
|
100
|
-
await performAction();
|
|
101
|
-
console.log('Action completed');
|
|
102
|
-
} catch (error) {
|
|
103
|
-
console.error('Action failed:', error);
|
|
104
|
-
} finally {
|
|
105
|
-
setIsLoading(false);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<button
|
|
111
|
-
onClick={handleClick}
|
|
112
|
-
disabled={isLoading}
|
|
113
|
-
style={{
|
|
114
|
-
padding: '12px 20px',
|
|
115
|
-
display: 'flex',
|
|
116
|
-
alignItems: 'center',
|
|
117
|
-
gap: '8px',
|
|
118
|
-
backgroundColor: '#007bff',
|
|
119
|
-
color: 'white',
|
|
120
|
-
border: 'none',
|
|
121
|
-
borderRadius: '4px',
|
|
122
|
-
cursor: isLoading ? 'not-allowed' : 'pointer',
|
|
123
|
-
opacity: isLoading ? 0.7 : 1,
|
|
124
|
-
}}
|
|
125
|
-
>
|
|
126
|
-
{isLoading && <Spinner size="small" color="white" />}
|
|
127
|
-
{isLoading ? 'Processing...' : 'Submit'}
|
|
128
|
-
</button>
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Loading overlay
|
|
133
|
-
function LoadingOverlay({ isLoading, children }: { isLoading: boolean, children: React.ReactNode }) {
|
|
134
|
-
return (
|
|
135
|
-
<div style={{ position: 'relative' }}>
|
|
136
|
-
{children}
|
|
137
|
-
|
|
138
|
-
{isLoading && (
|
|
139
|
-
<div
|
|
140
|
-
style={{
|
|
141
|
-
position: 'absolute',
|
|
142
|
-
top: 0,
|
|
143
|
-
left: 0,
|
|
144
|
-
right: 0,
|
|
145
|
-
bottom: 0,
|
|
146
|
-
backgroundColor: 'rgba(255, 255, 255, 0.8)',
|
|
147
|
-
display: 'flex',
|
|
148
|
-
flexDirection: 'column',
|
|
149
|
-
alignItems: 'center',
|
|
150
|
-
justifyContent: 'center',
|
|
151
|
-
gap: '16px',
|
|
152
|
-
zIndex: 10,
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
155
|
-
<Spinner size="medium" color="#007bff" />
|
|
156
|
-
<p style={{ margin: 0, color: '#666' }}>Loading...</p>
|
|
157
|
-
</div>
|
|
158
|
-
)}
|
|
159
|
-
</div>
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Usage with LoadingOverlay
|
|
164
|
-
function DataTable() {
|
|
165
|
-
const [data, setData] = useState([]);
|
|
166
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
167
|
-
|
|
168
|
-
const loadData = async () => {
|
|
169
|
-
setIsLoading(true);
|
|
170
|
-
try {
|
|
171
|
-
const result = await fetchTableData();
|
|
172
|
-
setData(result);
|
|
173
|
-
} catch (error) {
|
|
174
|
-
console.error('Failed to load data:', error);
|
|
175
|
-
} finally {
|
|
176
|
-
setIsLoading(false);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
useEffect(() => {
|
|
181
|
-
loadData();
|
|
182
|
-
}, []);
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<LoadingOverlay isLoading={isLoading}>
|
|
186
|
-
<table style={{ width: '100%', minHeight: '200px' }}>
|
|
187
|
-
<thead>
|
|
188
|
-
<tr>
|
|
189
|
-
<th>ID</th>
|
|
190
|
-
<th>Name</th>
|
|
191
|
-
<th>Status</th>
|
|
192
|
-
</tr>
|
|
193
|
-
</thead>
|
|
194
|
-
<tbody>
|
|
195
|
-
{data.map(item => (
|
|
196
|
-
<tr key={item.id}>
|
|
197
|
-
<td>{item.id}</td>
|
|
198
|
-
<td>{item.name}</td>
|
|
199
|
-
<td>{item.status}</td>
|
|
200
|
-
</tr>
|
|
201
|
-
))}
|
|
202
|
-
</tbody>
|
|
203
|
-
</table>
|
|
204
|
-
</LoadingOverlay>
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Conditional loading states
|
|
209
|
-
function ConditionalLoading() {
|
|
210
|
-
const [loadingStates, setLoadingStates] = useState({
|
|
211
|
-
user: false,
|
|
212
|
-
posts: false,
|
|
213
|
-
comments: false,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
const loadResource = async (resource: keyof typeof loadingStates) => {
|
|
217
|
-
setLoadingStates(prev => ({ ...prev, [resource]: true }));
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
// Simulate different loading times
|
|
221
|
-
const delay = resource === 'user' ? 1000 : resource === 'posts' ? 2000 : 1500;
|
|
222
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
223
|
-
|
|
224
|
-
console.log(`${resource} loaded`);
|
|
225
|
-
} catch (error) {
|
|
226
|
-
console.error(`Failed to load ${resource}:`, error);
|
|
227
|
-
} finally {
|
|
228
|
-
setLoadingStates(prev => ({ ...prev, [resource]: false }));
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
return (
|
|
233
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
234
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
235
|
-
<button
|
|
236
|
-
onClick={() => loadResource('user')}
|
|
237
|
-
disabled={loadingStates.user}
|
|
238
|
-
>
|
|
239
|
-
Load User
|
|
240
|
-
</button>
|
|
241
|
-
{loadingStates.user && <Spinner size="small" color="#007bff" />}
|
|
242
|
-
</div>
|
|
243
|
-
|
|
244
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
245
|
-
<button
|
|
246
|
-
onClick={() => loadResource('posts')}
|
|
247
|
-
disabled={loadingStates.posts}
|
|
248
|
-
>
|
|
249
|
-
Load Posts
|
|
250
|
-
</button>
|
|
251
|
-
{loadingStates.posts && <Spinner size="small" color="#28a745" />}
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
255
|
-
<button
|
|
256
|
-
onClick={() => loadResource('comments')}
|
|
257
|
-
disabled={loadingStates.comments}
|
|
258
|
-
>
|
|
259
|
-
Load Comments
|
|
260
|
-
</button>
|
|
261
|
-
{loadingStates.comments && <Spinner size="small" color="#ffc107" />}
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Page loading spinner
|
|
268
|
-
function PageLoader() {
|
|
269
|
-
const [isPageLoading, setIsPageLoading] = useState(true);
|
|
270
|
-
|
|
271
|
-
useEffect(() => {
|
|
272
|
-
// Simulate page load
|
|
273
|
-
const timer = setTimeout(() => {
|
|
274
|
-
setIsPageLoading(false);
|
|
275
|
-
}, 2000);
|
|
276
|
-
|
|
277
|
-
return () => clearTimeout(timer);
|
|
278
|
-
}, []);
|
|
279
|
-
|
|
280
|
-
if (isPageLoading) {
|
|
281
|
-
return (
|
|
282
|
-
<div
|
|
283
|
-
style={{
|
|
284
|
-
position: 'fixed',
|
|
285
|
-
top: 0,
|
|
286
|
-
left: 0,
|
|
287
|
-
right: 0,
|
|
288
|
-
bottom: 0,
|
|
289
|
-
backgroundColor: 'white',
|
|
290
|
-
display: 'flex',
|
|
291
|
-
flexDirection: 'column',
|
|
292
|
-
alignItems: 'center',
|
|
293
|
-
justifyContent: 'center',
|
|
294
|
-
gap: '20px',
|
|
295
|
-
zIndex: 9999,
|
|
296
|
-
}}
|
|
297
|
-
>
|
|
298
|
-
<Spinner size="medium" color="#007bff" />
|
|
299
|
-
<h2 style={{ margin: 0, color: '#333' }}>Loading Application...</h2>
|
|
300
|
-
<p style={{ margin: 0, color: '#666' }}>Please wait while we set things up</p>
|
|
301
|
-
</div>
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return (
|
|
306
|
-
<div>
|
|
307
|
-
<h1>Welcome to the Application!</h1>
|
|
308
|
-
<p>The application has finished loading.</p>
|
|
309
|
-
</div>
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Inline loading states
|
|
314
|
-
function InlineLoading() {
|
|
315
|
-
const [sections, setSections] = useState({
|
|
316
|
-
header: { loading: false, loaded: false },
|
|
317
|
-
sidebar: { loading: false, loaded: false },
|
|
318
|
-
content: { loading: false, loaded: false },
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
const loadSection = async (sectionName: keyof typeof sections) => {
|
|
322
|
-
setSections(prev => ({
|
|
323
|
-
...prev,
|
|
324
|
-
[sectionName]: { loading: true, loaded: false }
|
|
325
|
-
}));
|
|
326
|
-
|
|
327
|
-
try {
|
|
328
|
-
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
329
|
-
|
|
330
|
-
setSections(prev => ({
|
|
331
|
-
...prev,
|
|
332
|
-
[sectionName]: { loading: false, loaded: true }
|
|
333
|
-
}));
|
|
334
|
-
} catch (error) {
|
|
335
|
-
setSections(prev => ({
|
|
336
|
-
...prev,
|
|
337
|
-
[sectionName]: { loading: false, loaded: false }
|
|
338
|
-
}));
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
const renderSection = (name: keyof typeof sections, title: string) => {
|
|
343
|
-
const section = sections[name];
|
|
344
|
-
|
|
345
|
-
return (
|
|
346
|
-
<div
|
|
347
|
-
style={{
|
|
348
|
-
padding: '20px',
|
|
349
|
-
border: '1px solid #ddd',
|
|
350
|
-
borderRadius: '4px',
|
|
351
|
-
minHeight: '100px',
|
|
352
|
-
display: 'flex',
|
|
353
|
-
flexDirection: 'column',
|
|
354
|
-
justifyContent: 'center',
|
|
355
|
-
alignItems: 'center',
|
|
356
|
-
}}
|
|
357
|
-
>
|
|
358
|
-
{!section.loaded && !section.loading && (
|
|
359
|
-
<button onClick={() => loadSection(name)}>
|
|
360
|
-
Load {title}
|
|
361
|
-
</button>
|
|
362
|
-
)}
|
|
363
|
-
|
|
364
|
-
{section.loading && (
|
|
365
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
366
|
-
<Spinner size="small" />
|
|
367
|
-
<span>Loading {title.toLowerCase()}...</span>
|
|
368
|
-
</div>
|
|
369
|
-
)}
|
|
370
|
-
|
|
371
|
-
{section.loaded && (
|
|
372
|
-
<div>
|
|
373
|
-
<h3>{title}</h3>
|
|
374
|
-
<p>{title} content has been loaded successfully!</p>
|
|
375
|
-
</div>
|
|
376
|
-
)}
|
|
377
|
-
</div>
|
|
378
|
-
);
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
return (
|
|
382
|
-
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '16px' }}>
|
|
383
|
-
{renderSection('header', 'Header')}
|
|
384
|
-
{renderSection('sidebar', 'Sidebar')}
|
|
385
|
-
{renderSection('content', 'Content')}
|
|
386
|
-
<div style={{ gridColumn: '1 / -1' }}>
|
|
387
|
-
<button
|
|
388
|
-
onClick={() => {
|
|
389
|
-
Object.keys(sections).forEach(section => {
|
|
390
|
-
loadSection(section as keyof typeof sections);
|
|
391
|
-
});
|
|
392
|
-
}}
|
|
393
|
-
style={{
|
|
394
|
-
padding: '12px 24px',
|
|
395
|
-
backgroundColor: '#28a745',
|
|
396
|
-
color: 'white',
|
|
397
|
-
border: 'none',
|
|
398
|
-
borderRadius: '4px',
|
|
399
|
-
cursor: 'pointer',
|
|
400
|
-
}}
|
|
401
|
-
>
|
|
402
|
-
Load All Sections
|
|
403
|
-
</button>
|
|
404
|
-
</div>
|
|
405
|
-
</div>
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// Search with debounced loading
|
|
410
|
-
function SearchWithSpinner() {
|
|
411
|
-
const [query, setQuery] = useState('');
|
|
412
|
-
const [results, setResults] = useState([]);
|
|
413
|
-
const [isSearching, setIsSearching] = useState(false);
|
|
414
|
-
const [debouncedQuery, setDebouncedQuery] = useState('');
|
|
415
|
-
|
|
416
|
-
// Debounce the search query
|
|
417
|
-
useEffect(() => {
|
|
418
|
-
const timer = setTimeout(() => {
|
|
419
|
-
setDebouncedQuery(query);
|
|
420
|
-
}, 500);
|
|
421
|
-
|
|
422
|
-
return () => clearTimeout(timer);
|
|
423
|
-
}, [query]);
|
|
424
|
-
|
|
425
|
-
// Perform search when debounced query changes
|
|
426
|
-
useEffect(() => {
|
|
427
|
-
if (debouncedQuery) {
|
|
428
|
-
performSearch(debouncedQuery);
|
|
429
|
-
} else {
|
|
430
|
-
setResults([]);
|
|
431
|
-
}
|
|
432
|
-
}, [debouncedQuery]);
|
|
433
|
-
|
|
434
|
-
const performSearch = async (searchQuery: string) => {
|
|
435
|
-
setIsSearching(true);
|
|
436
|
-
|
|
437
|
-
try {
|
|
438
|
-
// Simulate search API call
|
|
439
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
440
|
-
|
|
441
|
-
// Mock results
|
|
442
|
-
const mockResults = [
|
|
443
|
-
`Result 1 for "${searchQuery}"`,
|
|
444
|
-
`Result 2 for "${searchQuery}"`,
|
|
445
|
-
`Result 3 for "${searchQuery}"`,
|
|
446
|
-
];
|
|
447
|
-
|
|
448
|
-
setResults(mockResults);
|
|
449
|
-
} catch (error) {
|
|
450
|
-
console.error('Search failed:', error);
|
|
451
|
-
setResults([]);
|
|
452
|
-
} finally {
|
|
453
|
-
setIsSearching(false);
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
return (
|
|
458
|
-
<div>
|
|
459
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '16px' }}>
|
|
460
|
-
<input
|
|
461
|
-
type="text"
|
|
462
|
-
placeholder="Search..."
|
|
463
|
-
value={query}
|
|
464
|
-
onChange={(e) => setQuery(e.target.value)}
|
|
465
|
-
style={{
|
|
466
|
-
padding: '8px 12px',
|
|
467
|
-
border: '1px solid #ddd',
|
|
468
|
-
borderRadius: '4px',
|
|
469
|
-
flex: 1,
|
|
470
|
-
}}
|
|
471
|
-
/>
|
|
472
|
-
{isSearching && <Spinner size="small" color="#007bff" />}
|
|
473
|
-
</div>
|
|
474
|
-
|
|
475
|
-
<div>
|
|
476
|
-
{results.length > 0 ? (
|
|
477
|
-
<div>
|
|
478
|
-
<h4>Search Results:</h4>
|
|
479
|
-
<ul>
|
|
480
|
-
{results.map((result, index) => (
|
|
481
|
-
<li key={index}>{result}</li>
|
|
482
|
-
))}
|
|
483
|
-
</ul>
|
|
484
|
-
</div>
|
|
485
|
-
) : query && !isSearching ? (
|
|
486
|
-
<p>No results found for "{query}"</p>
|
|
487
|
-
) : null}
|
|
488
|
-
</div>
|
|
489
|
-
</div>
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
## Props Reference
|
|
495
|
-
|
|
496
|
-
| Prop | Type | Default | Required | Description |
|
|
497
|
-
|------|------|---------|----------|-------------|
|
|
498
|
-
| `boxRef` | `Ref<HTMLDivElement>` | `undefined` | No | Ref for the spinner container element |
|
|
499
|
-
| `color` | `string` | `undefined` | No | Custom color for the spinner |
|
|
500
|
-
| `size` | `'small' \| 'medium'` | - | Yes | Size variant of the spinner |
|
|
501
|
-
|
|
502
|
-
## AI Agent Guidelines
|
|
503
|
-
|
|
504
|
-
### Recommended Patterns
|
|
505
|
-
|
|
506
|
-
1. **Size Selection**: Choose appropriate size for context
|
|
507
|
-
```typescript
|
|
508
|
-
// Small for inline elements
|
|
509
|
-
<Button disabled={loading}>
|
|
510
|
-
{loading && <Spinner size="small" />}
|
|
511
|
-
Submit
|
|
512
|
-
</Button>
|
|
513
|
-
|
|
514
|
-
// Medium for standalone loading states
|
|
515
|
-
<div>
|
|
516
|
-
<Spinner size="medium" />
|
|
517
|
-
<p>Loading content...</p>
|
|
518
|
-
</div>
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
2. **Color Consistency**: Match spinner colors to your theme
|
|
522
|
-
```typescript
|
|
523
|
-
// Match brand colors
|
|
524
|
-
<Spinner size="medium" color="#007bff" /> // Primary
|
|
525
|
-
<Spinner size="medium" color="#28a745" /> // Success
|
|
526
|
-
<Spinner size="medium" color="#dc3545" /> // Error
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
3. **Conditional Rendering**: Only show when actually loading
|
|
530
|
-
```typescript
|
|
531
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
532
|
-
|
|
533
|
-
// Good - conditional rendering
|
|
534
|
-
{isLoading && <Spinner size="medium" />}
|
|
535
|
-
|
|
536
|
-
// Avoid - always rendered
|
|
537
|
-
<Spinner size="medium" style={{ display: isLoading ? 'block' : 'none' }} />
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### Common Mistakes to Avoid
|
|
541
|
-
|
|
542
|
-
1. **Missing Size Prop**: Always provide the required `size` prop
|
|
543
|
-
2. **Performance Issues**: Don't render multiple spinners unnecessarily
|
|
544
|
-
3. **Accessibility**: Provide appropriate ARIA labels for screen readers
|
|
545
|
-
4. **Overlapping Spinners**: Avoid multiple spinners in the same area
|
|
546
|
-
5. **Infinite Loading**: Always have a timeout or error handling for loading states
|
|
547
|
-
|
|
548
|
-
### Integration Tips
|
|
549
|
-
|
|
550
|
-
1. **Loading States**: Use with React state management
|
|
551
|
-
```typescript
|
|
552
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
553
|
-
|
|
554
|
-
const handleAction = async () => {
|
|
555
|
-
setIsLoading(true);
|
|
556
|
-
try {
|
|
557
|
-
await performAction();
|
|
558
|
-
} finally {
|
|
559
|
-
setIsLoading(false);
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
2. **Button Integration**: Common pattern for loading buttons
|
|
565
|
-
```typescript
|
|
566
|
-
<button disabled={isLoading}>
|
|
567
|
-
{isLoading && <Spinner size="small" color="white" />}
|
|
568
|
-
{isLoading ? 'Loading...' : 'Click Me'}
|
|
569
|
-
</button>
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
3. **Overlay Pattern**: For loading overlays
|
|
573
|
-
```typescript
|
|
574
|
-
{isLoading && (
|
|
575
|
-
<div style={{
|
|
576
|
-
position: 'absolute',
|
|
577
|
-
top: 0,
|
|
578
|
-
left: 0,
|
|
579
|
-
right: 0,
|
|
580
|
-
bottom: 0,
|
|
581
|
-
display: 'flex',
|
|
582
|
-
alignItems: 'center',
|
|
583
|
-
justifyContent: 'center',
|
|
584
|
-
backgroundColor: 'rgba(255,255,255,0.8)'
|
|
585
|
-
}}>
|
|
586
|
-
<Spinner size="medium" />
|
|
587
|
-
</div>
|
|
588
|
-
)}
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
4. **Accessibility**: Include proper ARIA labels
|
|
592
|
-
```typescript
|
|
593
|
-
<div role="status" aria-live="polite">
|
|
594
|
-
<Spinner size="medium" />
|
|
595
|
-
<span className="sr-only">Loading...</span>
|
|
596
|
-
</div>
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
5. **Performance**: Use React.memo for components with spinners to prevent unnecessary re-renders
|
|
600
|
-
|
|
601
|
-
## Related Components
|
|
602
|
-
|
|
603
|
-
- **Button**: Often used together for loading button states
|
|
604
|
-
- **ProgressBar**: Alternative for progress indication
|
|
605
|
-
- **Modal**: For loading dialogs
|
|
606
|
-
- **Skeleton**: Alternative loading pattern for content placeholders
|
|
607
|
-
- **Alert**: For loading completion notifications
|