@lerx/promise-modal 0.10.4 → 0.11.0

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.
@@ -0,0 +1,207 @@
1
+ # Hooks Reference
2
+
3
+ ## useModal
4
+
5
+ Returns modal handlers tied to component lifecycle.
6
+
7
+ ```typescript
8
+ import { useModal } from '@lerx/promise-modal';
9
+
10
+ function MyComponent() {
11
+ const modal = useModal({
12
+ ForegroundComponent: CustomForeground, // Hook-level config
13
+ });
14
+
15
+ const handleShow = async () => {
16
+ await modal.alert({ title: 'Alert', content: 'Hello!' });
17
+ };
18
+
19
+ return <button onClick={handleShow}>Open Modal</button>;
20
+ }
21
+ ```
22
+
23
+ **Key Feature**: Modals are automatically cleaned up when component unmounts.
24
+
25
+ | Feature | Static Handlers | useModal Hook |
26
+ |------|------------|-------------|
27
+ | Lifecycle | Independent | Tied to component |
28
+ | Cleanup | Manual | Auto on unmount |
29
+ | Usage Location | Anywhere | Inside React components |
30
+
31
+ ---
32
+
33
+ ## useActiveModalCount
34
+
35
+ Returns the count of currently active modals.
36
+
37
+ ```typescript
38
+ import { useActiveModalCount } from '@lerx/promise-modal';
39
+
40
+ function App() {
41
+ const count = useActiveModalCount();
42
+ // Optional: Filter with condition
43
+ const alertCount = useActiveModalCount(
44
+ (modal) => modal?.type === 'alert' && modal.visible
45
+ );
46
+
47
+ return <div>Open modals: {count}</div>;
48
+ }
49
+ ```
50
+
51
+ **Parameters**:
52
+ - `filter?: (modal: ModalNode) => boolean` - Optional filter function
53
+
54
+ **Returns**: `number` - Active modal count
55
+
56
+ ---
57
+
58
+ ## useModalAnimation
59
+
60
+ Provides animation state callbacks.
61
+
62
+ ```typescript
63
+ import { useModalAnimation } from '@lerx/promise-modal';
64
+
65
+ function CustomForeground({ visible, children }) {
66
+ const ref = useRef(null);
67
+
68
+ useModalAnimation(visible, {
69
+ onVisible: () => ref.current?.classList.add('visible'),
70
+ onHidden: () => ref.current?.classList.remove('visible'),
71
+ });
72
+
73
+ return <div ref={ref}>{children}</div>;
74
+ }
75
+ ```
76
+
77
+ **Parameters**:
78
+ - `visible: boolean` - Modal visibility state
79
+ - `callbacks: { onVisible?: () => void; onHidden?: () => void }` - State change callbacks
80
+
81
+ **Timing**:
82
+ - `onVisible`: When modal starts becoming visible
83
+ - `onHidden`: When modal starts becoming hidden
84
+
85
+ ---
86
+
87
+ ## useModalDuration
88
+
89
+ Returns modal animation duration.
90
+
91
+ ```typescript
92
+ import { useModalDuration } from '@lerx/promise-modal';
93
+
94
+ function Component() {
95
+ const { duration, milliseconds } = useModalDuration();
96
+ // duration: '300ms', milliseconds: 300
97
+
98
+ return <div>Animation duration: {duration}</div>;
99
+ }
100
+ ```
101
+
102
+ **Returns**:
103
+ ```typescript
104
+ {
105
+ duration: string; // CSS format (e.g., '300ms')
106
+ milliseconds: number; // Number format (e.g., 300)
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## useDestroyAfter
113
+
114
+ Automatically destroys modal after specified time.
115
+
116
+ ```typescript
117
+ import { useDestroyAfter } from '@lerx/promise-modal';
118
+
119
+ function ToastComponent({ id, duration }) {
120
+ useDestroyAfter(id, duration);
121
+ return <div>Toast message</div>;
122
+ }
123
+ ```
124
+
125
+ **Parameters**:
126
+ - `id: number` - Modal ID
127
+ - `duration: number | string` - Wait time before destruction
128
+
129
+ **Use Case**: Auto-removal in toast notification implementation
130
+
131
+ ---
132
+
133
+ ## useSubscribeModal
134
+
135
+ Subscribes to modal state changes.
136
+
137
+ ```typescript
138
+ import { useSubscribeModal } from '@lerx/promise-modal';
139
+
140
+ function ModalTracker({ modal }) {
141
+ const version = useSubscribeModal(modal);
142
+
143
+ useEffect(() => {
144
+ console.log('Modal state changed');
145
+ }, [version]);
146
+
147
+ return <div>Version: {version}</div>;
148
+ }
149
+ ```
150
+
151
+ **Parameters**:
152
+ - `modal: ModalNode` - Modal node to subscribe to
153
+
154
+ **Returns**: `number` - Modal version (increments on state change)
155
+
156
+ **Purpose**: React to modal internal state changes
157
+
158
+ ---
159
+
160
+ ## useModalOptions
161
+
162
+ Returns modal option configuration.
163
+
164
+ ```typescript
165
+ import { useModalOptions } from '@lerx/promise-modal';
166
+
167
+ function ModalDebugInfo() {
168
+ const options = useModalOptions();
169
+
170
+ return (
171
+ <div>
172
+ <p>Duration: {options.duration}</p>
173
+ <p>Backdrop: {options.backdrop}</p>
174
+ <p>Manual Destroy: {options.manualDestroy ? 'Yes' : 'No'}</p>
175
+ </div>
176
+ );
177
+ }
178
+ ```
179
+
180
+ **Returns**: `ModalOptions` - Current modal's options object
181
+
182
+ **Included Properties**:
183
+ - `duration` - Animation duration
184
+ - `backdrop` - Background configuration
185
+ - `manualDestroy` - Manual destruction mode
186
+ - `closeOnBackdropClick` - Close on backdrop click
187
+ - Other modal configuration options
188
+
189
+ ---
190
+
191
+ ## useModalBackdrop
192
+
193
+ Returns only modal background configuration.
194
+
195
+ ```typescript
196
+ import { useModalBackdrop } from '@lerx/promise-modal';
197
+
198
+ function BackdropInfo() {
199
+ const backdrop = useModalBackdrop();
200
+
201
+ return <p>Current backdrop: {backdrop}</p>;
202
+ }
203
+ ```
204
+
205
+ **Returns**: `ModalBackground` - Background configuration value
206
+
207
+ **Purpose**: Lighter alternative to `useModalOptions` when only backdrop configuration is needed
@@ -0,0 +1,172 @@
1
+ # Type Definitions
2
+
3
+ ## ModalFrameProps
4
+
5
+ Props passed to Foreground/Background components.
6
+
7
+ ```typescript
8
+ interface ModalFrameProps<Context = any, B = any> {
9
+ id: number;
10
+ type: 'alert' | 'confirm' | 'prompt';
11
+ alive: boolean;
12
+ visible: boolean;
13
+ initiator: string;
14
+ manualDestroy: boolean;
15
+ closeOnBackdropClick: boolean;
16
+ background?: ModalBackground<B>;
17
+ onConfirm: () => void;
18
+ onClose: () => void;
19
+ onChange: (value: any) => void;
20
+ onDestroy: () => void;
21
+ onChangeOrder: Function;
22
+ context: Context;
23
+ children: ReactNode;
24
+ }
25
+ ```
26
+
27
+ **Property Descriptions**:
28
+
29
+ | Property | Type | Description |
30
+ |------|------|------|
31
+ | `id` | `number` | Unique modal ID |
32
+ | `type` | `'alert' \| 'confirm' \| 'prompt'` | Modal type |
33
+ | `alive` | `boolean` | Whether modal exists in DOM |
34
+ | `visible` | `boolean` | Whether modal is visible on screen |
35
+ | `initiator` | `string` | Identifier of modal creator |
36
+ | `manualDestroy` | `boolean` | Whether manual destruction mode is enabled |
37
+ | `closeOnBackdropClick` | `boolean` | Whether close on backdrop click is enabled |
38
+ | `background` | `ModalBackground<B>` | Background configuration |
39
+ | `onConfirm` | `() => void` | Confirm button click handler |
40
+ | `onClose` | `() => void` | Modal close handler |
41
+ | `onChange` | `(value: any) => void` | Value change handler (for prompt) |
42
+ | `onDestroy` | `() => void` | Modal destruction handler |
43
+ | `onChangeOrder` | `Function` | Modal order change handler |
44
+ | `context` | `Context` | User-defined context data |
45
+ | `children` | `ReactNode` | Modal internal content |
46
+
47
+ ---
48
+
49
+ ## FooterComponentProps
50
+
51
+ Props for custom footer components.
52
+
53
+ ```typescript
54
+ interface FooterComponentProps {
55
+ type: 'alert' | 'confirm' | 'prompt';
56
+ onConfirm: (value?: any) => void;
57
+ onClose: () => void;
58
+ onCancel?: () => void;
59
+ disabled?: boolean;
60
+ footer?: FooterOptions;
61
+ context: any;
62
+ }
63
+ ```
64
+
65
+ **Property Descriptions**:
66
+
67
+ | Property | Type | Description |
68
+ |------|------|------|
69
+ | `type` | `'alert' \| 'confirm' \| 'prompt'` | Modal type |
70
+ | `onConfirm` | `(value?: any) => void` | Confirm button click handler |
71
+ | `onClose` | `() => void` | Close button click handler |
72
+ | `onCancel` | `() => void` | Cancel button click handler (optional) |
73
+ | `disabled` | `boolean` | Confirm button disabled state (optional) |
74
+ | `footer` | `FooterOptions` | Footer configuration options (optional) |
75
+ | `context` | `any` | User-defined context data |
76
+
77
+ **Usage Example**:
78
+
79
+ ```typescript
80
+ const CustomFooter: React.FC<FooterComponentProps> = ({
81
+ type,
82
+ onConfirm,
83
+ onClose,
84
+ disabled,
85
+ footer,
86
+ }) => {
87
+ return (
88
+ <div className="custom-footer">
89
+ {type !== 'alert' && (
90
+ <button onClick={onClose}>
91
+ {footer?.cancel || 'Cancel'}
92
+ </button>
93
+ )}
94
+ <button onClick={() => onConfirm()} disabled={disabled}>
95
+ {footer?.confirm || 'Confirm'}
96
+ </button>
97
+ </div>
98
+ );
99
+ };
100
+ ```
101
+
102
+ ---
103
+
104
+ ## PromptInputProps<T>
105
+
106
+ Props for prompt input components.
107
+
108
+ ```typescript
109
+ interface PromptInputProps<T> {
110
+ value?: T;
111
+ defaultValue?: T;
112
+ onChange: (value: T | undefined) => void;
113
+ onConfirm: () => void;
114
+ onCancel: () => void;
115
+ context: any;
116
+ }
117
+ ```
118
+
119
+ **Property Descriptions**:
120
+
121
+ | Property | Type | Description |
122
+ |------|------|------|
123
+ | `value` | `T` | Current input value (optional) |
124
+ | `defaultValue` | `T` | Default input value (optional) |
125
+ | `onChange` | `(value: T \| undefined) => void` | Value change handler |
126
+ | `onConfirm` | `() => void` | Confirm action handler (e.g., Enter key) |
127
+ | `onCancel` | `() => void` | Cancel action handler (e.g., Escape key) |
128
+ | `context` | `any` | User-defined context data |
129
+
130
+ **Usage Examples**:
131
+
132
+ ```typescript
133
+ // Simple text input
134
+ const TextInput: React.FC<PromptInputProps<string>> = ({
135
+ value = '',
136
+ onChange,
137
+ onConfirm,
138
+ }) => {
139
+ return (
140
+ <input
141
+ type="text"
142
+ value={value}
143
+ onChange={(e) => onChange(e.target.value)}
144
+ onKeyPress={(e) => e.key === 'Enter' && onConfirm()}
145
+ />
146
+ );
147
+ };
148
+
149
+ // Complex object input
150
+ interface FormData {
151
+ name: string;
152
+ email: string;
153
+ }
154
+
155
+ const FormInput: React.FC<PromptInputProps<FormData>> = ({
156
+ value = { name: '', email: '' },
157
+ onChange,
158
+ }) => {
159
+ return (
160
+ <div>
161
+ <input
162
+ value={value.name}
163
+ onChange={(e) => onChange({ ...value, name: e.target.value })}
164
+ />
165
+ <input
166
+ value={value.email}
167
+ onChange={(e) => onChange({ ...value, email: e.target.value })}
168
+ />
169
+ </div>
170
+ );
171
+ };
172
+ ```