@lerx/promise-modal 0.2.8 → 0.2.9

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.
@@ -3,5 +3,217 @@ interface ModalAnimationHandler {
3
3
  onVisible?: Fn;
4
4
  onHidden?: Fn;
5
5
  }
6
+ /**
7
+ * Hook that triggers animation callbacks based on modal visibility changes.
8
+ *
9
+ * Uses requestAnimationFrame to ensure callbacks are executed at the optimal time
10
+ * for animations. Callbacks are triggered on the next frame after visibility changes,
11
+ * allowing for smooth CSS transitions and JavaScript animations.
12
+ *
13
+ * @param visible - Current visibility state of the modal
14
+ * @param handler - Object containing onVisible and onHidden callbacks
15
+ *
16
+ * @example
17
+ * Basic fade animation:
18
+ * ```tsx
19
+ * function FadeModal({ visible }) {
20
+ * const modalRef = useRef<HTMLDivElement>(null);
21
+ *
22
+ * useModalAnimation(visible, {
23
+ * onVisible: () => {
24
+ * if (modalRef.current) {
25
+ * modalRef.current.style.opacity = '0';
26
+ * modalRef.current.style.transform = 'scale(0.9)';
27
+ *
28
+ * requestAnimationFrame(() => {
29
+ * modalRef.current.style.opacity = '1';
30
+ * modalRef.current.style.transform = 'scale(1)';
31
+ * });
32
+ * }
33
+ * },
34
+ * onHidden: () => {
35
+ * if (modalRef.current) {
36
+ * modalRef.current.style.opacity = '0';
37
+ * modalRef.current.style.transform = 'scale(0.9)';
38
+ * }
39
+ * },
40
+ * });
41
+ *
42
+ * return (
43
+ * <div
44
+ * ref={modalRef}
45
+ * style={{
46
+ * transition: 'all 300ms ease',
47
+ * opacity: 0,
48
+ * }}
49
+ * >
50
+ * Modal Content
51
+ * </div>
52
+ * );
53
+ * }
54
+ * ```
55
+ *
56
+ * @example
57
+ * Slide animation with dynamic direction:
58
+ * ```tsx
59
+ * function SlideModal({ visible, direction = 'bottom' }) {
60
+ * const modalRef = useRef<HTMLDivElement>(null);
61
+ *
62
+ * const getTransform = (hidden: boolean) => {
63
+ * if (!hidden) return 'translate(0, 0)';
64
+ *
65
+ * switch (direction) {
66
+ * case 'top': return 'translate(0, -100%)';
67
+ * case 'bottom': return 'translate(0, 100%)';
68
+ * case 'left': return 'translate(-100%, 0)';
69
+ * case 'right': return 'translate(100%, 0)';
70
+ * }
71
+ * };
72
+ *
73
+ * useModalAnimation(visible, {
74
+ * onVisible: () => {
75
+ * if (modalRef.current) {
76
+ * modalRef.current.style.transform = getTransform(false);
77
+ * }
78
+ * },
79
+ * onHidden: () => {
80
+ * if (modalRef.current) {
81
+ * modalRef.current.style.transform = getTransform(true);
82
+ * }
83
+ * },
84
+ * });
85
+ *
86
+ * return (
87
+ * <div
88
+ * ref={modalRef}
89
+ * style={{
90
+ * transition: 'transform 400ms cubic-bezier(0.4, 0, 0.2, 1)',
91
+ * transform: getTransform(true),
92
+ * }}
93
+ * >
94
+ * // Content
95
+ * </div>
96
+ * );
97
+ * }
98
+ * ```
99
+ *
100
+ * @example
101
+ * Complex animation sequence:
102
+ * ```tsx
103
+ * function SequenceModal({ visible }) {
104
+ * const overlayRef = useRef<HTMLDivElement>(null);
105
+ * const contentRef = useRef<HTMLDivElement>(null);
106
+ *
107
+ * useModalAnimation(visible, {
108
+ * onVisible: () => {
109
+ * // Animate overlay first
110
+ * if (overlayRef.current) {
111
+ * overlayRef.current.style.opacity = '0';
112
+ * requestAnimationFrame(() => {
113
+ * overlayRef.current.style.opacity = '1';
114
+ * });
115
+ * }
116
+ *
117
+ * // Then animate content with delay
118
+ * setTimeout(() => {
119
+ * if (contentRef.current) {
120
+ * contentRef.current.style.transform = 'scale(0.8)';
121
+ * contentRef.current.style.opacity = '0';
122
+ *
123
+ * requestAnimationFrame(() => {
124
+ * contentRef.current.style.transform = 'scale(1)';
125
+ * contentRef.current.style.opacity = '1';
126
+ * });
127
+ * }
128
+ * }, 150);
129
+ * },
130
+ * onHidden: () => {
131
+ * // Reverse animation
132
+ * if (contentRef.current) {
133
+ * contentRef.current.style.transform = 'scale(0.8)';
134
+ * contentRef.current.style.opacity = '0';
135
+ * }
136
+ *
137
+ * setTimeout(() => {
138
+ * if (overlayRef.current) {
139
+ * overlayRef.current.style.opacity = '0';
140
+ * }
141
+ * }, 150);
142
+ * },
143
+ * });
144
+ *
145
+ * return (
146
+ * <>
147
+ * <div
148
+ * ref={overlayRef}
149
+ * className="modal-overlay"
150
+ * style={{ transition: 'opacity 300ms' }}
151
+ * />
152
+ * <div
153
+ * ref={contentRef}
154
+ * className="modal-content"
155
+ * style={{ transition: 'all 300ms ease' }}
156
+ * >
157
+ * // Content
158
+ * </div>
159
+ * </>
160
+ * );
161
+ * }
162
+ * ```
163
+ *
164
+ * @example
165
+ * With class-based animations:
166
+ * ```tsx
167
+ * function ClassAnimatedModal({ visible }) {
168
+ * const [animationClass, setAnimationClass] = useState('');
169
+ *
170
+ * useModalAnimation(visible, {
171
+ * onVisible: () => setAnimationClass('modal-enter'),
172
+ * onHidden: () => setAnimationClass('modal-exit'),
173
+ * });
174
+ *
175
+ * return (
176
+ * <div className={`modal ${animationClass}`}>
177
+ * // Content
178
+ * </div>
179
+ * );
180
+ * }
181
+ * ```
182
+ *
183
+ * @example
184
+ * Integrating with animation libraries:
185
+ * ```tsx
186
+ * function SpringModal({ visible }) {
187
+ * const springRef = useRef<SpringRef>(null);
188
+ *
189
+ * useModalAnimation(visible, {
190
+ * onVisible: () => {
191
+ * springRef.current?.start({
192
+ * from: { opacity: 0, scale: 0.8 },
193
+ * to: { opacity: 1, scale: 1 },
194
+ * });
195
+ * },
196
+ * onHidden: () => {
197
+ * springRef.current?.start({
198
+ * to: { opacity: 0, scale: 0.8 },
199
+ * });
200
+ * },
201
+ * });
202
+ *
203
+ * return (
204
+ * <animated.div ref={springRef}>
205
+ * // Content
206
+ * </animated.div>
207
+ * );
208
+ * }
209
+ * ```
210
+ *
211
+ * @remarks
212
+ * - Uses useLayoutEffect to ensure DOM updates before animations
213
+ * - Callbacks are wrapped in requestAnimationFrame for optimal timing
214
+ * - Handler reference is kept fresh without causing re-renders
215
+ * - Automatically cancels pending animation frames on cleanup
216
+ * - Perfect for coordinating CSS transitions and JS animations
217
+ */
6
218
  export declare const useModalAnimation: (visible: boolean, handler: ModalAnimationHandler) => void;
