@lmb-it/kitsconcerto-native 0.1.293 → 0.1.295
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/components/overlay/ConfirmDialog/index.cjs +10 -8
- package/components/overlay/ConfirmDialog/index.cjs.map +1 -1
- package/components/overlay/ConfirmDialog/index.js +10 -8
- package/components/overlay/ConfirmDialog/index.js.map +1 -1
- package/contexts/DialogContext.cjs +97 -25
- package/contexts/DialogContext.cjs.map +1 -1
- package/contexts/DialogContext.js +98 -26
- package/contexts/DialogContext.js.map +1 -1
- package/form-renderer/hooks/useFormManager.cjs +5 -4
- package/form-renderer/hooks/useFormManager.cjs.map +1 -1
- package/form-renderer/hooks/useFormManager.js +5 -4
- package/form-renderer/hooks/useFormManager.js.map +1 -1
- package/hooks/useSeverityColors.cjs +5 -3
- package/hooks/useSeverityColors.cjs.map +1 -1
- package/hooks/useSeverityColors.js +5 -3
- package/hooks/useSeverityColors.js.map +1 -1
- package/index.d.ts +12 -3
- package/package.json +1 -1
|
@@ -12,34 +12,90 @@ var index_native$3 = require('../components/overlay/ConfirmPopup/index.cjs');
|
|
|
12
12
|
const PopupContext = React.createContext(null);
|
|
13
13
|
const PopupProvider = ({ children }) => {
|
|
14
14
|
const toastRef = React.useRef(null);
|
|
15
|
-
const [confirmState, setConfirmState] = React.useState({ visible: false });
|
|
15
|
+
const [confirmState, setConfirmState] = React.useState({ visible: false, owner: 0 });
|
|
16
16
|
const confirmPromiseRef = React.useRef({});
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
const confirmOwnerRef = React.useRef(0);
|
|
18
|
+
const notifiedConfirmOwnerRef = React.useRef(0);
|
|
19
|
+
const activeConfirmActionsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
20
|
+
const promptPromiseRef = React.useRef({});
|
|
21
|
+
const mountedRef = React.useRef(true);
|
|
22
|
+
const openConfirmation = React.useCallback((props, pending = {}) => {
|
|
23
|
+
if (!mountedRef.current) {
|
|
24
|
+
pending.resolve?.(false);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const previous = confirmPromiseRef.current;
|
|
28
|
+
if (previous.owner !== void 0) previous.resolve?.(false);
|
|
29
|
+
const owner2 = ++confirmOwnerRef.current;
|
|
30
|
+
confirmPromiseRef.current = { ...pending, owner: owner2 };
|
|
31
|
+
setConfirmState({ ...props, owner: owner2 });
|
|
32
|
+
}, []);
|
|
33
|
+
const hideConfirm = React.useCallback((owner2) => {
|
|
34
|
+
if (!mountedRef.current || owner2 !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner2)) return;
|
|
35
|
+
const pending = confirmPromiseRef.current;
|
|
36
|
+
setConfirmState((s) => s.owner === owner2 ? { ...s, visible: false } : s);
|
|
37
|
+
Promise.resolve().then(() => {
|
|
38
|
+
if (pending.owner !== owner2) return;
|
|
39
|
+
pending.resolve?.(false);
|
|
40
|
+
if (confirmPromiseRef.current === pending) confirmPromiseRef.current = {};
|
|
41
|
+
});
|
|
42
|
+
}, []);
|
|
43
|
+
const runConfirmAction = React.useCallback((owner2, accepted, callback, wait = false) => {
|
|
44
|
+
if (!mountedRef.current || owner2 !== confirmOwnerRef.current || confirmPromiseRef.current.owner !== owner2) return;
|
|
45
|
+
const pending = confirmPromiseRef.current;
|
|
25
46
|
confirmPromiseRef.current = {};
|
|
26
|
-
|
|
47
|
+
if (!wait) {
|
|
48
|
+
pending.resolve?.(accepted);
|
|
49
|
+
try {
|
|
50
|
+
return callback?.();
|
|
51
|
+
} finally {
|
|
52
|
+
hideConfirm(owner2);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
activeConfirmActionsRef.current.set(owner2, pending);
|
|
56
|
+
const failed = (error) => {
|
|
57
|
+
activeConfirmActionsRef.current.delete(owner2);
|
|
58
|
+
if (owner2 !== confirmOwnerRef.current || !mountedRef.current) {
|
|
59
|
+
pending.resolve?.(false);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
confirmPromiseRef.current = pending;
|
|
63
|
+
return Promise.reject(error);
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
return Promise.resolve(callback?.()).then(() => {
|
|
67
|
+
activeConfirmActionsRef.current.delete(owner2);
|
|
68
|
+
pending.resolve?.(accepted);
|
|
69
|
+
hideConfirm(owner2);
|
|
70
|
+
}, failed);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return failed(error);
|
|
73
|
+
}
|
|
27
74
|
}, [hideConfirm]);
|
|
28
75
|
const [confirmPopupState, setConfirmPopupState] = React.useState({ visible: false });
|
|
29
|
-
const hideConfirmPopup = React.useCallback((
|
|
76
|
+
const hideConfirmPopup = React.useCallback((_result) => setConfirmPopupState((s) => ({ ...s, visible: false })), []);
|
|
30
77
|
const [dialogState, setDialogState] = React.useState({ visible: false });
|
|
31
78
|
const onCloseRef = React.useRef();
|
|
32
79
|
React.useEffect(() => {
|
|
33
80
|
onCloseRef.current = dialogState.onClose;
|
|
34
81
|
}, [dialogState.onClose]);
|
|
35
82
|
const hideDialog = React.useCallback(() => {
|
|
83
|
+
promptPromiseRef.current.reject?.();
|
|
84
|
+
promptPromiseRef.current = {};
|
|
36
85
|
setDialogState((s) => ({ ...s, visible: false }));
|
|
37
86
|
onCloseRef.current?.();
|
|
38
87
|
}, []);
|
|
39
|
-
React.
|
|
88
|
+
React.useLayoutEffect(() => {
|
|
89
|
+
mountedRef.current = true;
|
|
90
|
+
const activeActions = activeConfirmActionsRef.current;
|
|
40
91
|
return () => {
|
|
92
|
+
mountedRef.current = false;
|
|
41
93
|
confirmPromiseRef.current.reject?.();
|
|
42
94
|
confirmPromiseRef.current = {};
|
|
95
|
+
activeActions.forEach((pending) => pending.reject?.());
|
|
96
|
+
activeActions.clear();
|
|
97
|
+
promptPromiseRef.current.reject?.();
|
|
98
|
+
promptPromiseRef.current = {};
|
|
43
99
|
};
|
|
44
100
|
}, []);
|
|
45
101
|
const toast = React.useCallback((...a) => {
|
|
@@ -52,8 +108,8 @@ const PopupProvider = ({ children }) => {
|
|
|
52
108
|
toastRef.current?.dismissAll?.();
|
|
53
109
|
}, []);
|
|
54
110
|
const confirm = React.useCallback((props) => {
|
|
55
|
-
|
|
56
|
-
}, []);
|
|
111
|
+
openConfirmation({ visible: true, acceptLabel: "Accept", rejectLabel: "Reject", ...props });
|
|
112
|
+
}, [openConfirmation]);
|
|
57
113
|
const confirmPopup = React.useCallback((props) => {
|
|
58
114
|
setConfirmPopupState({ visible: true, ...props });
|
|
59
115
|
}, []);
|
|
@@ -61,8 +117,7 @@ const PopupProvider = ({ children }) => {
|
|
|
61
117
|
setDialogState({ visible, ...props });
|
|
62
118
|
}, []);
|
|
63
119
|
const alert = React.useCallback((message, opts = {}) => new Promise((resolve) => {
|
|
64
|
-
|
|
65
|
-
setConfirmState({
|
|
120
|
+
openConfirmation({
|
|
66
121
|
visible: true,
|
|
67
122
|
header: opts.header ?? "Alert",
|
|
68
123
|
message,
|
|
@@ -71,23 +126,25 @@ const PopupProvider = ({ children }) => {
|
|
|
71
126
|
type: opts.type,
|
|
72
127
|
icon: opts.icon,
|
|
73
128
|
headless: opts.headless
|
|
74
|
-
});
|
|
75
|
-
}), []);
|
|
129
|
+
}, { resolve: () => resolve(), reject: () => resolve() });
|
|
130
|
+
}), [openConfirmation]);
|
|
76
131
|
const confirmAsync = React.useCallback((opts) => new Promise((resolve) => {
|
|
77
|
-
|
|
78
|
-
setConfirmState({
|
|
132
|
+
openConfirmation({
|
|
79
133
|
visible: true,
|
|
80
134
|
defaultUI: true,
|
|
81
135
|
acceptLabel: opts.acceptLabel ?? "Yes",
|
|
82
136
|
rejectLabel: opts.rejectLabel ?? "No",
|
|
83
137
|
...opts
|
|
84
|
-
});
|
|
85
|
-
}), []);
|
|
138
|
+
}, { resolve, reject: () => resolve(false) });
|
|
139
|
+
}), [openConfirmation]);
|
|
86
140
|
const prompt = React.useCallback((render, opts = {}) => new Promise((resolve, reject) => {
|
|
87
|
-
|
|
141
|
+
const pending = { resolve, reject };
|
|
142
|
+
promptPromiseRef.current.reject?.();
|
|
143
|
+
promptPromiseRef.current = pending;
|
|
88
144
|
const hide = () => {
|
|
145
|
+
if (promptPromiseRef.current !== pending) return;
|
|
89
146
|
setDialogState((s) => ({ ...s, visible: false }));
|
|
90
|
-
|
|
147
|
+
promptPromiseRef.current = {};
|
|
91
148
|
};
|
|
92
149
|
setDialogState({
|
|
93
150
|
visible: true,
|
|
@@ -116,10 +173,25 @@ const PopupProvider = ({ children }) => {
|
|
|
116
173
|
confirmAsync,
|
|
117
174
|
prompt
|
|
118
175
|
}), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);
|
|
176
|
+
const { owner, ...confirmationProps } = confirmState;
|
|
119
177
|
return /* @__PURE__ */ jsxRuntime.jsxs(PopupContext.Provider, { value, children: [
|
|
120
178
|
children,
|
|
121
179
|
/* @__PURE__ */ jsxRuntime.jsx(index_native.default, { ref: toastRef }),
|
|
122
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
180
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
181
|
+
index_native$1.default,
|
|
182
|
+
{
|
|
183
|
+
...confirmationProps,
|
|
184
|
+
onHide: (result) => {
|
|
185
|
+
if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner) || notifiedConfirmOwnerRef.current === owner) return;
|
|
186
|
+
notifiedConfirmOwnerRef.current = owner;
|
|
187
|
+
hideConfirm(owner);
|
|
188
|
+
confirmationProps.onHide?.(result);
|
|
189
|
+
},
|
|
190
|
+
accept: () => runConfirmAction(owner, true, confirmationProps.accept, confirmationProps.async),
|
|
191
|
+
reject: () => runConfirmAction(owner, false, confirmationProps.reject, confirmationProps.async)
|
|
192
|
+
},
|
|
193
|
+
owner
|
|
194
|
+
),
|
|
123
195
|
/* @__PURE__ */ jsxRuntime.jsx(index_native$2.default, { state: dialogState, onHide: hideDialog }),
|
|
124
196
|
/* @__PURE__ */ jsxRuntime.jsx(index_native$3.default, { onHide: hideConfirmPopup, ...confirmPopupState })
|
|
125
197
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogContext.cjs","sources":["../../../src/contexts/DialogContext.tsx"],"sourcesContent":["import React, {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from \"react\";\nimport KitsToast from \"../components/overlay/Toast\";\nimport KitsConfirm from \"../components/overlay/ConfirmDialog\";\nimport KitsDialog from \"../components/overlay/Dialog\";\nimport KitsConfirmPopup from \"../components/overlay/ConfirmPopup\";\nimport type {\n IConfirmDialogProps,\n IConfirmPopupProps,\n IDialogState,\n IKitsToastRef,\n IToastFunction,\n IToastParams,\n ToastPosition,\n} from \"@lmb-it/kitsconcerto-types\";\n\ninterface Ctx {\n confirm: (props: IConfirmDialogProps) => void;\n confirmPopup: (props: IConfirmPopupProps) => void;\n dialog: (props: IDialogState) => void;\n toast: IToastFunction;\n toastDismiss: (position?: ToastPosition) => void;\n toastDismissAll: () => void;\n alert: (message: React.ReactNode, opts?: IConfirmDialogProps) => Promise<void>;\n confirmAsync: (opts: IConfirmDialogProps) => Promise<boolean>;\n prompt: (\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts?: IConfirmDialogProps\n ) => Promise<any>;\n}\n\nconst PopupContext = createContext<Ctx>(null as any);\n\nconst PopupProvider: React.FC<React.PropsWithChildren> = ({children}) => {\n const toastRef = useRef<IKitsToastRef>(null);\n\n // --- Confirm ---\n const [confirmState, setConfirmState] = useState<IConfirmDialogProps>({visible: false});\n const confirmPromiseRef = useRef<{ resolve?: (v: any) => void; reject?: (r?: any) => void }>({});\n\n const hideConfirm = useCallback(() => setConfirmState(s => ({...s, visible: false})), []);\n const doAccept = useCallback(() => {\n confirmPromiseRef.current.resolve?.(true);\n confirmPromiseRef.current = {};\n hideConfirm();\n }, [hideConfirm]);\n const doReject = useCallback(() => {\n confirmPromiseRef.current.resolve?.(false);\n confirmPromiseRef.current = {};\n hideConfirm();\n }, [hideConfirm]);\n\n // --- ConfirmPopup ---\n const [confirmPopupState, setConfirmPopupState] = useState<IConfirmPopupProps>({visible: false});\n const hideConfirmPopup = useCallback((result) => setConfirmPopupState(s => ({...s, visible: false})), []);\n\n // --- Dialog ---\n const [dialogState, setDialogState] = useState<IDialogState>({visible: false});\n // @ts-ignore\n const onCloseRef = useRef<(() => void) | undefined>();\n\n useEffect(() => {\n onCloseRef.current = dialogState.onClose;\n }, [dialogState.onClose]);\n\n const hideDialog = useCallback(() => {\n setDialogState(s => ({...s, visible: false}));\n onCloseRef.current?.();\n }, []);\n\n // --- Cleanup pending promises on unmount ---\n useEffect(() => {\n return () => {\n confirmPromiseRef.current.reject?.();\n confirmPromiseRef.current = {};\n };\n }, []);\n\n // --- Toast API ---\n const toast = useCallback<IToastFunction>((...a) => {\n toastRef.current?.toast(...(a as IToastParams));\n }, []);\n\n const toastDismiss = useCallback((position?: ToastPosition) => {\n toastRef.current?.dismiss?.(position);\n }, []);\n\n const toastDismissAll = useCallback(() => {\n toastRef.current?.dismissAll?.();\n }, []);\n\n // --- Confirm API ---\n const confirm = useCallback((props: IConfirmDialogProps) => {\n setConfirmState({visible: true, acceptLabel: \"Accept\", rejectLabel: \"Reject\", ...props});\n }, []);\n\n const confirmPopup = useCallback((props: IConfirmPopupProps) => {\n setConfirmPopupState({visible: true, ...props});\n }, []);\n\n const dialog = useCallback(({visible = true, ...props}: IDialogState) => {\n setDialogState({visible, ...props});\n }, []);\n\n const alert = useCallback((message: React.ReactNode, opts: IConfirmDialogProps = {}) =>\n new Promise<void>(resolve => {\n confirmPromiseRef.current = {resolve: () => resolve()};\n setConfirmState({\n visible: true,\n header: opts.header ?? \"Alert\",\n message,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"OK\",\n type: opts.type,\n icon: opts.icon,\n headless: opts.headless,\n });\n }), []);\n\n const confirmAsync = useCallback((opts: IConfirmDialogProps) =>\n new Promise<boolean>(resolve => {\n confirmPromiseRef.current = {resolve};\n setConfirmState({\n visible: true,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"Yes\",\n rejectLabel: opts.rejectLabel ?? \"No\",\n ...opts,\n });\n }), []);\n\n const prompt = useCallback((\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts: IConfirmDialogProps = {}\n ) =>\n new Promise<any>((resolve, reject) => {\n confirmPromiseRef.current = {resolve, reject};\n const hide = () => {\n setDialogState(s => ({...s, visible: false}));\n confirmPromiseRef.current = {};\n };\n setDialogState({\n visible: true,\n header: opts.header,\n children: render({\n resolve: (v) => {\n resolve(v);\n hide();\n },\n reject: () => {\n reject();\n hide();\n },\n hide,\n }),\n });\n }), []);\n\n // --- Stable context value ---\n const value = useMemo<Ctx>(() => ({\n confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt,\n }), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);\n\n return (\n <PopupContext.Provider value={value}>\n {children}\n <KitsToast ref={toastRef}/>\n <KitsConfirm onHide={hideConfirm} accept={doAccept} reject={doReject} {...confirmState} />\n <KitsDialog state={dialogState} onHide={hideDialog}/>\n {/*@ts-ignore*/}\n <KitsConfirmPopup onHide={hideConfirmPopup} {...confirmPopupState} />\n </PopupContext.Provider>\n );\n};\n\nexport const usePopup = () => useContext(PopupContext);\nexport const useDialog = usePopup; // alias\n\nexport default PopupProvider;\n"],"names":["createContext","useRef","useState","useCallback","useEffect","useMemo","jsxs","jsx","KitsToast","KitsConfirm","KitsDialog","KitsConfirmPopup","useContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DialogContext.cjs","sources":["../../../src/contexts/DialogContext.tsx"],"sourcesContent":["import React, {createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from \"react\";\nimport KitsToast from \"../components/overlay/Toast\";\nimport KitsConfirm from \"../components/overlay/ConfirmDialog\";\nimport KitsDialog from \"../components/overlay/Dialog\";\nimport KitsConfirmPopup from \"../components/overlay/ConfirmPopup\";\nimport type {\n IConfirmDialogProps,\n IConfirmPopupProps,\n IDialogState,\n IKitsToastRef,\n IToastFunction,\n IToastParams,\n ToastPosition,\n} from \"@lmb-it/kitsconcerto-types\";\n\ninterface Ctx {\n confirm: (props: IConfirmDialogProps) => void;\n confirmPopup: (props: IConfirmPopupProps) => void;\n dialog: (props: IDialogState) => void;\n toast: IToastFunction;\n toastDismiss: (position?: ToastPosition) => void;\n toastDismissAll: () => void;\n alert: (message: React.ReactNode, opts?: IConfirmDialogProps) => Promise<void>;\n confirmAsync: (opts: IConfirmDialogProps) => Promise<boolean>;\n prompt: (\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts?: IConfirmDialogProps\n ) => Promise<any>;\n}\n\nconst PopupContext = createContext<Ctx>(null as any);\ntype PendingDialog = {resolve?: (v: any) => void; reject?: (r?: any) => void; owner?: number};\ntype OwnedConfirmation = IConfirmDialogProps & {owner: number};\n\nconst PopupProvider: React.FC<React.PropsWithChildren> = ({children}) => {\n const toastRef = useRef<IKitsToastRef>(null);\n\n // --- Confirm ---\n const [confirmState, setConfirmState] = useState<OwnedConfirmation>({visible: false, owner: 0});\n const confirmPromiseRef = useRef<PendingDialog>({});\n const confirmOwnerRef = useRef(0);\n const notifiedConfirmOwnerRef = useRef(0);\n const activeConfirmActionsRef = useRef(new Map<number, PendingDialog>());\n const promptPromiseRef = useRef<PendingDialog>({});\n const mountedRef = useRef(true);\n\n const openConfirmation = useCallback((props: IConfirmDialogProps, pending: PendingDialog = {}) => {\n if (!mountedRef.current) {pending.resolve?.(false); return;}\n const previous = confirmPromiseRef.current;\n if (previous.owner !== undefined) previous.resolve?.(false);\n const owner = ++confirmOwnerRef.current;\n confirmPromiseRef.current = {...pending, owner};\n setConfirmState({...props, owner});\n }, []);\n\n const hideConfirm = useCallback((owner: number) => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner)) return;\n const pending = confirmPromiseRef.current;\n setConfirmState(s => s.owner === owner ? {...s, visible: false} : s);\n // Some renderers close before invoking their explicit action. Settle\n // dismissal at the end of that synchronous action, without a timer.\n // A newer confirmation owns a different promise and is never cleared.\n Promise.resolve().then(() => {\n if (pending.owner !== owner) return;\n pending.resolve?.(false);\n if (confirmPromiseRef.current === pending) confirmPromiseRef.current = {};\n });\n }, []);\n const runConfirmAction = useCallback((owner: number, accepted: boolean, callback?: () => unknown, wait = false) => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || confirmPromiseRef.current.owner !== owner) return;\n const pending = confirmPromiseRef.current;\n confirmPromiseRef.current = {};\n if (!wait) {\n pending.resolve?.(accepted);\n try {return callback?.();} finally {hideConfirm(owner);}\n }\n activeConfirmActionsRef.current.set(owner, pending);\n const failed = (error: unknown) => {\n activeConfirmActionsRef.current.delete(owner);\n if (owner !== confirmOwnerRef.current || !mountedRef.current) {\n pending.resolve?.(false);\n return;\n }\n confirmPromiseRef.current = pending;\n return Promise.reject(error);\n };\n try {\n return Promise.resolve(callback?.()).then(() => {\n activeConfirmActionsRef.current.delete(owner);\n pending.resolve?.(accepted);\n hideConfirm(owner);\n }, failed);\n } catch (error) {\n return failed(error);\n }\n }, [hideConfirm]);\n\n // --- ConfirmPopup ---\n const [confirmPopupState, setConfirmPopupState] = useState<IConfirmPopupProps>({visible: false});\n const hideConfirmPopup = useCallback((_result: unknown) => setConfirmPopupState(s => ({...s, visible: false})), []);\n\n // --- Dialog ---\n const [dialogState, setDialogState] = useState<IDialogState>({visible: false});\n // @ts-ignore\n const onCloseRef = useRef<(() => void) | undefined>();\n\n useEffect(() => {\n onCloseRef.current = dialogState.onClose;\n }, [dialogState.onClose]);\n\n const hideDialog = useCallback(() => {\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = {};\n setDialogState(s => ({...s, visible: false}));\n onCloseRef.current?.();\n }, []);\n\n // --- Cleanup pending promises on unmount ---\n useLayoutEffect(() => {\n mountedRef.current = true;\n const activeActions = activeConfirmActionsRef.current;\n return () => {\n mountedRef.current = false;\n confirmPromiseRef.current.reject?.();\n confirmPromiseRef.current = {};\n activeActions.forEach(pending => pending.reject?.());\n activeActions.clear();\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = {};\n };\n }, []);\n\n // --- Toast API ---\n const toast = useCallback<IToastFunction>((...a) => {\n toastRef.current?.toast(...(a as IToastParams));\n }, []);\n\n const toastDismiss = useCallback((position?: ToastPosition) => {\n toastRef.current?.dismiss?.(position);\n }, []);\n\n const toastDismissAll = useCallback(() => {\n toastRef.current?.dismissAll?.();\n }, []);\n\n // --- Confirm API ---\n const confirm = useCallback((props: IConfirmDialogProps) => {\n openConfirmation({visible: true, acceptLabel: \"Accept\", rejectLabel: \"Reject\", ...props});\n }, [openConfirmation]);\n\n const confirmPopup = useCallback((props: IConfirmPopupProps) => {\n setConfirmPopupState({visible: true, ...props});\n }, []);\n\n const dialog = useCallback(({visible = true, ...props}: IDialogState) => {\n setDialogState({visible, ...props});\n }, []);\n\n const alert = useCallback((message: React.ReactNode, opts: IConfirmDialogProps = {}) =>\n new Promise<void>(resolve => {\n openConfirmation({\n visible: true,\n header: opts.header ?? \"Alert\",\n message,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"OK\",\n type: opts.type,\n icon: opts.icon,\n headless: opts.headless,\n }, {resolve: () => resolve(), reject: () => resolve()});\n }), [openConfirmation]);\n\n const confirmAsync = useCallback((opts: IConfirmDialogProps) =>\n new Promise<boolean>(resolve => {\n openConfirmation({\n visible: true,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"Yes\",\n rejectLabel: opts.rejectLabel ?? \"No\",\n ...opts,\n }, {resolve, reject: () => resolve(false)});\n }), [openConfirmation]);\n\n const prompt = useCallback((\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts: IConfirmDialogProps = {}\n ) =>\n new Promise<any>((resolve, reject) => {\n const pending = {resolve, reject};\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = pending;\n const hide = () => {\n if (promptPromiseRef.current !== pending) return;\n setDialogState(s => ({...s, visible: false}));\n promptPromiseRef.current = {};\n };\n setDialogState({\n visible: true,\n header: opts.header,\n children: render({\n resolve: (v) => {\n resolve(v);\n hide();\n },\n reject: () => {\n reject();\n hide();\n },\n hide,\n }),\n });\n }), []);\n\n // --- Stable context value ---\n const value = useMemo<Ctx>(() => ({\n confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt,\n }), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);\n const {owner, ...confirmationProps} = confirmState;\n\n return (\n <PopupContext.Provider value={value}>\n {children}\n <KitsToast ref={toastRef}/>\n <KitsConfirm\n key={owner}\n {...confirmationProps}\n onHide={result => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner) || notifiedConfirmOwnerRef.current === owner) return;\n notifiedConfirmOwnerRef.current = owner;\n hideConfirm(owner);\n confirmationProps.onHide?.(result);\n }}\n accept={() => runConfirmAction(owner, true, confirmationProps.accept, confirmationProps.async)}\n reject={() => runConfirmAction(owner, false, confirmationProps.reject, confirmationProps.async)}\n />\n <KitsDialog state={dialogState} onHide={hideDialog}/>\n {/*@ts-ignore*/}\n <KitsConfirmPopup onHide={hideConfirmPopup} {...confirmPopupState} />\n </PopupContext.Provider>\n );\n};\n\nexport const usePopup = () => useContext(PopupContext);\nexport const useDialog = usePopup; // alias\n\nexport default PopupProvider;\n"],"names":["createContext","useRef","useState","useCallback","owner","useEffect","useLayoutEffect","useMemo","jsxs","jsx","KitsToast","KitsConfirm","KitsDialog","KitsConfirmPopup","useContext"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createContext, useRef, useState, useCallback, useEffect, useMemo, useContext } from 'react';
|
|
2
|
+
import { createContext, useRef, useState, useCallback, useEffect, useLayoutEffect, useMemo, useContext } from 'react';
|
|
3
3
|
import KitsToast from '../components/overlay/Toast/index.js';
|
|
4
4
|
import KitsConfirm from '../components/overlay/ConfirmDialog/index.js';
|
|
5
5
|
import KitsDialogControlled from '../components/overlay/Dialog/index.js';
|
|
@@ -8,34 +8,90 @@ import KitsConfirmPopup from '../components/overlay/ConfirmPopup/index.js';
|
|
|
8
8
|
const PopupContext = createContext(null);
|
|
9
9
|
const PopupProvider = ({ children }) => {
|
|
10
10
|
const toastRef = useRef(null);
|
|
11
|
-
const [confirmState, setConfirmState] = useState({ visible: false });
|
|
11
|
+
const [confirmState, setConfirmState] = useState({ visible: false, owner: 0 });
|
|
12
12
|
const confirmPromiseRef = useRef({});
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const confirmOwnerRef = useRef(0);
|
|
14
|
+
const notifiedConfirmOwnerRef = useRef(0);
|
|
15
|
+
const activeConfirmActionsRef = useRef(/* @__PURE__ */ new Map());
|
|
16
|
+
const promptPromiseRef = useRef({});
|
|
17
|
+
const mountedRef = useRef(true);
|
|
18
|
+
const openConfirmation = useCallback((props, pending = {}) => {
|
|
19
|
+
if (!mountedRef.current) {
|
|
20
|
+
pending.resolve?.(false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const previous = confirmPromiseRef.current;
|
|
24
|
+
if (previous.owner !== void 0) previous.resolve?.(false);
|
|
25
|
+
const owner2 = ++confirmOwnerRef.current;
|
|
26
|
+
confirmPromiseRef.current = { ...pending, owner: owner2 };
|
|
27
|
+
setConfirmState({ ...props, owner: owner2 });
|
|
28
|
+
}, []);
|
|
29
|
+
const hideConfirm = useCallback((owner2) => {
|
|
30
|
+
if (!mountedRef.current || owner2 !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner2)) return;
|
|
31
|
+
const pending = confirmPromiseRef.current;
|
|
32
|
+
setConfirmState((s) => s.owner === owner2 ? { ...s, visible: false } : s);
|
|
33
|
+
Promise.resolve().then(() => {
|
|
34
|
+
if (pending.owner !== owner2) return;
|
|
35
|
+
pending.resolve?.(false);
|
|
36
|
+
if (confirmPromiseRef.current === pending) confirmPromiseRef.current = {};
|
|
37
|
+
});
|
|
38
|
+
}, []);
|
|
39
|
+
const runConfirmAction = useCallback((owner2, accepted, callback, wait = false) => {
|
|
40
|
+
if (!mountedRef.current || owner2 !== confirmOwnerRef.current || confirmPromiseRef.current.owner !== owner2) return;
|
|
41
|
+
const pending = confirmPromiseRef.current;
|
|
21
42
|
confirmPromiseRef.current = {};
|
|
22
|
-
|
|
43
|
+
if (!wait) {
|
|
44
|
+
pending.resolve?.(accepted);
|
|
45
|
+
try {
|
|
46
|
+
return callback?.();
|
|
47
|
+
} finally {
|
|
48
|
+
hideConfirm(owner2);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
activeConfirmActionsRef.current.set(owner2, pending);
|
|
52
|
+
const failed = (error) => {
|
|
53
|
+
activeConfirmActionsRef.current.delete(owner2);
|
|
54
|
+
if (owner2 !== confirmOwnerRef.current || !mountedRef.current) {
|
|
55
|
+
pending.resolve?.(false);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
confirmPromiseRef.current = pending;
|
|
59
|
+
return Promise.reject(error);
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
return Promise.resolve(callback?.()).then(() => {
|
|
63
|
+
activeConfirmActionsRef.current.delete(owner2);
|
|
64
|
+
pending.resolve?.(accepted);
|
|
65
|
+
hideConfirm(owner2);
|
|
66
|
+
}, failed);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return failed(error);
|
|
69
|
+
}
|
|
23
70
|
}, [hideConfirm]);
|
|
24
71
|
const [confirmPopupState, setConfirmPopupState] = useState({ visible: false });
|
|
25
|
-
const hideConfirmPopup = useCallback((
|
|
72
|
+
const hideConfirmPopup = useCallback((_result) => setConfirmPopupState((s) => ({ ...s, visible: false })), []);
|
|
26
73
|
const [dialogState, setDialogState] = useState({ visible: false });
|
|
27
74
|
const onCloseRef = useRef();
|
|
28
75
|
useEffect(() => {
|
|
29
76
|
onCloseRef.current = dialogState.onClose;
|
|
30
77
|
}, [dialogState.onClose]);
|
|
31
78
|
const hideDialog = useCallback(() => {
|
|
79
|
+
promptPromiseRef.current.reject?.();
|
|
80
|
+
promptPromiseRef.current = {};
|
|
32
81
|
setDialogState((s) => ({ ...s, visible: false }));
|
|
33
82
|
onCloseRef.current?.();
|
|
34
83
|
}, []);
|
|
35
|
-
|
|
84
|
+
useLayoutEffect(() => {
|
|
85
|
+
mountedRef.current = true;
|
|
86
|
+
const activeActions = activeConfirmActionsRef.current;
|
|
36
87
|
return () => {
|
|
88
|
+
mountedRef.current = false;
|
|
37
89
|
confirmPromiseRef.current.reject?.();
|
|
38
90
|
confirmPromiseRef.current = {};
|
|
91
|
+
activeActions.forEach((pending) => pending.reject?.());
|
|
92
|
+
activeActions.clear();
|
|
93
|
+
promptPromiseRef.current.reject?.();
|
|
94
|
+
promptPromiseRef.current = {};
|
|
39
95
|
};
|
|
40
96
|
}, []);
|
|
41
97
|
const toast = useCallback((...a) => {
|
|
@@ -48,8 +104,8 @@ const PopupProvider = ({ children }) => {
|
|
|
48
104
|
toastRef.current?.dismissAll?.();
|
|
49
105
|
}, []);
|
|
50
106
|
const confirm = useCallback((props) => {
|
|
51
|
-
|
|
52
|
-
}, []);
|
|
107
|
+
openConfirmation({ visible: true, acceptLabel: "Accept", rejectLabel: "Reject", ...props });
|
|
108
|
+
}, [openConfirmation]);
|
|
53
109
|
const confirmPopup = useCallback((props) => {
|
|
54
110
|
setConfirmPopupState({ visible: true, ...props });
|
|
55
111
|
}, []);
|
|
@@ -57,8 +113,7 @@ const PopupProvider = ({ children }) => {
|
|
|
57
113
|
setDialogState({ visible, ...props });
|
|
58
114
|
}, []);
|
|
59
115
|
const alert = useCallback((message, opts = {}) => new Promise((resolve) => {
|
|
60
|
-
|
|
61
|
-
setConfirmState({
|
|
116
|
+
openConfirmation({
|
|
62
117
|
visible: true,
|
|
63
118
|
header: opts.header ?? "Alert",
|
|
64
119
|
message,
|
|
@@ -67,23 +122,25 @@ const PopupProvider = ({ children }) => {
|
|
|
67
122
|
type: opts.type,
|
|
68
123
|
icon: opts.icon,
|
|
69
124
|
headless: opts.headless
|
|
70
|
-
});
|
|
71
|
-
}), []);
|
|
125
|
+
}, { resolve: () => resolve(), reject: () => resolve() });
|
|
126
|
+
}), [openConfirmation]);
|
|
72
127
|
const confirmAsync = useCallback((opts) => new Promise((resolve) => {
|
|
73
|
-
|
|
74
|
-
setConfirmState({
|
|
128
|
+
openConfirmation({
|
|
75
129
|
visible: true,
|
|
76
130
|
defaultUI: true,
|
|
77
131
|
acceptLabel: opts.acceptLabel ?? "Yes",
|
|
78
132
|
rejectLabel: opts.rejectLabel ?? "No",
|
|
79
133
|
...opts
|
|
80
|
-
});
|
|
81
|
-
}), []);
|
|
134
|
+
}, { resolve, reject: () => resolve(false) });
|
|
135
|
+
}), [openConfirmation]);
|
|
82
136
|
const prompt = useCallback((render, opts = {}) => new Promise((resolve, reject) => {
|
|
83
|
-
|
|
137
|
+
const pending = { resolve, reject };
|
|
138
|
+
promptPromiseRef.current.reject?.();
|
|
139
|
+
promptPromiseRef.current = pending;
|
|
84
140
|
const hide = () => {
|
|
141
|
+
if (promptPromiseRef.current !== pending) return;
|
|
85
142
|
setDialogState((s) => ({ ...s, visible: false }));
|
|
86
|
-
|
|
143
|
+
promptPromiseRef.current = {};
|
|
87
144
|
};
|
|
88
145
|
setDialogState({
|
|
89
146
|
visible: true,
|
|
@@ -112,10 +169,25 @@ const PopupProvider = ({ children }) => {
|
|
|
112
169
|
confirmAsync,
|
|
113
170
|
prompt
|
|
114
171
|
}), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);
|
|
172
|
+
const { owner, ...confirmationProps } = confirmState;
|
|
115
173
|
return /* @__PURE__ */ jsxs(PopupContext.Provider, { value, children: [
|
|
116
174
|
children,
|
|
117
175
|
/* @__PURE__ */ jsx(KitsToast, { ref: toastRef }),
|
|
118
|
-
/* @__PURE__ */ jsx(
|
|
176
|
+
/* @__PURE__ */ jsx(
|
|
177
|
+
KitsConfirm,
|
|
178
|
+
{
|
|
179
|
+
...confirmationProps,
|
|
180
|
+
onHide: (result) => {
|
|
181
|
+
if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner) || notifiedConfirmOwnerRef.current === owner) return;
|
|
182
|
+
notifiedConfirmOwnerRef.current = owner;
|
|
183
|
+
hideConfirm(owner);
|
|
184
|
+
confirmationProps.onHide?.(result);
|
|
185
|
+
},
|
|
186
|
+
accept: () => runConfirmAction(owner, true, confirmationProps.accept, confirmationProps.async),
|
|
187
|
+
reject: () => runConfirmAction(owner, false, confirmationProps.reject, confirmationProps.async)
|
|
188
|
+
},
|
|
189
|
+
owner
|
|
190
|
+
),
|
|
119
191
|
/* @__PURE__ */ jsx(KitsDialogControlled, { state: dialogState, onHide: hideDialog }),
|
|
120
192
|
/* @__PURE__ */ jsx(KitsConfirmPopup, { onHide: hideConfirmPopup, ...confirmPopupState })
|
|
121
193
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogContext.js","sources":["../../../src/contexts/DialogContext.tsx"],"sourcesContent":["import React, {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from \"react\";\nimport KitsToast from \"../components/overlay/Toast\";\nimport KitsConfirm from \"../components/overlay/ConfirmDialog\";\nimport KitsDialog from \"../components/overlay/Dialog\";\nimport KitsConfirmPopup from \"../components/overlay/ConfirmPopup\";\nimport type {\n IConfirmDialogProps,\n IConfirmPopupProps,\n IDialogState,\n IKitsToastRef,\n IToastFunction,\n IToastParams,\n ToastPosition,\n} from \"@lmb-it/kitsconcerto-types\";\n\ninterface Ctx {\n confirm: (props: IConfirmDialogProps) => void;\n confirmPopup: (props: IConfirmPopupProps) => void;\n dialog: (props: IDialogState) => void;\n toast: IToastFunction;\n toastDismiss: (position?: ToastPosition) => void;\n toastDismissAll: () => void;\n alert: (message: React.ReactNode, opts?: IConfirmDialogProps) => Promise<void>;\n confirmAsync: (opts: IConfirmDialogProps) => Promise<boolean>;\n prompt: (\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts?: IConfirmDialogProps\n ) => Promise<any>;\n}\n\nconst PopupContext = createContext<Ctx>(null as any);\n\nconst PopupProvider: React.FC<React.PropsWithChildren> = ({children}) => {\n const toastRef = useRef<IKitsToastRef>(null);\n\n // --- Confirm ---\n const [confirmState, setConfirmState] = useState<IConfirmDialogProps>({visible: false});\n const confirmPromiseRef = useRef<{ resolve?: (v: any) => void; reject?: (r?: any) => void }>({});\n\n const hideConfirm = useCallback(() => setConfirmState(s => ({...s, visible: false})), []);\n const doAccept = useCallback(() => {\n confirmPromiseRef.current.resolve?.(true);\n confirmPromiseRef.current = {};\n hideConfirm();\n }, [hideConfirm]);\n const doReject = useCallback(() => {\n confirmPromiseRef.current.resolve?.(false);\n confirmPromiseRef.current = {};\n hideConfirm();\n }, [hideConfirm]);\n\n // --- ConfirmPopup ---\n const [confirmPopupState, setConfirmPopupState] = useState<IConfirmPopupProps>({visible: false});\n const hideConfirmPopup = useCallback((result) => setConfirmPopupState(s => ({...s, visible: false})), []);\n\n // --- Dialog ---\n const [dialogState, setDialogState] = useState<IDialogState>({visible: false});\n // @ts-ignore\n const onCloseRef = useRef<(() => void) | undefined>();\n\n useEffect(() => {\n onCloseRef.current = dialogState.onClose;\n }, [dialogState.onClose]);\n\n const hideDialog = useCallback(() => {\n setDialogState(s => ({...s, visible: false}));\n onCloseRef.current?.();\n }, []);\n\n // --- Cleanup pending promises on unmount ---\n useEffect(() => {\n return () => {\n confirmPromiseRef.current.reject?.();\n confirmPromiseRef.current = {};\n };\n }, []);\n\n // --- Toast API ---\n const toast = useCallback<IToastFunction>((...a) => {\n toastRef.current?.toast(...(a as IToastParams));\n }, []);\n\n const toastDismiss = useCallback((position?: ToastPosition) => {\n toastRef.current?.dismiss?.(position);\n }, []);\n\n const toastDismissAll = useCallback(() => {\n toastRef.current?.dismissAll?.();\n }, []);\n\n // --- Confirm API ---\n const confirm = useCallback((props: IConfirmDialogProps) => {\n setConfirmState({visible: true, acceptLabel: \"Accept\", rejectLabel: \"Reject\", ...props});\n }, []);\n\n const confirmPopup = useCallback((props: IConfirmPopupProps) => {\n setConfirmPopupState({visible: true, ...props});\n }, []);\n\n const dialog = useCallback(({visible = true, ...props}: IDialogState) => {\n setDialogState({visible, ...props});\n }, []);\n\n const alert = useCallback((message: React.ReactNode, opts: IConfirmDialogProps = {}) =>\n new Promise<void>(resolve => {\n confirmPromiseRef.current = {resolve: () => resolve()};\n setConfirmState({\n visible: true,\n header: opts.header ?? \"Alert\",\n message,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"OK\",\n type: opts.type,\n icon: opts.icon,\n headless: opts.headless,\n });\n }), []);\n\n const confirmAsync = useCallback((opts: IConfirmDialogProps) =>\n new Promise<boolean>(resolve => {\n confirmPromiseRef.current = {resolve};\n setConfirmState({\n visible: true,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"Yes\",\n rejectLabel: opts.rejectLabel ?? \"No\",\n ...opts,\n });\n }), []);\n\n const prompt = useCallback((\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts: IConfirmDialogProps = {}\n ) =>\n new Promise<any>((resolve, reject) => {\n confirmPromiseRef.current = {resolve, reject};\n const hide = () => {\n setDialogState(s => ({...s, visible: false}));\n confirmPromiseRef.current = {};\n };\n setDialogState({\n visible: true,\n header: opts.header,\n children: render({\n resolve: (v) => {\n resolve(v);\n hide();\n },\n reject: () => {\n reject();\n hide();\n },\n hide,\n }),\n });\n }), []);\n\n // --- Stable context value ---\n const value = useMemo<Ctx>(() => ({\n confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt,\n }), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);\n\n return (\n <PopupContext.Provider value={value}>\n {children}\n <KitsToast ref={toastRef}/>\n <KitsConfirm onHide={hideConfirm} accept={doAccept} reject={doReject} {...confirmState} />\n <KitsDialog state={dialogState} onHide={hideDialog}/>\n {/*@ts-ignore*/}\n <KitsConfirmPopup onHide={hideConfirmPopup} {...confirmPopupState} />\n </PopupContext.Provider>\n );\n};\n\nexport const usePopup = () => useContext(PopupContext);\nexport const useDialog = usePopup; // alias\n\nexport default PopupProvider;\n"],"names":["KitsDialog"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DialogContext.js","sources":["../../../src/contexts/DialogContext.tsx"],"sourcesContent":["import React, {createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from \"react\";\nimport KitsToast from \"../components/overlay/Toast\";\nimport KitsConfirm from \"../components/overlay/ConfirmDialog\";\nimport KitsDialog from \"../components/overlay/Dialog\";\nimport KitsConfirmPopup from \"../components/overlay/ConfirmPopup\";\nimport type {\n IConfirmDialogProps,\n IConfirmPopupProps,\n IDialogState,\n IKitsToastRef,\n IToastFunction,\n IToastParams,\n ToastPosition,\n} from \"@lmb-it/kitsconcerto-types\";\n\ninterface Ctx {\n confirm: (props: IConfirmDialogProps) => void;\n confirmPopup: (props: IConfirmPopupProps) => void;\n dialog: (props: IDialogState) => void;\n toast: IToastFunction;\n toastDismiss: (position?: ToastPosition) => void;\n toastDismissAll: () => void;\n alert: (message: React.ReactNode, opts?: IConfirmDialogProps) => Promise<void>;\n confirmAsync: (opts: IConfirmDialogProps) => Promise<boolean>;\n prompt: (\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts?: IConfirmDialogProps\n ) => Promise<any>;\n}\n\nconst PopupContext = createContext<Ctx>(null as any);\ntype PendingDialog = {resolve?: (v: any) => void; reject?: (r?: any) => void; owner?: number};\ntype OwnedConfirmation = IConfirmDialogProps & {owner: number};\n\nconst PopupProvider: React.FC<React.PropsWithChildren> = ({children}) => {\n const toastRef = useRef<IKitsToastRef>(null);\n\n // --- Confirm ---\n const [confirmState, setConfirmState] = useState<OwnedConfirmation>({visible: false, owner: 0});\n const confirmPromiseRef = useRef<PendingDialog>({});\n const confirmOwnerRef = useRef(0);\n const notifiedConfirmOwnerRef = useRef(0);\n const activeConfirmActionsRef = useRef(new Map<number, PendingDialog>());\n const promptPromiseRef = useRef<PendingDialog>({});\n const mountedRef = useRef(true);\n\n const openConfirmation = useCallback((props: IConfirmDialogProps, pending: PendingDialog = {}) => {\n if (!mountedRef.current) {pending.resolve?.(false); return;}\n const previous = confirmPromiseRef.current;\n if (previous.owner !== undefined) previous.resolve?.(false);\n const owner = ++confirmOwnerRef.current;\n confirmPromiseRef.current = {...pending, owner};\n setConfirmState({...props, owner});\n }, []);\n\n const hideConfirm = useCallback((owner: number) => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner)) return;\n const pending = confirmPromiseRef.current;\n setConfirmState(s => s.owner === owner ? {...s, visible: false} : s);\n // Some renderers close before invoking their explicit action. Settle\n // dismissal at the end of that synchronous action, without a timer.\n // A newer confirmation owns a different promise and is never cleared.\n Promise.resolve().then(() => {\n if (pending.owner !== owner) return;\n pending.resolve?.(false);\n if (confirmPromiseRef.current === pending) confirmPromiseRef.current = {};\n });\n }, []);\n const runConfirmAction = useCallback((owner: number, accepted: boolean, callback?: () => unknown, wait = false) => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || confirmPromiseRef.current.owner !== owner) return;\n const pending = confirmPromiseRef.current;\n confirmPromiseRef.current = {};\n if (!wait) {\n pending.resolve?.(accepted);\n try {return callback?.();} finally {hideConfirm(owner);}\n }\n activeConfirmActionsRef.current.set(owner, pending);\n const failed = (error: unknown) => {\n activeConfirmActionsRef.current.delete(owner);\n if (owner !== confirmOwnerRef.current || !mountedRef.current) {\n pending.resolve?.(false);\n return;\n }\n confirmPromiseRef.current = pending;\n return Promise.reject(error);\n };\n try {\n return Promise.resolve(callback?.()).then(() => {\n activeConfirmActionsRef.current.delete(owner);\n pending.resolve?.(accepted);\n hideConfirm(owner);\n }, failed);\n } catch (error) {\n return failed(error);\n }\n }, [hideConfirm]);\n\n // --- ConfirmPopup ---\n const [confirmPopupState, setConfirmPopupState] = useState<IConfirmPopupProps>({visible: false});\n const hideConfirmPopup = useCallback((_result: unknown) => setConfirmPopupState(s => ({...s, visible: false})), []);\n\n // --- Dialog ---\n const [dialogState, setDialogState] = useState<IDialogState>({visible: false});\n // @ts-ignore\n const onCloseRef = useRef<(() => void) | undefined>();\n\n useEffect(() => {\n onCloseRef.current = dialogState.onClose;\n }, [dialogState.onClose]);\n\n const hideDialog = useCallback(() => {\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = {};\n setDialogState(s => ({...s, visible: false}));\n onCloseRef.current?.();\n }, []);\n\n // --- Cleanup pending promises on unmount ---\n useLayoutEffect(() => {\n mountedRef.current = true;\n const activeActions = activeConfirmActionsRef.current;\n return () => {\n mountedRef.current = false;\n confirmPromiseRef.current.reject?.();\n confirmPromiseRef.current = {};\n activeActions.forEach(pending => pending.reject?.());\n activeActions.clear();\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = {};\n };\n }, []);\n\n // --- Toast API ---\n const toast = useCallback<IToastFunction>((...a) => {\n toastRef.current?.toast(...(a as IToastParams));\n }, []);\n\n const toastDismiss = useCallback((position?: ToastPosition) => {\n toastRef.current?.dismiss?.(position);\n }, []);\n\n const toastDismissAll = useCallback(() => {\n toastRef.current?.dismissAll?.();\n }, []);\n\n // --- Confirm API ---\n const confirm = useCallback((props: IConfirmDialogProps) => {\n openConfirmation({visible: true, acceptLabel: \"Accept\", rejectLabel: \"Reject\", ...props});\n }, [openConfirmation]);\n\n const confirmPopup = useCallback((props: IConfirmPopupProps) => {\n setConfirmPopupState({visible: true, ...props});\n }, []);\n\n const dialog = useCallback(({visible = true, ...props}: IDialogState) => {\n setDialogState({visible, ...props});\n }, []);\n\n const alert = useCallback((message: React.ReactNode, opts: IConfirmDialogProps = {}) =>\n new Promise<void>(resolve => {\n openConfirmation({\n visible: true,\n header: opts.header ?? \"Alert\",\n message,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"OK\",\n type: opts.type,\n icon: opts.icon,\n headless: opts.headless,\n }, {resolve: () => resolve(), reject: () => resolve()});\n }), [openConfirmation]);\n\n const confirmAsync = useCallback((opts: IConfirmDialogProps) =>\n new Promise<boolean>(resolve => {\n openConfirmation({\n visible: true,\n defaultUI: true,\n acceptLabel: opts.acceptLabel ?? \"Yes\",\n rejectLabel: opts.rejectLabel ?? \"No\",\n ...opts,\n }, {resolve, reject: () => resolve(false)});\n }), [openConfirmation]);\n\n const prompt = useCallback((\n render: (api: { resolve: (v: any) => void; reject: () => void; hide: () => void }) => React.ReactNode,\n opts: IConfirmDialogProps = {}\n ) =>\n new Promise<any>((resolve, reject) => {\n const pending = {resolve, reject};\n promptPromiseRef.current.reject?.();\n promptPromiseRef.current = pending;\n const hide = () => {\n if (promptPromiseRef.current !== pending) return;\n setDialogState(s => ({...s, visible: false}));\n promptPromiseRef.current = {};\n };\n setDialogState({\n visible: true,\n header: opts.header,\n children: render({\n resolve: (v) => {\n resolve(v);\n hide();\n },\n reject: () => {\n reject();\n hide();\n },\n hide,\n }),\n });\n }), []);\n\n // --- Stable context value ---\n const value = useMemo<Ctx>(() => ({\n confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt,\n }), [confirm, confirmPopup, dialog, toast, toastDismiss, toastDismissAll, alert, confirmAsync, prompt]);\n const {owner, ...confirmationProps} = confirmState;\n\n return (\n <PopupContext.Provider value={value}>\n {children}\n <KitsToast ref={toastRef}/>\n <KitsConfirm\n key={owner}\n {...confirmationProps}\n onHide={result => {\n if (!mountedRef.current || owner !== confirmOwnerRef.current || activeConfirmActionsRef.current.has(owner) || notifiedConfirmOwnerRef.current === owner) return;\n notifiedConfirmOwnerRef.current = owner;\n hideConfirm(owner);\n confirmationProps.onHide?.(result);\n }}\n accept={() => runConfirmAction(owner, true, confirmationProps.accept, confirmationProps.async)}\n reject={() => runConfirmAction(owner, false, confirmationProps.reject, confirmationProps.async)}\n />\n <KitsDialog state={dialogState} onHide={hideDialog}/>\n {/*@ts-ignore*/}\n <KitsConfirmPopup onHide={hideConfirmPopup} {...confirmPopupState} />\n </PopupContext.Provider>\n );\n};\n\nexport const usePopup = () => useContext(PopupContext);\nexport const useDialog = usePopup; // alias\n\nexport default PopupProvider;\n"],"names":["owner","KitsDialog"],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ const useFormManager = ({
|
|
|
24
24
|
}
|
|
25
25
|
}, [elements]);
|
|
26
26
|
const defaultValues = React.useMemo(() => helpers.getDefaultValues(elements), [elements]);
|
|
27
|
-
const schema = React.useMemo(() => schemaBuilder.schemaBuilder(elements), [elements]);
|
|
27
|
+
const schema = React.useMemo(() => schemaBuilder.schemaBuilder(elements), [elements, id]);
|
|
28
28
|
const combinedChildIds = React.useMemo(() => helpers.getCombinedChildIds(elements), [elements]);
|
|
29
29
|
const stripCombinedChildren = React.useCallback((data) => {
|
|
30
30
|
if (combinedChildIds.size === 0) return data;
|
|
@@ -82,7 +82,7 @@ const useFormManager = ({
|
|
|
82
82
|
[outputFormat, onSubmit, setIsSubmitting, formMethods, stripCombinedChildren]
|
|
83
83
|
);
|
|
84
84
|
const handleSubmitWrapper = React.useCallback(() => {
|
|
85
|
-
formMethods.handleSubmit(onValidSubmit, (errors) => {
|
|
85
|
+
return formMethods.handleSubmit(onValidSubmit, (errors) => {
|
|
86
86
|
setIsSubmitting(false);
|
|
87
87
|
onInvalidSubmit?.(errors);
|
|
88
88
|
})();
|
|
@@ -93,8 +93,9 @@ const useFormManager = ({
|
|
|
93
93
|
return acc[key];
|
|
94
94
|
}, obj);
|
|
95
95
|
}
|
|
96
|
+
const { watch } = formMethods;
|
|
96
97
|
React.useEffect(() => {
|
|
97
|
-
const subscription =
|
|
98
|
+
const subscription = watch((currentValues, { name, type }) => {
|
|
98
99
|
onChange?.(stripCombinedChildren(currentValues));
|
|
99
100
|
if (onChangeSingleValue && name && type === "change") {
|
|
100
101
|
if (!combinedChildIds.has(name)) {
|
|
@@ -104,7 +105,7 @@ const useFormManager = ({
|
|
|
104
105
|
}
|
|
105
106
|
});
|
|
106
107
|
return () => subscription.unsubscribe();
|
|
107
|
-
}, [
|
|
108
|
+
}, [watch, onChange, onChangeSingleValue, stripCombinedChildren, combinedChildIds]);
|
|
108
109
|
return {
|
|
109
110
|
formMethods,
|
|
110
111
|
// The original object for FormProvider
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormManager.cjs","sources":["../../../../src/form-renderer/hooks/useFormManager.ts"],"sourcesContent":["// hooks/useFormManager.ts\n\nimport {type Dispatch, type SetStateAction, useCallback, useEffect, useMemo} from 'react';\nimport {type FieldValues, type SubmitHandler, useForm, type UseFormReturn, type DefaultValues} from 'react-hook-form';\nimport {yupResolver} from '@hookform/resolvers/yup';\nimport {checkNameDuplication, getCombinedChildIds, getDefaultValues, schemaBuilder} from '../utils';\nimport type {IFormComponent} from '@lmb-it/kitsconcerto-types';\n\n// --- Using Your Provided Type Definitions ---\n\n\n// --- CORRECTED RETURN TYPE ---\nexport interface UseFormManagerReturn<T extends FieldValues> {\n /**\n * The original, unmodified methods returned from react-hook-form's useForm hook.\n * This is what gets passed to the FormProvider.\n */\n formMethods: UseFormReturn<T>;\n /**\n * Our custom loading state for the submit button.\n */\n isSubmitting: boolean;\n /**\n * Our wrapped submit handler that manages the isSubmitting state.\n * This is what the <form> element's onSubmit will call.\n */\n handleSubmit: () => void;\n\n setIsSubmitting: Dispatch<SetStateAction<boolean>>\n}\n\n// A helper utility to check for valid URLs, as used in your original getDefaultValues.\nconst isValidURL = (urlString: string): boolean => {\n try {\n const url = new URL(urlString);\n return ['http:', 'https:'].includes(url.protocol);\n } catch (_) {\n return false;\n }\n};\n\nexport const useFormManager = <T extends FieldValues>({\n elements,\n onSubmit,\n onInvalidSubmit, id,\n onChange,\n onChangeSingleValue, // <-- Add this\n outputFormat = 'Json'\n }: IFormComponent<T>, isSubmitting: boolean, setIsSubmitting: Dispatch<SetStateAction<boolean>>): UseFormManagerReturn<T> => {\n\n\n // 1. Check for duplicate names on mount and when elements change.\n useEffect(() => {\n try {\n checkNameDuplication(elements);\n } catch (error) {\n console.error(\"Form Configuration Error:\", error);\n }\n }, [elements]);\n\n // 2. Generate the default values object, memoized for performance.\n const defaultValues = useMemo(() => getDefaultValues(elements), [elements]);\n\n const schema = useMemo(() => schemaBuilder(elements, id!), [elements]);\n\n // 2b. Collect Combined children IDs to exclude from output data.\n const combinedChildIds = useMemo(() => getCombinedChildIds(elements), [elements]);\n\n const stripCombinedChildren = useCallback((data: Record<string, any>) => {\n if (combinedChildIds.size === 0) return data;\n const filtered: Record<string, any> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!combinedChildIds.has(key)) {\n filtered[key] = value;\n }\n }\n return filtered;\n }, [combinedChildIds]);\n\n // console.log(id, elements, schema)\n\n // console.log(schema.describe())\n // This is the original, unmodified object from react-hook-form\n const formMethods = useForm<T>({\n resolver: yupResolver(schema),\n defaultValues: defaultValues as DefaultValues<T>,\n shouldUnregister: false,\n mode: \"onSubmit\",\n reValidateMode: \"onChange\",\n // ... (defaultValues logic remains the same)\n });\n\n\n const onValidSubmit: SubmitHandler<any> = useCallback(\n (rawData) => {\n const data = stripCombinedChildren(rawData);\n if (outputFormat === \"FormData\") {\n const formData = new FormData();\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value)) {\n if (value.length === 1 && value[0] instanceof File) {\n formData.append(key, value[0]);\n } else {\n value.forEach((item) => {\n if (item instanceof File) {\n formData.append(`${key}[]`, item);\n } else if (\n typeof item === \"number\" ||\n typeof item === \"string\"\n ) {\n formData.append(`${key}[]`, item.toString());\n } else {\n formData.append(`${key}[]`, JSON.stringify(item));\n }\n });\n }\n } else {\n if (value instanceof File) {\n formData.append(key, value);\n } else if (\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n formData.append(key, value.toString());\n } else {\n formData.append(key, JSON.stringify(value));\n }\n }\n }\n\n onSubmit && onSubmit(formData, setIsSubmitting, formMethods);\n } else {\n onSubmit && onSubmit(data, setIsSubmitting, formMethods);\n }\n },\n [outputFormat, onSubmit, setIsSubmitting, formMethods, stripCombinedChildren],\n );\n\n\n // Our custom wrapper function\n const handleSubmitWrapper = useCallback(() => {\n // We call the ORIGINAL handleSubmit from formMethods here\n formMethods.handleSubmit(onValidSubmit, (errors) => {\n setIsSubmitting(false);\n onInvalidSubmit?.(errors);\n })();\n }, [formMethods, onValidSubmit, setIsSubmitting, onInvalidSubmit]);\n\n function getValueByPath(obj: any, path: string) {\n return path.split(\".\").reduce((acc, key) => {\n if (acc === undefined || acc === null) return undefined;\n return acc[key];\n }, obj);\n }\n\n // This useEffect hook handles both global and single-value change events.\n useEffect(() => {\n const subscription = formMethods.watch((currentValues, {name, type}) => {\n // 1. Trigger the global onChange callback with all values (excluding Combined children).\n onChange?.(stripCombinedChildren(currentValues as { [s: string]: any }));\n\n // 2. Trigger the single value change callback (skip Combined child fields).\n if (onChangeSingleValue && name && type === 'change') {\n if (!combinedChildIds.has(name)) {\n const value = getValueByPath(currentValues, name);\n onChangeSingleValue(name, value);\n }\n }\n });\n return () => subscription.unsubscribe();\n }, [formMethods.watch, onChange, onChangeSingleValue, stripCombinedChildren, combinedChildIds]);\n\n // Return the two concerns separately\n return {\n formMethods, // The original object for FormProvider\n isSubmitting,\n setIsSubmitting,\n handleSubmit: handleSubmitWrapper, // The wrapped function for our UI\n };\n};\n"],"names":["useEffect","checkNameDuplication","useMemo","getDefaultValues","schemaBuilder","getCombinedChildIds","useCallback","useForm","yupResolver"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFormManager.cjs","sources":["../../../../src/form-renderer/hooks/useFormManager.ts"],"sourcesContent":["// hooks/useFormManager.ts\n\nimport {type Dispatch, type SetStateAction, useCallback, useEffect, useMemo} from 'react';\nimport {type FieldValues, type SubmitHandler, useForm, type UseFormReturn, type DefaultValues} from 'react-hook-form';\nimport {yupResolver} from '@hookform/resolvers/yup';\nimport {checkNameDuplication, getCombinedChildIds, getDefaultValues, schemaBuilder} from '../utils';\nimport type {IFormComponent} from '@lmb-it/kitsconcerto-types';\n\n// --- Using Your Provided Type Definitions ---\n\n\n// --- CORRECTED RETURN TYPE ---\nexport interface UseFormManagerReturn<T extends FieldValues> {\n /**\n * The original, unmodified methods returned from react-hook-form's useForm hook.\n * This is what gets passed to the FormProvider.\n */\n formMethods: UseFormReturn<T>;\n /**\n * Our custom loading state for the submit button.\n */\n isSubmitting: boolean;\n /**\n * Our wrapped submit handler that manages the isSubmitting state.\n * This is what the <form> element's onSubmit will call.\n */\n handleSubmit: () => Promise<void>;\n\n setIsSubmitting: Dispatch<SetStateAction<boolean>>\n}\n\nexport const useFormManager = <T extends FieldValues>({\n elements,\n onSubmit,\n onInvalidSubmit, id,\n onChange,\n onChangeSingleValue, // <-- Add this\n outputFormat = 'Json'\n }: IFormComponent<T>, isSubmitting: boolean, setIsSubmitting: Dispatch<SetStateAction<boolean>>): UseFormManagerReturn<T> => {\n\n\n // 1. Check for duplicate names on mount and when elements change.\n useEffect(() => {\n try {\n checkNameDuplication(elements);\n } catch (error) {\n console.error(\"Form Configuration Error:\", error);\n }\n }, [elements]);\n\n // 2. Generate the default values object, memoized for performance.\n const defaultValues = useMemo(() => getDefaultValues(elements), [elements]);\n\n const schema = useMemo(() => schemaBuilder(elements, id!), [elements, id]);\n\n // 2b. Collect Combined children IDs to exclude from output data.\n const combinedChildIds = useMemo(() => getCombinedChildIds(elements), [elements]);\n\n const stripCombinedChildren = useCallback((data: Record<string, any>) => {\n if (combinedChildIds.size === 0) return data;\n const filtered: Record<string, any> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!combinedChildIds.has(key)) {\n filtered[key] = value;\n }\n }\n return filtered;\n }, [combinedChildIds]);\n\n // console.log(id, elements, schema)\n\n // console.log(schema.describe())\n // This is the original, unmodified object from react-hook-form\n const formMethods = useForm<T>({\n resolver: yupResolver(schema),\n defaultValues: defaultValues as DefaultValues<T>,\n shouldUnregister: false,\n mode: \"onSubmit\",\n reValidateMode: \"onChange\",\n // ... (defaultValues logic remains the same)\n });\n\n\n const onValidSubmit: SubmitHandler<any> = useCallback(\n (rawData) => {\n const data = stripCombinedChildren(rawData);\n if (outputFormat === \"FormData\") {\n const formData = new FormData();\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value)) {\n if (value.length === 1 && value[0] instanceof File) {\n formData.append(key, value[0]);\n } else {\n value.forEach((item) => {\n if (item instanceof File) {\n formData.append(`${key}[]`, item);\n } else if (\n typeof item === \"number\" ||\n typeof item === \"string\"\n ) {\n formData.append(`${key}[]`, item.toString());\n } else {\n formData.append(`${key}[]`, JSON.stringify(item));\n }\n });\n }\n } else {\n if (value instanceof File) {\n formData.append(key, value);\n } else if (\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n formData.append(key, value.toString());\n } else {\n formData.append(key, JSON.stringify(value));\n }\n }\n }\n\n onSubmit && onSubmit(formData, setIsSubmitting, formMethods);\n } else {\n onSubmit && onSubmit(data, setIsSubmitting, formMethods);\n }\n },\n [outputFormat, onSubmit, setIsSubmitting, formMethods, stripCombinedChildren],\n );\n\n\n // Our custom wrapper function\n const handleSubmitWrapper = useCallback(() => {\n // We call the ORIGINAL handleSubmit from formMethods here\n return formMethods.handleSubmit(onValidSubmit, (errors) => {\n setIsSubmitting(false);\n onInvalidSubmit?.(errors);\n })();\n }, [formMethods, onValidSubmit, setIsSubmitting, onInvalidSubmit]);\n\n function getValueByPath(obj: any, path: string) {\n return path.split(\".\").reduce((acc, key) => {\n if (acc === undefined || acc === null) return undefined;\n return acc[key];\n }, obj);\n }\n\n // This useEffect hook handles both global and single-value change events.\n const {watch} = formMethods;\n useEffect(() => {\n const subscription = watch((currentValues, {name, type}) => {\n // 1. Trigger the global onChange callback with all values (excluding Combined children).\n onChange?.(stripCombinedChildren(currentValues as { [s: string]: any }));\n\n // 2. Trigger the single value change callback (skip Combined child fields).\n if (onChangeSingleValue && name && type === 'change') {\n if (!combinedChildIds.has(name)) {\n const value = getValueByPath(currentValues, name);\n onChangeSingleValue(name, value);\n }\n }\n });\n return () => subscription.unsubscribe();\n }, [watch, onChange, onChangeSingleValue, stripCombinedChildren, combinedChildIds]);\n\n // Return the two concerns separately\n return {\n formMethods, // The original object for FormProvider\n isSubmitting,\n setIsSubmitting,\n handleSubmit: handleSubmitWrapper, // The wrapped function for our UI\n };\n};\n"],"names":["useEffect","checkNameDuplication","useMemo","getDefaultValues","schemaBuilder","getCombinedChildIds","useCallback","useForm","yupResolver"],"mappings":"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"}
|