@lerx/promise-modal 0.12.1 → 0.12.3
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/README.md +5 -3
- package/dist/app/ModalManager.d.ts +10 -1
- package/dist/app/index.d.ts +2 -0
- package/dist/bootstrap/BootstrapProvider/useBootstrap.d.ts +2 -28
- package/dist/claude-hashes.json +3 -3
- package/dist/core/handle/alert.d.ts +5 -3
- package/dist/core/handle/confirm.d.ts +6 -4
- package/dist/core/handle/dispatchModal.d.ts +29 -0
- package/dist/core/handle/index.d.ts +1 -1
- package/dist/core/handle/prompt.d.ts +11 -12
- package/dist/core/handle/static.d.ts +7 -3
- package/dist/core/handle/type.d.ts +7 -3
- package/dist/core/node/ModalNode/PromptNode.d.ts +1 -1
- package/dist/helpers/hideModal.d.ts +2 -0
- package/dist/hooks/useModal.d.ts +2 -3
- package/dist/index.cjs +188 -149
- package/dist/index.mjs +188 -149
- package/dist/providers/ModalManagerContext/ModalManagerContext.d.ts +2 -2
- package/dist/providers/ModalManagerContext/useModalManagerContext.d.ts +1 -1
- package/dist/types/base.d.ts +5 -0
- package/docs/claude/skills/promise-modal-skill/knowledge/api-reference.md +3 -3
- package/docs/en/SPECIFICATION.md +3 -3
- package/docs/ko/SPECIFICATION.md +3 -3
- package/package.json +19 -8
- package/dist/helpers/subscribeAbortSignal.d.ts +0 -2
package/README.md
CHANGED
|
@@ -793,11 +793,13 @@ Opens a prompt modal to receive input from the user.
|
|
|
793
793
|
- props: `{ value: T; onChange: (value: T) => void }`
|
|
794
794
|
- `defaultValue?`: Default value (T)
|
|
795
795
|
- `disabled?`: Function to determine if confirm button should be disabled
|
|
796
|
-
- `(value: T) => boolean`
|
|
797
|
-
- `returnOnCancel?`:
|
|
796
|
+
- `(value: T | undefined) => boolean`
|
|
797
|
+
- `returnOnCancel?`: If true, cancel resolves with the current input value instead of null (boolean)
|
|
798
798
|
- `footer?`: Footer settings (similar to confirm)
|
|
799
799
|
|
|
800
|
-
**Returns:** `Promise<T>` - Resolves to the input value
|
|
800
|
+
**Returns:** `Promise<T | null>` - Resolves to the input value on confirm, or null on cancel
|
|
801
|
+
|
|
802
|
+
> **Upgrade note:** `prompt()` now types cancellation explicitly — the return is `Promise<T | null>` and the `disabled` callback receives `T | undefined`. Consumers that previously annotated these as non-null may hit new TypeScript errors on upgrade; the runtime behaviour (cancel resolves `null`) is unchanged.
|
|
801
803
|
|
|
802
804
|
```typescript
|
|
803
805
|
// Example
|
|
@@ -15,8 +15,17 @@ export declare class ModalManager {
|
|
|
15
15
|
static get anchored(): boolean;
|
|
16
16
|
private static __prerenderList__;
|
|
17
17
|
static get prerender(): Modal[];
|
|
18
|
+
private static __defaultOpenHandler__;
|
|
18
19
|
private static __openHandler__;
|
|
20
|
+
/**
|
|
21
|
+
* Registers the React-side open handler, then flushes the prerender queue
|
|
22
|
+
* through it so modals opened before mount keep their promise wiring alive.
|
|
23
|
+
*/
|
|
19
24
|
static set openHandler(handler: Fn<[Modal], ModalNode>);
|
|
25
|
+
/** Attaches a flush-time dispatcher to a queued modal; no-op if not queued. */
|
|
26
|
+
static bindPrerender(modal: Modal, dispatch: Fn): void;
|
|
27
|
+
/** Removes a queued modal (pre-mount abort). Returns whether it was queued. */
|
|
28
|
+
static cancelPrerender(modal: Modal): boolean;
|
|
20
29
|
private static __refreshHandler__?;
|
|
21
30
|
static set refreshHandler(handler: Fn<[], void>);
|
|
22
31
|
static refresh(): void;
|
|
@@ -24,5 +33,5 @@ export declare class ModalManager {
|
|
|
24
33
|
static applyStyleSheet(): void;
|
|
25
34
|
static getHashedClassNames(styleId: string): string;
|
|
26
35
|
static reset(): void;
|
|
27
|
-
static open(modal: Modal): ModalNode;
|
|
36
|
+
static open(modal: Modal): ModalNode | undefined;
|
|
28
37
|
}
|
|
@@ -96,33 +96,6 @@ import type { BootstrapProviderProps } from './type.js';
|
|
|
96
96
|
* ```
|
|
97
97
|
*
|
|
98
98
|
* @example
|
|
99
|
-
* Multiple modal systems:
|
|
100
|
-
* ```tsx
|
|
101
|
-
* function MultiModalApp() {
|
|
102
|
-
* // System modals (errors, confirmations)
|
|
103
|
-
* const { portal: systemPortal } = useBootstrap({
|
|
104
|
-
* ForegroundComponent: SystemModal,
|
|
105
|
-
* options: { backdrop: 'rgba(255, 0, 0, 0.8)' },
|
|
106
|
-
* });
|
|
107
|
-
*
|
|
108
|
-
* // Feature modals (forms, wizards)
|
|
109
|
-
* const { portal: featurePortal } = useBootstrap({
|
|
110
|
-
* ForegroundComponent: FeatureModal,
|
|
111
|
-
* options: { backdrop: 'rgba(0, 0, 255, 0.8)' },
|
|
112
|
-
* });
|
|
113
|
-
*
|
|
114
|
-
* return (
|
|
115
|
-
* <>
|
|
116
|
-
* <SystemSection />
|
|
117
|
-
* <FeatureSection />
|
|
118
|
-
* {systemPortal}
|
|
119
|
-
* {featurePortal}
|
|
120
|
-
* </>
|
|
121
|
-
* );
|
|
122
|
-
* }
|
|
123
|
-
* ```
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
99
|
* With custom hooks for specific modal types:
|
|
127
100
|
* ```tsx
|
|
128
101
|
* function useConfirmDialog() {
|
|
@@ -178,7 +151,8 @@ import type { BootstrapProviderProps } from './type.js';
|
|
|
178
151
|
* @remarks
|
|
179
152
|
* - Use `mode: 'manual'` when you need to control the initialization timing
|
|
180
153
|
* - The portal element must be rendered in your component tree
|
|
181
|
-
* -
|
|
154
|
+
* - The modal system is a singleton: mount exactly one bootstrap
|
|
155
|
+
* (ModalProvider or useBootstrap) at a time
|
|
182
156
|
* - Context changes will affect all modals created after the change
|
|
183
157
|
*/
|
|
184
158
|
export declare const useBootstrap: ({ usePathname: useExternalPathname, ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, context, mode, }?: BootstrapProviderProps & {
|
package/dist/claude-hashes.json
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": {
|
|
4
4
|
"name": "@lerx/promise-modal",
|
|
5
|
-
"version": "0.12.
|
|
5
|
+
"version": "0.12.3"
|
|
6
6
|
},
|
|
7
|
-
"generatedAt": "2026-
|
|
7
|
+
"generatedAt": "2026-07-05T18:39:01.047Z",
|
|
8
8
|
"algorithm": "sha256",
|
|
9
9
|
"assetRoot": "docs/claude",
|
|
10
10
|
"files": {
|
|
11
11
|
"skills/promise-modal-skill/SKILL.md": "b424c979b9e969e11ba8fa0a56afc3cbf1793c822f06509e6b730068f384679e",
|
|
12
12
|
"skills/promise-modal-skill/knowledge/advanced-patterns.md": "2e2c29449a46b1336727f8a1d5f1eede4e99639675dbe819edd2bf4243acfaab",
|
|
13
|
-
"skills/promise-modal-skill/knowledge/api-reference.md": "
|
|
13
|
+
"skills/promise-modal-skill/knowledge/api-reference.md": "b54ae4dcd0791ebfce8110a69af615e712bfdcbb5be5b57f725cd4bfb12ab50f",
|
|
14
14
|
"skills/promise-modal-skill/knowledge/hooks-reference.md": "b0137caf257ad9712cfa7ab44c908041bbbc61bf355fa0180925a35479e47516",
|
|
15
15
|
"skills/promise-modal-skill/knowledge/type-definitions.md": "fde17b7f99d3e65b7e6c16abf4689af0a9e41a8a06dfeb9482b94a7611841d50"
|
|
16
16
|
},
|
|
@@ -8,7 +8,8 @@ import type { AlertProps } from './type.js';
|
|
|
8
8
|
* @returns Object containing modalNode and promiseHandler
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
* - modalNode:
|
|
11
|
+
* - modalNode: live getter for the modal node; undefined while the modal is
|
|
12
|
+
* queued before the ModalProvider mounts, then set once the queue flushes
|
|
12
13
|
* - promiseHandler: Promise that resolves when the modal is closed
|
|
13
14
|
*
|
|
14
15
|
* @example
|
|
@@ -22,6 +23,7 @@ import type { AlertProps } from './type.js';
|
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
25
|
export declare const alertHandler: <BackgroundValue = any>(args: AlertProps<BackgroundValue>) => {
|
|
25
|
-
readonly modalNode: AlertNode<BackgroundValue
|
|
26
|
-
|
|
26
|
+
readonly modalNode: AlertNode<BackgroundValue> | undefined;
|
|
27
|
+
promiseHandler: Promise<void>;
|
|
28
|
+
cancel: import("../../@aileron/declare").Fn<[], void>;
|
|
27
29
|
};
|
|
@@ -8,10 +8,11 @@ import type { ConfirmProps } from './type.js';
|
|
|
8
8
|
* @returns Object containing modalNode and promiseHandler
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
* - modalNode:
|
|
11
|
+
* - modalNode: live getter for the modal node; undefined while the modal is
|
|
12
|
+
* queued before the ModalProvider mounts, then set once the queue flushes
|
|
12
13
|
* - promiseHandler: Promise that resolves to true if confirmed, false if cancelled
|
|
13
14
|
* - Returns true only when explicitly confirmed via the confirm action
|
|
14
|
-
* - Returns false for cancel action
|
|
15
|
+
* - Returns false for cancel action, backdrop click (if enabled), or abort
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* ```tsx
|
|
@@ -27,6 +28,7 @@ import type { ConfirmProps } from './type.js';
|
|
|
27
28
|
* ```
|
|
28
29
|
*/
|
|
29
30
|
export declare const confirmHandler: <BackgroundValue = any>(args: ConfirmProps<BackgroundValue>) => {
|
|
30
|
-
readonly modalNode: ConfirmNode<BackgroundValue
|
|
31
|
-
|
|
31
|
+
readonly modalNode: ConfirmNode<BackgroundValue> | undefined;
|
|
32
|
+
promiseHandler: Promise<boolean>;
|
|
33
|
+
cancel: import("../../@aileron/declare").Fn<[], void>;
|
|
32
34
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Fn } from '../../@aileron/declare/index.js';
|
|
2
|
+
import type { ModalNode } from '../../core/node/index.js';
|
|
3
|
+
import type { Modal } from '../../types/index.js';
|
|
4
|
+
interface DispatchModalOptions<Result> {
|
|
5
|
+
/** Abort signal that cancels the modal (before or after mount). */
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
/** Maps the node's raw resolve payload to the public promise result. */
|
|
8
|
+
mapResult: Fn<[result: unknown], Result>;
|
|
9
|
+
/** Raw payload used when the modal is aborted before React ever mounted. */
|
|
10
|
+
cancelResult: Fn<[], unknown>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Opens a modal through ModalManager and wires its promise settlement.
|
|
14
|
+
*
|
|
15
|
+
* The resolver travels inside the modal data (`handleResolve`), so the wiring
|
|
16
|
+
* survives the prerender queue: modals opened before the provider mounts are
|
|
17
|
+
* flushed later and still settle the very same promise.
|
|
18
|
+
*
|
|
19
|
+
* @returns modalNode - live getter: undefined while the modal is queued before
|
|
20
|
+
* mount, then the node created by the flush (late reads see the real node)
|
|
21
|
+
* @returns promiseHandler - settles on user interaction or abort; rejects only
|
|
22
|
+
* when the open handler itself throws
|
|
23
|
+
*/
|
|
24
|
+
export declare const dispatchModal: <Node extends ModalNode, Result>(modal: Modal, { signal, mapResult, cancelResult }: DispatchModalOptions<Result>) => {
|
|
25
|
+
readonly modalNode: Node | undefined;
|
|
26
|
+
promiseHandler: Promise<Result>;
|
|
27
|
+
cancel: Fn<[], void>;
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -2,4 +2,4 @@ export { alertHandler } from './alert.js';
|
|
|
2
2
|
export { confirmHandler } from './confirm.js';
|
|
3
3
|
export { promptHandler } from './prompt.js';
|
|
4
4
|
export { alert, confirm, prompt } from './static.js';
|
|
5
|
-
export type { AlertProps, ConfirmProps, PromptProps } from './type.js';
|
|
5
|
+
export type { AlertProps, ConfirmProps, OverridableHandleProps, PromptProps, } from './type.js';
|
|
@@ -9,12 +9,14 @@ import type { PromptProps } from './type.js';
|
|
|
9
9
|
* @returns Object containing modalNode and promiseHandler
|
|
10
10
|
*
|
|
11
11
|
* @remarks
|
|
12
|
-
* - modalNode:
|
|
13
|
-
*
|
|
12
|
+
* - modalNode: live getter for the modal node; undefined while the modal is
|
|
13
|
+
* queued before the ModalProvider mounts, then set once the queue flushes
|
|
14
|
+
* - promiseHandler: Promise that resolves with the user input value
|
|
14
15
|
* - Input component receives value, onChange, onConfirm, onCancel, and context props
|
|
15
16
|
* - Use disabled function to control confirm button's enabled state
|
|
16
|
-
* - If returnOnCancel is false (default), promise
|
|
17
|
-
* - If returnOnCancel is true,
|
|
17
|
+
* - If returnOnCancel is false (default), the promise resolves with null on cancel
|
|
18
|
+
* - If returnOnCancel is true, resolves with the input value at cancel time
|
|
19
|
+
* (initially defaultValue)
|
|
18
20
|
*
|
|
19
21
|
* @example
|
|
20
22
|
* ```tsx
|
|
@@ -31,15 +33,12 @@ import type { PromptProps } from './type.js';
|
|
|
31
33
|
* defaultValue: '',
|
|
32
34
|
* });
|
|
33
35
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* console.log('User entered:', name);
|
|
37
|
-
* } catch {
|
|
38
|
-
* console.log('User cancelled');
|
|
39
|
-
* }
|
|
36
|
+
* const name = await promiseHandler;
|
|
37
|
+
* if (name === null) console.log('User cancelled');
|
|
40
38
|
* ```
|
|
41
39
|
*/
|
|
42
40
|
export declare const promptHandler: <InputValue, BackgroundValue = any>(args: PromptProps<InputValue, BackgroundValue>) => {
|
|
43
|
-
readonly modalNode: PromptNode<InputValue, BackgroundValue
|
|
44
|
-
|
|
41
|
+
readonly modalNode: PromptNode<InputValue, BackgroundValue> | undefined;
|
|
42
|
+
promiseHandler: Promise<InputValue | null>;
|
|
43
|
+
cancel: import("../../@aileron/declare").Fn<[], void>;
|
|
45
44
|
};
|
|
@@ -66,8 +66,9 @@ export declare const confirm: <BackgroundValue = any>(args: ConfirmProps<Backgro
|
|
|
66
66
|
* @typeParam InputValue - Type of the value collected from user input
|
|
67
67
|
* @typeParam BackgroundValue - Type of background data passed to BackgroundComponent
|
|
68
68
|
* @param args - Prompt modal configuration options
|
|
69
|
-
* @returns Promise that resolves with user input value
|
|
70
|
-
*
|
|
69
|
+
* @returns Promise that resolves with the user input value on confirm, or null
|
|
70
|
+
* on cancel. With returnOnCancel: true, cancel resolves with the input value
|
|
71
|
+
* at cancel time (initially defaultValue) instead of null.
|
|
71
72
|
*
|
|
72
73
|
* @example
|
|
73
74
|
* ```tsx
|
|
@@ -84,6 +85,9 @@ export declare const confirm: <BackgroundValue = any>(args: ConfirmProps<Backgro
|
|
|
84
85
|
* ),
|
|
85
86
|
* defaultValue: 'John Doe',
|
|
86
87
|
* });
|
|
88
|
+
* if (name === null) {
|
|
89
|
+
* console.log('User cancelled');
|
|
90
|
+
* }
|
|
87
91
|
* ```
|
|
88
92
|
*
|
|
89
93
|
* @example
|
|
@@ -102,4 +106,4 @@ export declare const confirm: <BackgroundValue = any>(args: ConfirmProps<Backgro
|
|
|
102
106
|
* });
|
|
103
107
|
* ```
|
|
104
108
|
*/
|
|
105
|
-
export declare const prompt: <InputValue, BackgroundValue = any>(args: PromptProps<InputValue, BackgroundValue>) => Promise<InputValue>;
|
|
109
|
+
export declare const prompt: <InputValue, BackgroundValue = any>(args: PromptProps<InputValue, BackgroundValue>) => Promise<InputValue | null>;
|
|
@@ -44,9 +44,13 @@ export interface PromptProps<InputValue, BackgroundValue = any> extends BaseHand
|
|
|
44
44
|
defaultValue?: InputValue;
|
|
45
45
|
/** Input component that receives value, onChange, and other props */
|
|
46
46
|
Input: Fn<[props: PromptInputProps<InputValue>], ReactNode>;
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Validation function. Returns true to disable the confirm button.
|
|
49
|
+
* Called with the current value, which stays undefined until the first
|
|
50
|
+
* input when no defaultValue is provided.
|
|
51
|
+
*/
|
|
52
|
+
disabled?: Fn<[value: InputValue | undefined], boolean>;
|
|
53
|
+
/** If true, cancel resolves with the current input value instead of null */
|
|
50
54
|
returnOnCancel?: boolean;
|
|
51
55
|
/** Footer configuration. Can be a render function, options object, or false */
|
|
52
56
|
footer?: PromptFooterRender<InputValue> | FooterOptions | false;
|
|
@@ -8,7 +8,7 @@ export declare class PromptNode<T = any, B = any> extends AbstractNode<T, B> {
|
|
|
8
8
|
readonly content?: ReactNode | ComponentType<PromptContentProps>;
|
|
9
9
|
readonly defaultValue: T | undefined;
|
|
10
10
|
readonly Input: Fn<[props: PromptInputProps<T>], ReactNode>;
|
|
11
|
-
readonly disabled?: Fn<[value: T], boolean>;
|
|
11
|
+
readonly disabled?: Fn<[value: T | undefined], boolean>;
|
|
12
12
|
readonly returnOnCancel?: boolean;
|
|
13
13
|
readonly footer?: PromptFooterRender<T> | FooterOptions | false;
|
|
14
14
|
private __value__;
|
package/dist/hooks/useModal.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { type AlertProps, type ConfirmProps, type PromptProps } from '../core/index.js';
|
|
2
|
-
import type { OverridableHandleProps } from '../core/handle/type.js';
|
|
1
|
+
import { type AlertProps, type ConfirmProps, type OverridableHandleProps, type PromptProps } from '../core/index.js';
|
|
3
2
|
export declare const useModal: (configuration?: OverridableHandleProps) => {
|
|
4
3
|
readonly alert: <Background = any>(args: AlertProps<Background>) => Promise<void>;
|
|
5
4
|
readonly confirm: <Background = any>(args: ConfirmProps<Background>) => Promise<boolean>;
|
|
6
|
-
readonly prompt: <Value, Background = any>(args: PromptProps<Value, Background>) => Promise<Value>;
|
|
5
|
+
readonly prompt: <Value, Background = any>(args: PromptProps<Value, Background>) => Promise<Value | null>;
|
|
7
6
|
};
|