7
219
  export {};
@@ -1,2 +1,116 @@
1
1
  import type { ModalNode } from '../core';
2
+ /**
3
+ * Hook that subscribes to modal state changes and triggers re-renders.
4
+ *
5
+ * Listens to any changes in the modal node (visibility, alive state, content, etc.)
6
+ * and returns a version number that increments on each change. This allows components
7
+ * to react to modal state changes without directly accessing the modal state.
8
+ *
9
+ * @param modal - The modal node to subscribe to
10
+ * @returns Version number that increments on each modal state change
11
+ *
12
+ * @example
13
+ * Basic usage to react to modal changes:
14
+ * ```tsx
15
+ * function ModalContent({ modalId }) {
16
+ * const { modal } = useModal(modalId);
17
+ * const version = useSubscribeModal(modal);
18
+ *
19
+ * // Component re-renders whenever modal state changes
20
+ * return (
21
+ * <div>
22
+ * <p>Modal is {modal?.visible ? 'visible' : 'hidden'}</p>
23
+ * <p>Update count: {version}</p>
24
+ * </div>
25
+ * );
26
+ * }
27
+ * ```
28
+ *
29
+ * @example
30
+ * Triggering side effects on modal state changes:
31
+ * ```tsx
32
+ * function ModalLogger({ modalId }) {
33
+ * const { modal } = useModal(modalId);
34
+ * const version = useSubscribeModal(modal);
35
+ *
36
+ * useEffect(() => {
37
+ * if (version === 0) return; // Skip initial render
38
+ *
39
+ * console.log('Modal state changed:', {
40
+ * visible: modal?.visible,
41
+ * alive: modal?.alive,
42
+ * type: modal?.type,
43
+ * });
44
+ * }, [version, modal]);
45
+ *
46
+ * return null;
47
+ * }
48
+ * ```
49
+ *
50
+ * @example
51
+ * Conditional rendering based on modal state:
52
+ * ```tsx
53
+ * function ModalAnimation({ modalId, children }) {
54
+ * const { modal } = useModal(modalId);
55
+ * const version = useSubscribeModal(modal);
56
+ * const [shouldRender, setShouldRender] = useState(false);
57
+ *
58
+ * useEffect(() => {
59
+ * if (modal?.visible) {
60
+ * setShouldRender(true);
61
+ * } else if (!modal?.alive) {
62
+ * // Delay unmount for exit animation
63
+ * setTimeout(() => setShouldRender(false), 300);
64
+ * }
65
+ * }, [version, modal]);
66
+ *
67
+ * if (!shouldRender) return null;
68
+ *
69
+ * return (
70
+ * <div className={modal?.visible ? 'fade-in' : 'fade-out'}>
71
+ * {children}
72
+ * </div>
73
+ * );
74
+ * }
75
+ * ```
76
+ *
77
+ * @example
78
+ * Tracking specific modal properties:
79
+ * ```tsx
80
+ * function ModalProgressTracker({ modalId }) {
81
+ * const { modal } = useModal(modalId);
82
+ * const version = useSubscribeModal(modal);
83
+ * const [history, setHistory] = useState([]);
84
+ *
85
+ * useEffect(() => {
86
+ * if (!modal) return;
87
+ *
88
+ * setHistory(prev => [...prev, {
89
+ * timestamp: Date.now(),
90
+ * visible: modal.visible,
91
+ * value: modal.value,
92
+ * }]);
93
+ * }, [version]); // Only depend on version, not modal
94
+ *
95
+ * return (
96
+ * <div>
97
+ * <h4>Modal State History</h4>
98
+ * {history.map((entry, i) => (
99
+ * <div key={i}>
100
+ * {new Date(entry.timestamp).toLocaleTimeString()}:
101
+ * {entry.visible ? 'Shown' : 'Hidden'}
102
+ * (value: {JSON.stringify(entry.value)})
103
+ * </div>
104
+ * ))}
105
+ * </div>
106
+ * );
107
+ * }
108
+ * ```
109
+ *
110
+ * @remarks
111
+ * - Returns 0 on initial render, increments on each change
112
+ * - Automatically unsubscribes when component unmounts or modal changes
113
+ * - More efficient than directly depending on modal object in useEffect
114
+ * - Use this when you need to react to any modal state change
115
+ */
2
116
  export declare const useSubscribeModal: (modal?: ModalNode) => number;
package/dist/index.cjs CHANGED
@@ -426,7 +426,7 @@ const DEFAULT_OPTIONS = {
426
426
  manualDestroy: false,
427
427
  };
428
428
  const ConfigurationContextProvider = react.memo(({ ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options: inputOptions, children, }) => {
429
- const memoized = hook.useMemorize({
429
+ const constant = hook.useConstant({
430
430
  BackgroundComponent,
431
431
  ForegroundComponent: ForegroundComponent || FallbackForegroundFrame,
432
432
  TitleComponent: TitleComponent || FallbackTitle,
@@ -436,17 +436,17 @@ const ConfigurationContextProvider = react.memo(({ ForegroundComponent, Backgrou
436
436
  });
437
437
  const options = hook.useSnapshot(inputOptions);
438
438
  const value = react.useMemo(() => ({
439
- ForegroundComponent: memoized.ForegroundComponent,
440
- BackgroundComponent: memoized.BackgroundComponent,
441
- TitleComponent: memoized.TitleComponent,
442
- SubtitleComponent: memoized.SubtitleComponent,
443
- ContentComponent: memoized.ContentComponent,
444
- FooterComponent: memoized.FooterComponent,
439
+ ForegroundComponent: constant.ForegroundComponent,
440
+ BackgroundComponent: constant.BackgroundComponent,
441
+ TitleComponent: constant.TitleComponent,
442
+ SubtitleComponent: constant.SubtitleComponent,
443
+ ContentComponent: constant.ContentComponent,
444
+ FooterComponent: constant.FooterComponent,
445
445
  options: {
446
446
  ...DEFAULT_OPTIONS,
447
447
  ...options,
448
448
  },
449
- }), [memoized, options]);
449
+ }), [constant, options]);
450
450
  return (jsxRuntime.jsx(ConfigurationContext.Provider, { value: value, children: children }));
451
451
  });
452
452
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { useConfigurationOptions as useModalOptions, useConfigurationDuration as useModalDuration, useConfigurationBackdrop as useModalBackdrop, } from './providers';
2
2
  export { useBootstrap as useInitializeModal, BootstrapProvider as ModalProvider, type BootstrapProviderHandle as ModalProviderHandle, type BootstrapProviderProps as ModalProviderProps, } from './bootstrap';
3
- export { useSubscribeModal } from './hooks/useSubscribeModal';
4
- export { useDestroyAfter } from './hooks/useDestroyAfter';
5
3
  export { useActiveModalCount } from './hooks/useActiveModalCount';
4
+ export { useDestroyAfter } from './hooks/useDestroyAfter';
6
5
  export { useModalAnimation } from './hooks/useModalAnimation';
6
+ export { useSubscribeModal } from './hooks/useSubscribeModal';
7
7
  export { alert, confirm, prompt } from './core';
8
8
  export type { ModalOptions, ModalFrameProps, FooterComponentProps, ModalBackground, PromptInputProps, AlertContentProps, ConfirmContentProps, PromptContentProps, WrapperComponentProps, } from './types';
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { createContext, useContext, useMemo, forwardRef, memo, useRef, useState, useLayoutEffect, useCallback, Fragment, useEffect, useImperativeHandle } from 'react';
3
3
  import { convertMsFromDuration } from '@winglet/common-utils/convert';
4
- import { useMemorize, useSnapshot, useReference, useOnMountLayout, useHandle, useVersion, useOnMount } from '@winglet/react-utils/hook';
4
+ import { useConstant, useSnapshot, useReference, useOnMountLayout, useHandle, useVersion, useOnMount } from '@winglet/react-utils/hook';
5
5
  import { polynomialHash } from '@winglet/common-utils/hash';
6
6
  import { getRandomString, counterFactory } from '@winglet/common-utils/lib';
7
7
  import { styleManagerFactory, destroyScope } from '@winglet/style-utils/style-manager';
@@ -424,7 +424,7 @@ const DEFAULT_OPTIONS = {
424
424
  manualDestroy: false,
425
425
  };
426
426
  const ConfigurationContextProvider = memo(({ ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options: inputOptions, children, }) => {
427
- const memoized = useMemorize({
427
+ const constant = useConstant({
428
428
  BackgroundComponent,
429
429
  ForegroundComponent: ForegroundComponent || FallbackForegroundFrame,
430
430
  TitleComponent: TitleComponent || FallbackTitle,
@@ -434,17 +434,17 @@ const ConfigurationContextProvider = memo(({ ForegroundComponent, BackgroundComp
434
434
  });
435
435
  const options = useSnapshot(inputOptions);
436
436
  const value = useMemo(() => ({
437
- ForegroundComponent: memoized.ForegroundComponent,
438
- BackgroundComponent: memoized.BackgroundComponent,
439
- TitleComponent: memoized.TitleComponent,
440
- SubtitleComponent: memoized.SubtitleComponent,
441
- ContentComponent: memoized.ContentComponent,
442
- FooterComponent: memoized.FooterComponent,
437
+ ForegroundComponent: constant.ForegroundComponent,
438
+ BackgroundComponent: constant.BackgroundComponent,
439
+ TitleComponent: constant.TitleComponent,
440
+ SubtitleComponent: constant.SubtitleComponent,
441
+ ContentComponent: constant.ContentComponent,
442
+ FooterComponent: constant.FooterComponent,
443
443
  options: {
444
444
  ...DEFAULT_OPTIONS,
445
445
  ...options,
446
446
  },
447
- }), [memoized, options]);
447
+ }), [constant, options]);
448
448
  return (jsx(ConfigurationContext.Provider, { value: value, children: children }));
449
449
  });
450
450
 
@@ -1,7 +1,280 @@
1
+ /**
2
+ * Hook that provides access to the complete modal configuration context.
3
+ *
4
+ * Returns all configuration including component overrides and options.
5
+ * This is the most comprehensive hook for accessing modal configuration,
6
+ * useful when you need multiple configuration values or custom components.
7
+ *
8
+ * @returns Complete configuration context with components and options
9
+ */
1
10
  export declare const useConfigurationContext: () => import("./ConfigurationContext").ConfigurationContextProps;
11
+ /**
12
+ * Hook that provides only the modal options from configuration.
13
+ *
14
+ * Convenient when you only need access to options like duration, backdrop,
15
+ * and behavior settings without the component definitions.
16
+ *
17
+ * @returns Modal options object with all settings
18
+ *
19
+ * @example
20
+ * Basic usage:
21
+ * ```tsx
22
+ * function ModalBackdrop() {
23
+ * const options = useConfigurationOptions();
24
+ *
25
+ * return (
26
+ * <div
27
+ * className="modal-backdrop"
28
+ * style={{
29
+ * backgroundColor: options.backdrop,
30
+ * transition: `opacity ${options.duration} ease`
31
+ * }}
32
+ * onClick={options.closeOnBackdropClick ? handleClose : undefined}
33
+ * />
34
+ * );
35
+ * }
36
+ * ```
37
+ *
38
+ * @example
39
+ * Conditional behavior based on options:
40
+ * ```tsx
41
+ * function ModalCloseButton({ onClose }) {
42
+ * const { closeOnBackdropClick, manualDestroy } = useConfigurationOptions();
43
+ * const [isClosing, setIsClosing] = useState(false);
44
+ *
45
+ * const handleClick = () => {
46
+ * if (manualDestroy) {
47
+ * setIsClosing(true);
48
+ * // Trigger close animation
49
+ * setTimeout(onClose, 300);
50
+ * } else {
51
+ * onClose();
52
+ * }
53
+ * };
54
+ *
55
+ * // Hide close button if backdrop click is disabled
56
+ * if (!closeOnBackdropClick) return null;
57
+ *
58
+ * return (
59
+ * <button
60
+ * onClick={handleClick}
61
+ * className={isClosing ? 'closing' : ''}
62
+ * >
63
+ * ×
64
+ * </button>
65
+ * );
66
+ * }
67
+ * ```
68
+ *
69
+ * @example
70
+ * Options-aware animations:
71
+ * ```tsx
72
+ * function AnimatedContent({ visible, children }) {
73
+ * const options = useConfigurationOptions();
74
+ * const contentRef = useRef<HTMLDivElement>(null);
75
+ *
76
+ * useEffect(() => {
77
+ * if (!contentRef.current) return;
78
+ *
79
+ * const element = contentRef.current;
80
+ * element.style.transition = `all ${options.duration} ease`;
81
+ *
82
+ * if (visible) {
83
+ * element.style.opacity = '1';
84
+ * element.style.transform = 'scale(1)';
85
+ * } else {
86
+ * element.style.opacity = '0';
87
+ * element.style.transform = 'scale(0.95)';
88
+ * }
89
+ * }, [visible, options.duration]);
90
+ *
91
+ * return <div ref={contentRef}>{children}</div>;
92
+ * }
93
+ * ```
94
+ */
2
95
  export declare const useConfigurationOptions: () => Required<import("../..").ModalOptions>;
96
+ /**
97
+ * Hook that provides modal animation duration in multiple formats.
98
+ *
99
+ * Returns both the original duration string and converted milliseconds,
100
+ * useful for JavaScript animations and timing calculations.
101
+ *
102
+ * @returns Object with duration string and milliseconds number
103
+ *
104
+ * @example
105
+ * Basic animation timing:
106
+ * ```tsx
107
+ * function TimedModal() {
108
+ * const { duration, milliseconds } = useConfigurationDuration();
109
+ * const [phase, setPhase] = useState<'entering' | 'visible' | 'leaving'>();
110
+ *
111
+ * useEffect(() => {
112
+ * if (phase === 'entering') {
113
+ * const timer = setTimeout(() => setPhase('visible'), milliseconds);
114
+ * return () => clearTimeout(timer);
115
+ * }
116
+ * }, [phase, milliseconds]);
117
+ *
118
+ * return (
119
+ * <div
120
+ * className={`modal-${phase}`}
121
+ * style={{ animationDuration: duration }}
122
+ * />
123
+ * );
124
+ * }
125
+ * ```
126
+ *
127
+ * @example
128
+ * Synchronized animations:
129
+ * ```tsx
130
+ * function ModalWithStaggeredElements({ items }) {
131
+ * const { duration, milliseconds } = useConfigurationDuration();
132
+ * const itemDelay = milliseconds / items.length;
133
+ *
134
+ * return (
135
+ * <div className="modal">
136
+ * {items.map((item, index) => (
137
+ * <div
138
+ * key={item.id}
139
+ * className="modal-item"
140
+ * style={{
141
+ * animationDuration: duration,
142
+ * animationDelay: `${index * itemDelay}ms`
143
+ * }}
144
+ * >
145
+ * {item.content}
146
+ * </div>
147
+ * ))}
148
+ * </div>
149
+ * );
150
+ * }
151
+ * ```
152
+ *
153
+ * @example
154
+ * Progress indicators:
155
+ * ```tsx
156
+ * function ModalProgress({ onComplete }) {
157
+ * const { milliseconds } = useConfigurationDuration();
158
+ * const [progress, setProgress] = useState(0);
159
+ *
160
+ * useEffect(() => {
161
+ * const startTime = Date.now();
162
+ * const interval = setInterval(() => {
163
+ * const elapsed = Date.now() - startTime;
164
+ * const percent = Math.min((elapsed / milliseconds) * 100, 100);
165
+ * setProgress(percent);
166
+ *
167
+ * if (percent >= 100) {
168
+ * clearInterval(interval);
169
+ * onComplete();
170
+ * }
171
+ * }, 16); // ~60fps
172
+ *
173
+ * return () => clearInterval(interval);
174
+ * }, [milliseconds, onComplete]);
175
+ *
176
+ * return (
177
+ * <div className="progress-bar">
178
+ * <div
179
+ * className="progress-fill"
180
+ * style={{ width: `${progress}%` }}
181
+ * />
182
+ * </div>
183
+ * );
184
+ * }
185
+ * ```
186
+ *
187
+ * @remarks
188
+ * - Supports various duration formats: '300ms', '0.3s', '1s', etc.
189
+ * - Automatically converts to milliseconds for JavaScript timing
190
+ * - Useful for coordinating CSS and JS animations
191
+ */
3
192
  export declare const useConfigurationDuration: () => {
4
193
  duration: `${number}ms`;
5
194
  milliseconds: number;
6
195
  };
196
+ /**
197
+ * Hook that provides the modal backdrop color configuration.
198
+ *
199
+ * Convenient accessor for backdrop styling, supporting any valid CSS color format.
200
+ *
201
+ * @returns Backdrop color string
202
+ *
203
+ * @example
204
+ * Basic backdrop:
205
+ * ```tsx
206
+ * function ModalOverlay({ visible }) {
207
+ * const backdrop = useConfigurationBackdrop();
208
+ *
209
+ * if (!visible) return null;
210
+ *
211
+ * return (
212
+ * <div
213
+ * className="fixed inset-0"
214
+ * style={{ backgroundColor: backdrop }}
215
+ * />
216
+ * );
217
+ * }
218
+ * ```
219
+ *
220
+ * @example
221
+ * Animated backdrop with opacity:
222
+ * ```tsx
223
+ * function AnimatedBackdrop({ visible }) {
224
+ * const backdrop = useConfigurationBackdrop();
225
+ * const [opacity, setOpacity] = useState(0);
226
+ *
227
+ * // Parse backdrop color and apply custom opacity
228
+ * const backdropWithOpacity = useMemo(() => {
229
+ * if (backdrop.startsWith('rgba')) {
230
+ * return backdrop.replace(/[\d.]+\)$/, `${opacity})`);
231
+ * }
232
+ * return `${backdrop}${Math.round(opacity * 255).toString(16).padStart(2, '0')}`;
233
+ * }, [backdrop, opacity]);
234
+ *
235
+ * useEffect(() => {
236
+ * setOpacity(visible ? 1 : 0);
237
+ * }, [visible]);
238
+ *
239
+ * return (
240
+ * <div
241
+ * className="backdrop"
242
+ * style={{
243
+ * backgroundColor: backdropWithOpacity,
244
+ * transition: 'opacity 300ms ease'
245
+ * }}
246
+ * />
247
+ * );
248
+ * }
249
+ * ```
250
+ *
251
+ * @example
252
+ * Theme-aware backdrop:
253
+ * ```tsx
254
+ * function ThemedBackdrop() {
255
+ * const backdrop = useConfigurationBackdrop();
256
+ * const { theme } = useTheme();
257
+ *
258
+ * const adjustedBackdrop = useMemo(() => {
259
+ * if (theme === 'dark') {
260
+ * // Make backdrop darker in dark mode
261
+ * return backdrop.replace('0.5', '0.8');
262
+ * }
263
+ * return backdrop;
264
+ * }, [backdrop, theme]);
265
+ *
266
+ * return (
267
+ * <div
268
+ * className="modal-backdrop"
269
+ * style={{ backgroundColor: adjustedBackdrop }}
270
+ * />
271
+ * );
272
+ * }
273
+ * ```
274
+ *
275
+ * @remarks
276
+ * - Supports all CSS color formats: hex, rgb, rgba, hsl, etc.
277
+ * - Default backdrop is typically semi-transparent black
278
+ * - Can be overridden at provider level or per-modal
279
+ */
7
280
  export declare const useConfigurationBackdrop: () => import("../../@aileron/declare").Color;