@qumra/jisr 1.0.2 → 1.0.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/dist/hooks/context.d.ts +16 -9
- package/dist/hooks/context.d.ts.map +1 -1
- package/dist/hooks/context.js +35 -12
- package/dist/hooks/context.js.map +1 -1
- package/dist/hooks/useModal.d.ts +24 -25
- package/dist/hooks/useModal.d.ts.map +1 -1
- package/dist/hooks/useModal.js +35 -28
- package/dist/hooks/useModal.js.map +1 -1
- package/dist/hooks/useNavigationMenu.d.ts +55 -0
- package/dist/hooks/useNavigationMenu.d.ts.map +1 -0
- package/dist/hooks/useNavigationMenu.js +81 -0
- package/dist/hooks/useNavigationMenu.js.map +1 -0
- package/dist/hooks/useSaveBar.d.ts +48 -24
- package/dist/hooks/useSaveBar.d.ts.map +1 -1
- package/dist/hooks/useSaveBar.js +73 -25
- package/dist/hooks/useSaveBar.js.map +1 -1
- package/dist/hooks/useToast.js +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jisr.global.js +2 -0
- package/dist/jisr.global.js.map +1 -0
- package/dist/utils/actions.d.ts +47 -14
- package/dist/utils/actions.d.ts.map +1 -1
- package/dist/utils/actions.js +26 -17
- package/dist/utils/actions.js.map +1 -1
- package/dist/utils/app-bridge.d.ts +19 -2
- package/dist/utils/app-bridge.d.ts.map +1 -1
- package/dist/utils/app-bridge.js +56 -4
- package/dist/utils/app-bridge.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks/context.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface QumraAppBridgeProviderProps {
|
|
|
12
12
|
children: React.ReactNode;
|
|
13
13
|
/** Configuration for the AppBridge instance */
|
|
14
14
|
config: AppBridgeConfig;
|
|
15
|
+
/** Custom navigate handler. If not provided, uses built-in SPA navigation (pushState + popstate). */
|
|
16
|
+
navigate?: (url: string) => void;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Provider component for AppBridge
|
|
@@ -19,18 +21,18 @@ export interface QumraAppBridgeProviderProps {
|
|
|
19
21
|
*
|
|
20
22
|
* @example
|
|
21
23
|
* ```tsx
|
|
22
|
-
*
|
|
24
|
+
* // Works out of the box — built-in navigation
|
|
25
|
+
* <QumraAppBridgeProvider config={{ apiKey: 'your-api-key' }}>
|
|
26
|
+
* <YourApp />
|
|
27
|
+
* </QumraAppBridgeProvider>
|
|
23
28
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* </QumraAppBridgeProvider>
|
|
29
|
-
* );
|
|
30
|
-
* }
|
|
29
|
+
* // Or with a custom navigate handler
|
|
30
|
+
* <QumraAppBridgeProvider config={{ apiKey }} navigate={(url) => navigate(url)}>
|
|
31
|
+
* <YourApp />
|
|
32
|
+
* </QumraAppBridgeProvider>
|
|
31
33
|
* ```
|
|
32
34
|
*/
|
|
33
|
-
export declare function QumraAppBridgeProvider({ children, config, }: QumraAppBridgeProviderProps): JSX.Element;
|
|
35
|
+
export declare function QumraAppBridgeProvider({ children, config, navigate, }: QumraAppBridgeProviderProps): JSX.Element;
|
|
34
36
|
/**
|
|
35
37
|
* Internal hook to get the AppBridge context
|
|
36
38
|
* @internal
|
|
@@ -38,4 +40,9 @@ export declare function QumraAppBridgeProvider({ children, config, }: QumraAppBr
|
|
|
38
40
|
* @throws Error if used outside of QumraAppBridgeProvider
|
|
39
41
|
*/
|
|
40
42
|
export declare function useAppBridgeContext(): AppBridge;
|
|
43
|
+
/**
|
|
44
|
+
* Internal hook to get the app-level navigate handler
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export declare function useAppNavigate(): (url: string) => void;
|
|
41
48
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAoBzE;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+CAA+C;IAC/C,MAAM,EAAE,eAAe,CAAC;IACxB,qGAAqG;IACrG,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,QAAQ,GACT,EAAE,2BAA2B,GAAG,GAAG,CAAC,OAAO,CAwB3C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CAU/C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAGtD"}
|
package/dist/hooks/context.js
CHANGED
|
@@ -7,34 +7,49 @@ import React from 'react';
|
|
|
7
7
|
import { AppBridge } from '../utils/app-bridge.js';
|
|
8
8
|
/** React Context for AppBridge instance */
|
|
9
9
|
const AppBridgeContext = React.createContext(null);
|
|
10
|
+
/** App-level navigate handler */
|
|
11
|
+
const NavigateContext = React.createContext(null);
|
|
12
|
+
/**
|
|
13
|
+
* Built-in navigate that works with React Router and most SPA routers.
|
|
14
|
+
* Uses pushState + popstate event which routers listen to.
|
|
15
|
+
*/
|
|
16
|
+
function defaultNavigate(url) {
|
|
17
|
+
if (typeof window === 'undefined')
|
|
18
|
+
return;
|
|
19
|
+
window.history.pushState(null, '', url);
|
|
20
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
21
|
+
}
|
|
10
22
|
/**
|
|
11
23
|
* Provider component for AppBridge
|
|
12
24
|
* Must wrap your application to provide the AppBridge to all hooks
|
|
13
25
|
*
|
|
14
26
|
* @example
|
|
15
27
|
* ```tsx
|
|
16
|
-
*
|
|
28
|
+
* // Works out of the box — built-in navigation
|
|
29
|
+
* <QumraAppBridgeProvider config={{ apiKey: 'your-api-key' }}>
|
|
30
|
+
* <YourApp />
|
|
31
|
+
* </QumraAppBridgeProvider>
|
|
17
32
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* </QumraAppBridgeProvider>
|
|
23
|
-
* );
|
|
24
|
-
* }
|
|
33
|
+
* // Or with a custom navigate handler
|
|
34
|
+
* <QumraAppBridgeProvider config={{ apiKey }} navigate={(url) => navigate(url)}>
|
|
35
|
+
* <YourApp />
|
|
36
|
+
* </QumraAppBridgeProvider>
|
|
25
37
|
* ```
|
|
26
38
|
*/
|
|
27
|
-
export function QumraAppBridgeProvider({ children, config, }) {
|
|
39
|
+
export function QumraAppBridgeProvider({ children, config, navigate, }) {
|
|
28
40
|
const [bridge] = React.useState(() => new AppBridge(config));
|
|
41
|
+
const navigateRef = React.useRef(navigate ?? defaultNavigate);
|
|
42
|
+
navigateRef.current = navigate ?? defaultNavigate;
|
|
29
43
|
React.useEffect(() => {
|
|
30
|
-
|
|
44
|
+
bridge.setNavigateHandler((path) => {
|
|
45
|
+
navigateRef.current(path);
|
|
46
|
+
});
|
|
31
47
|
bridge.ready();
|
|
32
|
-
// Cleanup on unmount
|
|
33
48
|
return () => {
|
|
34
49
|
bridge.destroy();
|
|
35
50
|
};
|
|
36
51
|
}, [bridge]);
|
|
37
|
-
return (_jsx(AppBridgeContext.Provider, { value: bridge, children: children }));
|
|
52
|
+
return (_jsx(AppBridgeContext.Provider, { value: bridge, children: _jsx(NavigateContext.Provider, { value: navigateRef, children: children }) }));
|
|
38
53
|
}
|
|
39
54
|
/**
|
|
40
55
|
* Internal hook to get the AppBridge context
|
|
@@ -49,4 +64,12 @@ export function useAppBridgeContext() {
|
|
|
49
64
|
}
|
|
50
65
|
return context;
|
|
51
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Internal hook to get the app-level navigate handler
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export function useAppNavigate() {
|
|
72
|
+
const ref = React.useContext(NavigateContext);
|
|
73
|
+
return ref?.current ?? defaultNavigate;
|
|
74
|
+
}
|
|
52
75
|
//# sourceMappingURL=context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAwB,MAAM,wBAAwB,CAAC;AAEzE,2CAA2C;AAC3C,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAmB,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAwB,MAAM,wBAAwB,CAAC;AAEzE,2CAA2C;AAC3C,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAmB,IAAI,CAAC,CAAC;AAErE,iCAAiC;AACjC,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAEzC,IAAI,CAAC,CAAC;AAER;;;GAGG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;AACtD,CAAC;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,QAAQ,GACoB;IAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,eAAe,CAAC,CAAC;IAC9D,WAAW,CAAC,OAAO,GAAG,QAAQ,IAAI,eAAe,CAAC;IAElD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,EAAE;YACjC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,CACL,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YACtC,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,WAAW,YACzC,QAAQ,GACgB,GACD,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAC9C,OAAO,GAAG,EAAE,OAAO,IAAI,eAAe,CAAC;AACzC,CAAC"}
|
package/dist/hooks/useModal.d.ts
CHANGED
|
@@ -2,45 +2,44 @@
|
|
|
2
2
|
* Hook for managing modal dialogs
|
|
3
3
|
*/
|
|
4
4
|
import type { ModalOptions } from '../utils/actions.js';
|
|
5
|
+
/**
|
|
6
|
+
* Options for modal.show() — modal config + event callbacks
|
|
7
|
+
*/
|
|
8
|
+
export interface ModalShowOptions extends ModalOptions {
|
|
9
|
+
/** Called when the user clicks the primary action */
|
|
10
|
+
onConfirm?: () => void | Promise<void>;
|
|
11
|
+
/** Called when the user clicks the secondary action or dismisses the modal */
|
|
12
|
+
onCancel?: () => void;
|
|
13
|
+
}
|
|
5
14
|
/**
|
|
6
15
|
* Modal utility functions
|
|
7
16
|
*/
|
|
8
17
|
export interface UseModalResult {
|
|
9
|
-
/**
|
|
10
|
-
|
|
18
|
+
/** Show a modal dialog */
|
|
19
|
+
show: (options: ModalShowOptions) => void;
|
|
11
20
|
/** Close the current modal */
|
|
12
|
-
|
|
21
|
+
hide: () => void;
|
|
13
22
|
}
|
|
14
23
|
/**
|
|
15
24
|
* Hook to manage modal dialogs
|
|
16
25
|
*
|
|
17
26
|
* @example
|
|
18
27
|
* ```tsx
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* export function MyComponent() {
|
|
22
|
-
* const modal = useModal();
|
|
23
|
-
*
|
|
24
|
-
* const handleOpenSettings = () => {
|
|
25
|
-
* modal.open({
|
|
26
|
-
* title: 'Settings',
|
|
27
|
-
* url: '/settings',
|
|
28
|
-
* size: 'large',
|
|
29
|
-
* primaryAction: {
|
|
30
|
-
* content: 'Save',
|
|
31
|
-
* onAction: () => {
|
|
32
|
-
* // Handle save
|
|
33
|
-
* modal.close();
|
|
34
|
-
* }
|
|
35
|
-
* }
|
|
36
|
-
* });
|
|
37
|
-
* };
|
|
28
|
+
* const modal = useModal();
|
|
38
29
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
30
|
+
* modal.show({
|
|
31
|
+
* title: 'حذف المنتج؟',
|
|
32
|
+
* message: 'هذا الإجراء لا يمكن التراجع عنه',
|
|
33
|
+
* primaryAction: { label: 'حذف', variant: 'destructive' },
|
|
34
|
+
* secondaryAction: { label: 'إلغاء' },
|
|
35
|
+
* onConfirm: async () => {
|
|
36
|
+
* await deleteProduct();
|
|
37
|
+
* modal.hide();
|
|
38
|
+
* },
|
|
39
|
+
* });
|
|
41
40
|
* ```
|
|
42
41
|
*
|
|
43
|
-
* @returns Object with
|
|
42
|
+
* @returns Object with show and hide methods
|
|
44
43
|
*/
|
|
45
44
|
export declare function useModal(): UseModalResult;
|
|
46
45
|
//# sourceMappingURL=useModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModal.d.ts","sourceRoot":"","sources":["../../src/hooks/useModal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"useModal.d.ts","sourceRoot":"","sources":["../../src/hooks/useModal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC1C,8BAA8B;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAyCzC"}
|
package/dist/hooks/useModal.js
CHANGED
|
@@ -1,48 +1,55 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Hook for managing modal dialogs
|
|
3
3
|
*/
|
|
4
|
-
import { useCallback } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
5
5
|
import { useAppBridge } from './useAppBridge.js';
|
|
6
|
-
import { openModal, closeModal } from '../utils/actions.js';
|
|
6
|
+
import { ActionType, openModal, closeModal } from '../utils/actions.js';
|
|
7
7
|
/**
|
|
8
8
|
* Hook to manage modal dialogs
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```tsx
|
|
12
|
-
*
|
|
12
|
+
* const modal = useModal();
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* onAction: () => {
|
|
25
|
-
* // Handle save
|
|
26
|
-
* modal.close();
|
|
27
|
-
* }
|
|
28
|
-
* }
|
|
29
|
-
* });
|
|
30
|
-
* };
|
|
31
|
-
*
|
|
32
|
-
* return <button onClick={handleOpenSettings}>Open Settings</button>;
|
|
33
|
-
* }
|
|
14
|
+
* modal.show({
|
|
15
|
+
* title: 'حذف المنتج؟',
|
|
16
|
+
* message: 'هذا الإجراء لا يمكن التراجع عنه',
|
|
17
|
+
* primaryAction: { label: 'حذف', variant: 'destructive' },
|
|
18
|
+
* secondaryAction: { label: 'إلغاء' },
|
|
19
|
+
* onConfirm: async () => {
|
|
20
|
+
* await deleteProduct();
|
|
21
|
+
* modal.hide();
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
34
24
|
* ```
|
|
35
25
|
*
|
|
36
|
-
* @returns Object with
|
|
26
|
+
* @returns Object with show and hide methods
|
|
37
27
|
*/
|
|
38
28
|
export function useModal() {
|
|
39
29
|
const bridge = useAppBridge();
|
|
40
|
-
const
|
|
41
|
-
|
|
30
|
+
const optionsRef = useRef();
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const unsubConfirm = bridge.subscribe(ActionType.MODAL_CONFIRM, () => {
|
|
33
|
+
optionsRef.current?.onConfirm?.();
|
|
34
|
+
});
|
|
35
|
+
const unsubCancel = bridge.subscribe(ActionType.MODAL_CANCEL, () => {
|
|
36
|
+
optionsRef.current?.onCancel?.();
|
|
37
|
+
optionsRef.current = undefined;
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
unsubConfirm();
|
|
41
|
+
unsubCancel();
|
|
42
|
+
};
|
|
43
|
+
}, [bridge]);
|
|
44
|
+
const show = useCallback((options) => {
|
|
45
|
+
optionsRef.current = options;
|
|
46
|
+
const { onConfirm, onCancel, ...modalOptions } = options;
|
|
47
|
+
bridge.dispatch(openModal(modalOptions));
|
|
42
48
|
}, [bridge]);
|
|
43
|
-
const
|
|
49
|
+
const hide = useCallback(() => {
|
|
50
|
+
optionsRef.current = undefined;
|
|
44
51
|
bridge.dispatch(closeModal());
|
|
45
52
|
}, [bridge]);
|
|
46
|
-
return {
|
|
53
|
+
return { show, hide };
|
|
47
54
|
}
|
|
48
55
|
//# sourceMappingURL=useModal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModal.js","sourceRoot":"","sources":["../../src/hooks/useModal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useModal.js","sourceRoot":"","sources":["../../src/hooks/useModal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAuBxE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,MAAM,EAAoB,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CACnC,UAAU,CAAC,aAAa,EACxB,GAAG,EAAE;YACH,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;QACpC,CAAC,CACF,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAClC,UAAU,CAAC,YAAY,EACvB,GAAG,EAAE;YACH,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC;YACjC,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;QACjC,CAAC,CACF,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,IAAI,GAAG,WAAW,CACtB,CAAC,OAAyB,EAAE,EAAE;QAC5B,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAC7B,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;QACzD,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3C,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;QAC/B,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAChC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for managing the navigation menu in the Qumra Admin host.
|
|
3
|
+
*/
|
|
4
|
+
import type { NavigationMenuItem } from '../utils/actions.js';
|
|
5
|
+
/**
|
|
6
|
+
* Partial update for a navigation menu item (url cannot be changed)
|
|
7
|
+
*/
|
|
8
|
+
export type NavigationMenuItemUpdate = Partial<Omit<NavigationMenuItem, 'url'>>;
|
|
9
|
+
/**
|
|
10
|
+
* Navigation menu utility functions
|
|
11
|
+
*/
|
|
12
|
+
export interface UseNavigationMenuResult {
|
|
13
|
+
/** Current navigation pages */
|
|
14
|
+
readonly pages: NavigationMenuItem[];
|
|
15
|
+
/** Replace all navigation pages */
|
|
16
|
+
set: (pages: NavigationMenuItem[]) => void;
|
|
17
|
+
/** Add a navigation item. If an item with the same url exists, it will be updated */
|
|
18
|
+
add: (item: NavigationMenuItem) => void;
|
|
19
|
+
/** Remove a navigation item by url */
|
|
20
|
+
remove: (url: string) => void;
|
|
21
|
+
/** Update properties of a single item by url */
|
|
22
|
+
update: (url: string, partial: NavigationMenuItemUpdate) => void;
|
|
23
|
+
/** Tell the host which page is currently active */
|
|
24
|
+
setActive: (path: string) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Hook to manage the navigation menu shown in the Qumra Admin host.
|
|
28
|
+
*
|
|
29
|
+
* The returned object is **stable** — safe to use in useEffect dependencies
|
|
30
|
+
* without causing infinite loops.
|
|
31
|
+
*
|
|
32
|
+
* Navigation events from the host (HOST::NAVIGATION::NAVIGATE) are handled
|
|
33
|
+
* at the Provider level, so they work even when components unmount/remount.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* function App() {
|
|
38
|
+
* const navigation = useNavigationMenu();
|
|
39
|
+
*
|
|
40
|
+
* useEffect(() => {
|
|
41
|
+
* navigation.set([
|
|
42
|
+
* { label: 'الرئيسية', url: '/', icon: 'home' },
|
|
43
|
+
* { label: 'الطلبات', url: '/orders', icon: 'orders', badge: 3 },
|
|
44
|
+
* ]);
|
|
45
|
+
* }, [navigation]); // safe — navigation is stable
|
|
46
|
+
*
|
|
47
|
+
* // Update badge dynamically
|
|
48
|
+
* navigation.update('/orders', { badge: 5 });
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @returns Stable object with navigation management methods
|
|
53
|
+
*/
|
|
54
|
+
export declare function useNavigationMenu(): UseNavigationMenuResult;
|
|
55
|
+
//# sourceMappingURL=useNavigationMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNavigationMenu.d.ts","sourceRoot":"","sources":["../../src/hooks/useNavigationMenu.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IACrC,mCAAmC;IACnC,GAAG,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;IAC3C,qFAAqF;IACrF,GAAG,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACxC,sCAAsC;IACtC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,gDAAgD;IAChD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACjE,mDAAmD;IACnD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,IAAI,uBAAuB,CA+E3D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for managing the navigation menu in the Qumra Admin host.
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
5
|
+
import { useAppBridge } from './useAppBridge.js';
|
|
6
|
+
import { ActionType } from '../utils/actions.js';
|
|
7
|
+
/**
|
|
8
|
+
* Hook to manage the navigation menu shown in the Qumra Admin host.
|
|
9
|
+
*
|
|
10
|
+
* The returned object is **stable** — safe to use in useEffect dependencies
|
|
11
|
+
* without causing infinite loops.
|
|
12
|
+
*
|
|
13
|
+
* Navigation events from the host (HOST::NAVIGATION::NAVIGATE) are handled
|
|
14
|
+
* at the Provider level, so they work even when components unmount/remount.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* function App() {
|
|
19
|
+
* const navigation = useNavigationMenu();
|
|
20
|
+
*
|
|
21
|
+
* useEffect(() => {
|
|
22
|
+
* navigation.set([
|
|
23
|
+
* { label: 'الرئيسية', url: '/', icon: 'home' },
|
|
24
|
+
* { label: 'الطلبات', url: '/orders', icon: 'orders', badge: 3 },
|
|
25
|
+
* ]);
|
|
26
|
+
* }, [navigation]); // safe — navigation is stable
|
|
27
|
+
*
|
|
28
|
+
* // Update badge dynamically
|
|
29
|
+
* navigation.update('/orders', { badge: 5 });
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @returns Stable object with navigation management methods
|
|
34
|
+
*/
|
|
35
|
+
export function useNavigationMenu() {
|
|
36
|
+
const bridge = useAppBridge();
|
|
37
|
+
const pagesRef = useRef([]);
|
|
38
|
+
// Dispatch the full pages list to the host and update the ref
|
|
39
|
+
const dispatchPages = useCallback((nextPages) => {
|
|
40
|
+
pagesRef.current = nextPages;
|
|
41
|
+
bridge.dispatch({
|
|
42
|
+
type: ActionType.NAVIGATION_UPDATE,
|
|
43
|
+
payload: { pages: nextPages },
|
|
44
|
+
});
|
|
45
|
+
}, [bridge]);
|
|
46
|
+
const set = useCallback((nextPages) => {
|
|
47
|
+
dispatchPages(nextPages);
|
|
48
|
+
}, [dispatchPages]);
|
|
49
|
+
const add = useCallback((item) => {
|
|
50
|
+
const current = pagesRef.current;
|
|
51
|
+
const index = current.findIndex((i) => i.url === item.url);
|
|
52
|
+
const nextPages = index >= 0
|
|
53
|
+
? current.map((i) => (i.url === item.url ? { ...i, ...item } : i))
|
|
54
|
+
: [...current, item];
|
|
55
|
+
dispatchPages(nextPages);
|
|
56
|
+
}, [dispatchPages]);
|
|
57
|
+
const remove = useCallback((url) => {
|
|
58
|
+
dispatchPages(pagesRef.current.filter((i) => i.url !== url));
|
|
59
|
+
}, [dispatchPages]);
|
|
60
|
+
const update = useCallback((url, partial) => {
|
|
61
|
+
dispatchPages(pagesRef.current.map((i) => i.url === url ? { ...i, ...partial } : i));
|
|
62
|
+
}, [dispatchPages]);
|
|
63
|
+
const setActive = useCallback((path) => {
|
|
64
|
+
bridge.dispatch({
|
|
65
|
+
type: ActionType.NAVIGATION_SET_ACTIVE,
|
|
66
|
+
payload: { path },
|
|
67
|
+
});
|
|
68
|
+
}, [bridge]);
|
|
69
|
+
// Stable object — all deps are stable (bridge never changes)
|
|
70
|
+
return useMemo(() => ({
|
|
71
|
+
get pages() {
|
|
72
|
+
return pagesRef.current;
|
|
73
|
+
},
|
|
74
|
+
set,
|
|
75
|
+
add,
|
|
76
|
+
remove,
|
|
77
|
+
update,
|
|
78
|
+
setActive,
|
|
79
|
+
}), [set, add, remove, update, setActive]);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=useNavigationMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNavigationMenu.js","sourceRoot":"","sources":["../../src/hooks/useNavigationMenu.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Hook for managing the save bar (unsaved changes indicator)
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Helpers passed to onSave for manual control over save result
|
|
6
|
+
*/
|
|
7
|
+
export interface SaveBarHelpers {
|
|
8
|
+
/** Signal that the save completed successfully */
|
|
9
|
+
complete: () => void;
|
|
10
|
+
/** Signal that the save failed */
|
|
11
|
+
error: (message?: string) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options passed to saveBar.show()
|
|
15
|
+
*/
|
|
16
|
+
export interface SaveBarShowOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Callback when the save button is clicked.
|
|
19
|
+
*
|
|
20
|
+
* Receives `{ complete, error }` helpers for manual control.
|
|
21
|
+
* - If you call `complete()` or `error()`, you control the result.
|
|
22
|
+
* - If you don't call either, the hook auto-dispatches based on the promise:
|
|
23
|
+
* resolves → SAVE_COMPLETE, throws → SAVE_ERROR.
|
|
24
|
+
*/
|
|
25
|
+
onSave?: (helpers: SaveBarHelpers) => void | Promise<void>;
|
|
26
|
+
/** Callback when the discard button is clicked */
|
|
27
|
+
onDiscard?: () => void;
|
|
28
|
+
}
|
|
5
29
|
/**
|
|
6
30
|
* Save bar utility functions
|
|
7
31
|
*/
|
|
8
32
|
export interface UseSaveBarResult {
|
|
9
33
|
/** Show the save bar */
|
|
10
|
-
show: (options?:
|
|
34
|
+
show: (options?: SaveBarShowOptions) => void;
|
|
11
35
|
/** Hide the save bar */
|
|
12
36
|
hide: () => void;
|
|
13
37
|
}
|
|
@@ -15,31 +39,31 @@ export interface UseSaveBarResult {
|
|
|
15
39
|
* Hook to manage the save bar for indicating unsaved changes
|
|
16
40
|
*
|
|
17
41
|
* @example
|
|
42
|
+
* Simple (auto mode):
|
|
18
43
|
* ```tsx
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* export function MyComponent() {
|
|
22
|
-
* const saveBar = useSaveBar();
|
|
23
|
-
* const [hasChanges, setHasChanges] = React.useState(false);
|
|
24
|
-
*
|
|
25
|
-
* const handleChange = () => {
|
|
26
|
-
* setHasChanges(true);
|
|
27
|
-
* saveBar.show();
|
|
28
|
-
* };
|
|
29
|
-
*
|
|
30
|
-
* const handleSave = async () => {
|
|
44
|
+
* saveBar.show({
|
|
45
|
+
* onSave: async () => {
|
|
31
46
|
* await saveData();
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
47
|
+
* // resolves → SAVE_COMPLETE, throws → SAVE_ERROR
|
|
48
|
+
* },
|
|
49
|
+
* onDiscard: () => resetForm(),
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
35
52
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
53
|
+
* @example
|
|
54
|
+
* Dynamic (manual control):
|
|
55
|
+
* ```tsx
|
|
56
|
+
* saveBar.show({
|
|
57
|
+
* onSave: async ({ complete, error }) => {
|
|
58
|
+
* const res = await fetch('/api/save', { method: 'POST' });
|
|
59
|
+
* if (res.ok) {
|
|
60
|
+
* complete();
|
|
61
|
+
* } else {
|
|
62
|
+
* error('فشل الحفظ');
|
|
63
|
+
* }
|
|
64
|
+
* },
|
|
65
|
+
* onDiscard: () => resetForm(),
|
|
66
|
+
* });
|
|
43
67
|
* ```
|
|
44
68
|
*
|
|
45
69
|
* @returns Object with show and hide methods
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSaveBar.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveBar.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"useSaveBar.d.ts","sourceRoot":"","sources":["../../src/hooks/useSaveBar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,kCAAkC;IAClC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC7C,wBAAwB;IACxB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CAqE7C"}
|
package/dist/hooks/useSaveBar.js
CHANGED
|
@@ -1,48 +1,96 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Hook for managing the save bar (unsaved changes indicator)
|
|
3
3
|
*/
|
|
4
|
-
import { useCallback } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
5
5
|
import { useAppBridge } from './useAppBridge.js';
|
|
6
|
-
import { showSaveBar, hideSaveBar } from '../utils/actions.js';
|
|
6
|
+
import { showSaveBar, hideSaveBar, ActionType } from '../utils/actions.js';
|
|
7
7
|
/**
|
|
8
8
|
* Hook to manage the save bar for indicating unsaved changes
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
|
+
* Simple (auto mode):
|
|
11
12
|
* ```tsx
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* export function MyComponent() {
|
|
15
|
-
* const saveBar = useSaveBar();
|
|
16
|
-
* const [hasChanges, setHasChanges] = React.useState(false);
|
|
17
|
-
*
|
|
18
|
-
* const handleChange = () => {
|
|
19
|
-
* setHasChanges(true);
|
|
20
|
-
* saveBar.show();
|
|
21
|
-
* };
|
|
22
|
-
*
|
|
23
|
-
* const handleSave = async () => {
|
|
13
|
+
* saveBar.show({
|
|
14
|
+
* onSave: async () => {
|
|
24
15
|
* await saveData();
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
16
|
+
* // resolves → SAVE_COMPLETE, throws → SAVE_ERROR
|
|
17
|
+
* },
|
|
18
|
+
* onDiscard: () => resetForm(),
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
28
21
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
22
|
+
* @example
|
|
23
|
+
* Dynamic (manual control):
|
|
24
|
+
* ```tsx
|
|
25
|
+
* saveBar.show({
|
|
26
|
+
* onSave: async ({ complete, error }) => {
|
|
27
|
+
* const res = await fetch('/api/save', { method: 'POST' });
|
|
28
|
+
* if (res.ok) {
|
|
29
|
+
* complete();
|
|
30
|
+
* } else {
|
|
31
|
+
* error('فشل الحفظ');
|
|
32
|
+
* }
|
|
33
|
+
* },
|
|
34
|
+
* onDiscard: () => resetForm(),
|
|
35
|
+
* });
|
|
36
36
|
* ```
|
|
37
37
|
*
|
|
38
38
|
* @returns Object with show and hide methods
|
|
39
39
|
*/
|
|
40
40
|
export function useSaveBar() {
|
|
41
41
|
const bridge = useAppBridge();
|
|
42
|
+
const optionsRef = useRef();
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const unsubSave = bridge.subscribe(ActionType.SAVE_BAR_SAVE, async () => {
|
|
45
|
+
const onSave = optionsRef.current?.onSave;
|
|
46
|
+
if (!onSave)
|
|
47
|
+
return;
|
|
48
|
+
let handled = false;
|
|
49
|
+
const dispatchComplete = () => {
|
|
50
|
+
bridge.dispatch({ type: ActionType.SAVE_BAR_SAVE_COMPLETE });
|
|
51
|
+
};
|
|
52
|
+
const dispatchError = (message) => {
|
|
53
|
+
bridge.dispatch({
|
|
54
|
+
type: ActionType.SAVE_BAR_SAVE_ERROR,
|
|
55
|
+
payload: { message },
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const helpers = {
|
|
59
|
+
complete: () => {
|
|
60
|
+
handled = true;
|
|
61
|
+
dispatchComplete();
|
|
62
|
+
},
|
|
63
|
+
error: (message) => {
|
|
64
|
+
handled = true;
|
|
65
|
+
dispatchError(message ?? 'Save failed');
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
await onSave(helpers);
|
|
70
|
+
if (!handled) {
|
|
71
|
+
dispatchComplete();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
if (!handled) {
|
|
76
|
+
dispatchError(err instanceof Error ? err.message : 'Save failed');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const unsubDiscard = bridge.subscribe(ActionType.SAVE_BAR_DISCARD, () => {
|
|
81
|
+
optionsRef.current?.onDiscard?.();
|
|
82
|
+
});
|
|
83
|
+
return () => {
|
|
84
|
+
unsubSave();
|
|
85
|
+
unsubDiscard();
|
|
86
|
+
};
|
|
87
|
+
}, [bridge]);
|
|
42
88
|
const show = useCallback((options) => {
|
|
43
|
-
|
|
89
|
+
optionsRef.current = options;
|
|
90
|
+
bridge.dispatch(showSaveBar());
|
|
44
91
|
}, [bridge]);
|
|
45
92
|
const hide = useCallback(() => {
|
|
93
|
+
optionsRef.current = undefined;
|
|
46
94
|
bridge.dispatch(hideSaveBar());
|
|
47
95
|
}, [bridge]);
|
|
48
96
|
return { show, hide };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSaveBar.js","sourceRoot":"","sources":["../../src/hooks/useSaveBar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useSaveBar.js","sourceRoot":"","sources":["../../src/hooks/useSaveBar.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/useToast.js
CHANGED
|
@@ -34,7 +34,7 @@ export function useToast() {
|
|
|
34
34
|
const show = useCallback((options) => {
|
|
35
35
|
bridge.dispatch(showToast(options.message, {
|
|
36
36
|
duration: options.duration,
|
|
37
|
-
|
|
37
|
+
variant: options.variant,
|
|
38
38
|
}));
|
|
39
39
|
}, [bridge]);
|
|
40
40
|
const hide = useCallback(() => {
|
package/dist/index.d.ts
CHANGED
|
@@ -45,15 +45,17 @@ export { useNavigate } from './hooks/useNavigate.js';
|
|
|
45
45
|
export { useToast } from './hooks/useToast.js';
|
|
46
46
|
export type { UseToastResult } from './hooks/useToast.js';
|
|
47
47
|
export { useModal } from './hooks/useModal.js';
|
|
48
|
-
export type { UseModalResult } from './hooks/useModal.js';
|
|
48
|
+
export type { UseModalResult, ModalShowOptions } from './hooks/useModal.js';
|
|
49
49
|
export { useAuthenticatedFetch } from './hooks/useAuthenticatedFetch.js';
|
|
50
50
|
export { useSaveBar } from './hooks/useSaveBar.js';
|
|
51
|
-
export type { UseSaveBarResult } from './hooks/useSaveBar.js';
|
|
51
|
+
export type { UseSaveBarResult, SaveBarShowOptions, SaveBarHelpers } from './hooks/useSaveBar.js';
|
|
52
52
|
export { useFullscreen } from './hooks/useFullscreen.js';
|
|
53
53
|
export type { UseFullscreenResult } from './hooks/useFullscreen.js';
|
|
54
54
|
export { useTitleBar } from './hooks/useTitleBar.js';
|
|
55
55
|
export type { UseTitleBarResult } from './hooks/useTitleBar.js';
|
|
56
|
+
export { useNavigationMenu } from './hooks/useNavigationMenu.js';
|
|
57
|
+
export type { UseNavigationMenuResult, NavigationMenuItemUpdate, } from './hooks/useNavigationMenu.js';
|
|
56
58
|
export { ActionType } from './utils/actions.js';
|
|
57
|
-
export type { NavigateOptions, ToastOptions, ModalOptions, SaveBarOptions, TitleBarOptions } from './utils/actions.js';
|
|
59
|
+
export type { NavigateOptions, ToastOptions, ModalOptions, SaveBarOptions, TitleBarOptions, NavigationMenuItem } from './utils/actions.js';
|
|
58
60
|
export { navigate, showToast, hideToast, openModal, closeModal, showSaveBar, hideSaveBar, updateTitleBar, startLoading, stopLoading, enterFullscreen, exitFullscreen, } from './utils/actions.js';
|
|
59
61
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EACV,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3I,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ export { useAuthenticatedFetch } from './hooks/useAuthenticatedFetch.js';
|
|
|
49
49
|
export { useSaveBar } from './hooks/useSaveBar.js';
|
|
50
50
|
export { useFullscreen } from './hooks/useFullscreen.js';
|
|
51
51
|
export { useTitleBar } from './hooks/useTitleBar.js';
|
|
52
|
+
export { useNavigationMenu } from './hooks/useNavigationMenu.js';
|
|
52
53
|
// Action exports
|
|
53
54
|
export { ActionType } from './utils/actions.js';
|
|
54
55
|
export { navigate, showToast, hideToast, openModal, closeModal, showSaveBar, hideSaveBar, updateTitleBar, startLoading, stopLoading, enterFullscreen, exitFullscreen, } from './utils/actions.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,yBAAyB;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAQlD,mBAAmB;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,yBAAyB;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAQlD,mBAAmB;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAMjE,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(()=>{var i={NAVIGATE:"APP::NAVIGATE",TOAST_SHOW:"APP::TOAST::SHOW",TOAST_HIDE:"APP::TOAST::HIDE",MODAL_OPEN:"APP::MODAL::SHOW",MODAL_CLOSE:"APP::MODAL::HIDE",MODAL_TOGGLE:"APP::MODAL::TOGGLE",SAVE_BAR_SHOW:"APP::SAVE_BAR::SHOW",SAVE_BAR_HIDE:"APP::SAVE_BAR::HIDE",SAVE_BAR_TOGGLE:"APP::SAVE_BAR::TOGGLE",SAVE_BAR_UPDATE:"APP::SAVE_BAR::UPDATE",TITLE_BAR_UPDATE:"APP::TITLE_BAR::UPDATE",LOADING_START:"APP::LOADING::START",LOADING_STOP:"APP::LOADING::STOP",READY:"APP::READY",FULLSCREEN_ENTER:"APP::FULLSCREEN::ENTER",FULLSCREEN_EXIT:"APP::FULLSCREEN::EXIT"},g={CONTEXT_UPDATE:"HOST::CONTEXT::UPDATE",LOADING_START:"HOST::LOADING::START",LOADING_STOP:"HOST::LOADING::STOP",SAVE_BAR_SAVE:"HOST::SAVE_BAR::SAVE",SAVE_BAR_DISCARD:"HOST::SAVE_BAR::DISCARD",MODAL_CLOSE:"HOST::MODAL::CLOSE"};function m(e){let o=0;return{show(t,a){let r=`toast-${++o}`;return e({type:i.TOAST_SHOW,payload:{id:r,message:t,duration:a?.duration??5e3,isError:a?.isError??!1,action:a?.action}}),r},hide(t){e({type:i.TOAST_HIDE,payload:{id:t}})}}}function T(e){return{show(o){e({type:i.MODAL_OPEN,payload:{id:o}})},hide(o){e({type:i.MODAL_CLOSE,payload:{id:o}})},toggle(o){e({type:i.MODAL_TOGGLE,payload:{id:o}})}}}function y(e){return(o,t)=>{e({type:i.NAVIGATE,payload:{url:o,external:t?.external??!1}})}}function E(e){return{show(o){e({type:i.SAVE_BAR_SHOW,payload:{id:o}})},hide(o){e({type:i.SAVE_BAR_HIDE,payload:{id:o}})},toggle(o){e({type:i.SAVE_BAR_TOGGLE,payload:{id:o}})}}}function f(e){return{update(o){e({type:i.TITLE_BAR_UPDATE,payload:{title:o.title,subtitle:o.subtitle,breadcrumbs:o.breadcrumbs}})}}}function B(e){return{enter(){e({type:i.FULLSCREEN_ENTER})},exit(){e({type:i.FULLSCREEN_EXIT})}}}function S(e){return o=>{e({type:o?i.LOADING_START:i.LOADING_STOP})}}function O(e){return async(o,t)=>{let r=e().context?.sessionToken,s=new Headers(t?.headers||{});return r&&s.set("Authorization",`Bearer ${r}`),fetch(o,{...t,headers:s})}}function p(e){let o={apiKey:e.apiKey,host:e.host||"https://app.qumra.cloud"},t={loading:!1,context:null},a=new Map,r=!1;function s(n){window.parent.postMessage({type:n.type,payload:n.payload,apiKey:o.apiKey},o.host)}function c(n,d){return a.has(n)||a.set(n,new Set),a.get(n).add(d),()=>{a.get(n).delete(d),a.get(n).size===0&&a.delete(n)}}function P(n,d){let A=a.get(n);A&&A.forEach(u=>{try{u(d)}catch(_){console.error(`[qumra] Error in subscriber for ${n}:`,_)}})}function l(n){let d=new URL(o.host);if(n.origin!==d.origin)return;let{type:A,payload:u}=n.data;A&&(A===g.CONTEXT_UPDATE?t.context=u:A===g.LOADING_START?t.loading=!0:A===g.LOADING_STOP&&(t.loading=!1),P(A,u))}return window.addEventListener("message",l),{get config(){return{...o}},get context(){return t.context},navigate:y(s),toast:m(s),modal:T(s),saveBar:E(s),titleBar:f(s),fullscreen:B(s),loading:S(s),fetch:O(()=>({...t})),dispatch:s,subscribe:c,getState:()=>({...t}),ready(){r||(r=!0,s({type:i.READY,payload:{apiKey:o.apiKey}}))},destroy(){window.removeEventListener("message",l),a.clear()},init(n){o.apiKey=n.apiKey,o.host=n.host||o.host}}}(function(){if(window.qumra)return;let o=document.querySelector('meta[name="qumra-api-key"]'),t=document.querySelector('meta[name="qumra-host"]');if(!o){window.qumra=L();return}let a={apiKey:o.getAttribute("content"),host:t?.getAttribute("content")||void 0};window.qumra=p(a),window.qumra.ready()})();function L(){let e=null,o='[qumra] Bridge not initialized. Add <meta name="qumra-api-key" content="..."> before the script tag, or call qumra.init({ apiKey: "..." }).';function t(){if(!e)throw new Error(o)}return{get config(){return t(),e.config},get context(){return t(),e.context},navigate(...r){return t(),e.navigate(...r)},toast:{show(...r){return t(),e.toast.show(...r)},hide(...r){return t(),e.toast.hide(...r)}},modal:{show(...r){return t(),e.modal.show(...r)},hide(...r){return t(),e.modal.hide(...r)},toggle(...r){return t(),e.modal.toggle(...r)}},saveBar:{show(...r){return t(),e.saveBar.show(...r)},hide(...r){return t(),e.saveBar.hide(...r)},toggle(...r){return t(),e.saveBar.toggle(...r)}},titleBar:{update(...r){return t(),e.titleBar.update(...r)}},fullscreen:{enter(){return t(),e.fullscreen.enter()},exit(){return t(),e.fullscreen.exit()}},loading(r){return t(),e.loading(r)},fetch(...r){return t(),e.fetch(...r)},dispatch(...r){return t(),e.dispatch(...r)},subscribe(...r){return t(),e.subscribe(...r)},getState(){return t(),e.getState()},ready(){return t(),e.ready()},destroy(){return t(),e.destroy()},init(r){e=p(r);let s=window.qumra;Object.keys(e).forEach(c=>{c!=="init"&&(s[c]=e[c])}),e.ready()}}}})();
|
|
2
|
+
//# sourceMappingURL=jisr.global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/actions.ts","../src/api/toast.ts","../src/api/modal.ts","../src/api/navigate.ts","../src/api/save-bar.ts","../src/api/title-bar.ts","../src/api/fullscreen.ts","../src/api/loading.ts","../src/api/fetch.ts","../src/core/bridge.ts","../src/cdn-entry.ts"],"sourcesContent":["/** Action type constants for host communication */\nexport const ActionType = {\n NAVIGATE: 'APP::NAVIGATE',\n TOAST_SHOW: 'APP::TOAST::SHOW',\n TOAST_HIDE: 'APP::TOAST::HIDE',\n MODAL_OPEN: 'APP::MODAL::SHOW',\n MODAL_CLOSE: 'APP::MODAL::HIDE',\n MODAL_TOGGLE: 'APP::MODAL::TOGGLE',\n SAVE_BAR_SHOW: 'APP::SAVE_BAR::SHOW',\n SAVE_BAR_HIDE: 'APP::SAVE_BAR::HIDE',\n SAVE_BAR_TOGGLE: 'APP::SAVE_BAR::TOGGLE',\n SAVE_BAR_UPDATE: 'APP::SAVE_BAR::UPDATE',\n TITLE_BAR_UPDATE: 'APP::TITLE_BAR::UPDATE',\n LOADING_START: 'APP::LOADING::START',\n LOADING_STOP: 'APP::LOADING::STOP',\n READY: 'APP::READY',\n FULLSCREEN_ENTER: 'APP::FULLSCREEN::ENTER',\n FULLSCREEN_EXIT: 'APP::FULLSCREEN::EXIT',\n} as const;\n\n/** Host event type constants */\nexport const HostEventType = {\n CONTEXT_UPDATE: 'HOST::CONTEXT::UPDATE',\n LOADING_START: 'HOST::LOADING::START',\n LOADING_STOP: 'HOST::LOADING::STOP',\n SAVE_BAR_SAVE: 'HOST::SAVE_BAR::SAVE',\n SAVE_BAR_DISCARD: 'HOST::SAVE_BAR::DISCARD',\n MODAL_CLOSE: 'HOST::MODAL::CLOSE',\n} as const;\n","import { ActionType } from '../core/actions.js';\nimport type { ToastAPI, ToastOptions, BridgeAction } from '../core/types.js';\n\nexport function createToastAPI(\n dispatch: (action: BridgeAction) => void\n): ToastAPI {\n let counter = 0;\n\n return {\n show(message: string, options?: ToastOptions): string {\n const id = `toast-${++counter}`;\n dispatch({\n type: ActionType.TOAST_SHOW,\n payload: {\n id,\n message,\n duration: options?.duration ?? 5000,\n isError: options?.isError ?? false,\n action: options?.action,\n },\n });\n return id;\n },\n hide(id: string) {\n dispatch({ type: ActionType.TOAST_HIDE, payload: { id } });\n },\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { ModalAPI, BridgeAction } from '../core/types.js';\n\nexport function createModalAPI(\n dispatch: (action: BridgeAction) => void\n): ModalAPI {\n return {\n show(id: string) {\n dispatch({ type: ActionType.MODAL_OPEN, payload: { id } });\n },\n hide(id: string) {\n dispatch({ type: ActionType.MODAL_CLOSE, payload: { id } });\n },\n toggle(id: string) {\n dispatch({ type: ActionType.MODAL_TOGGLE, payload: { id } });\n },\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { NavigateOptions, BridgeAction } from '../core/types.js';\n\nexport function createNavigate(\n dispatch: (action: BridgeAction) => void\n): (url: string, options?: NavigateOptions) => void {\n return (url: string, options?: NavigateOptions) => {\n dispatch({\n type: ActionType.NAVIGATE,\n payload: {\n url,\n external: options?.external ?? false,\n },\n });\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { SaveBarAPI, BridgeAction } from '../core/types.js';\n\nexport function createSaveBarAPI(\n dispatch: (action: BridgeAction) => void\n): SaveBarAPI {\n return {\n show(id: string) {\n dispatch({ type: ActionType.SAVE_BAR_SHOW, payload: { id } });\n },\n hide(id: string) {\n dispatch({ type: ActionType.SAVE_BAR_HIDE, payload: { id } });\n },\n toggle(id: string) {\n dispatch({ type: ActionType.SAVE_BAR_TOGGLE, payload: { id } });\n },\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { TitleBarAPI, TitleBarOptions, BridgeAction } from '../core/types.js';\n\nexport function createTitleBarAPI(\n dispatch: (action: BridgeAction) => void\n): TitleBarAPI {\n return {\n update(options: TitleBarOptions) {\n dispatch({\n type: ActionType.TITLE_BAR_UPDATE,\n payload: {\n title: options.title,\n subtitle: options.subtitle,\n breadcrumbs: options.breadcrumbs,\n },\n });\n },\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { FullscreenAPI, BridgeAction } from '../core/types.js';\n\nexport function createFullscreenAPI(\n dispatch: (action: BridgeAction) => void\n): FullscreenAPI {\n return {\n enter() {\n dispatch({ type: ActionType.FULLSCREEN_ENTER });\n },\n exit() {\n dispatch({ type: ActionType.FULLSCREEN_EXIT });\n },\n };\n}\n","import { ActionType } from '../core/actions.js';\nimport type { BridgeAction } from '../core/types.js';\n\nexport function createLoading(\n dispatch: (action: BridgeAction) => void\n): (isLoading: boolean) => void {\n return (isLoading: boolean) => {\n dispatch({\n type: isLoading ? ActionType.LOADING_START : ActionType.LOADING_STOP,\n });\n };\n}\n","import type { BridgeState } from '../core/types.js';\n\nexport function createAuthenticatedFetch(\n getState: () => BridgeState\n): (url: string, init?: RequestInit) => Promise<Response> {\n return async (url: string, init?: RequestInit) => {\n const state = getState();\n const sessionToken = state.context?.sessionToken;\n\n const headers = new Headers(init?.headers || {});\n\n if (sessionToken) {\n headers.set('Authorization', `Bearer ${sessionToken}`);\n }\n\n return fetch(url, {\n ...init,\n headers,\n });\n };\n}\n","import type {\n BridgeConfig,\n BridgeState,\n BridgeAction,\n QumraBridge,\n} from './types.js';\nimport { HostEventType, ActionType } from './actions.js';\nimport { createToastAPI } from '../api/toast.js';\nimport { createModalAPI } from '../api/modal.js';\nimport { createNavigate } from '../api/navigate.js';\nimport { createSaveBarAPI } from '../api/save-bar.js';\nimport { createTitleBarAPI } from '../api/title-bar.js';\nimport { createFullscreenAPI } from '../api/fullscreen.js';\nimport { createLoading } from '../api/loading.js';\nimport { createAuthenticatedFetch } from '../api/fetch.js';\n\n/**\n * Create a Qumra bridge instance.\n * This is the core factory for communicating with the Qumra Admin host.\n */\nexport function createQumraBridge(config: BridgeConfig): QumraBridge {\n const resolvedConfig: Required<BridgeConfig> = {\n apiKey: config.apiKey,\n host: config.host || 'https://app.qumra.cloud',\n };\n\n const state: BridgeState = {\n loading: false,\n context: null,\n };\n\n const subscribers = new Map<string, Set<(data: any) => void>>();\n let isReady = false;\n\n function dispatch(action: BridgeAction): void {\n window.parent.postMessage(\n {\n type: action.type,\n payload: action.payload,\n apiKey: resolvedConfig.apiKey,\n },\n resolvedConfig.host\n );\n }\n\n function subscribe(\n type: string,\n callback: (data: any) => void\n ): () => void {\n if (!subscribers.has(type)) {\n subscribers.set(type, new Set());\n }\n subscribers.get(type)!.add(callback);\n\n return () => {\n subscribers.get(type)!.delete(callback);\n if (subscribers.get(type)!.size === 0) {\n subscribers.delete(type);\n }\n };\n }\n\n function emit(type: string, data: any): void {\n const callbacks = subscribers.get(type);\n if (callbacks) {\n callbacks.forEach((cb) => {\n try {\n cb(data);\n } catch (error) {\n console.error(`[qumra] Error in subscriber for ${type}:`, error);\n }\n });\n }\n }\n\n function handleMessage(event: MessageEvent): void {\n const originUrl = new URL(resolvedConfig.host);\n if (event.origin !== originUrl.origin) {\n return;\n }\n\n const { type, payload } = event.data;\n if (!type) return;\n\n if (type === HostEventType.CONTEXT_UPDATE) {\n state.context = payload;\n } else if (type === HostEventType.LOADING_START) {\n state.loading = true;\n } else if (type === HostEventType.LOADING_STOP) {\n state.loading = false;\n }\n\n emit(type, payload);\n }\n\n window.addEventListener('message', handleMessage);\n\n const bridge: QumraBridge = {\n get config() {\n return { ...resolvedConfig };\n },\n get context() {\n return state.context;\n },\n\n navigate: createNavigate(dispatch),\n toast: createToastAPI(dispatch),\n modal: createModalAPI(dispatch),\n saveBar: createSaveBarAPI(dispatch),\n titleBar: createTitleBarAPI(dispatch),\n fullscreen: createFullscreenAPI(dispatch),\n loading: createLoading(dispatch),\n fetch: createAuthenticatedFetch(() => ({ ...state })),\n\n dispatch,\n subscribe,\n getState: () => ({ ...state }),\n\n ready() {\n if (isReady) return;\n isReady = true;\n dispatch({\n type: ActionType.READY,\n payload: { apiKey: resolvedConfig.apiKey },\n });\n },\n\n destroy() {\n window.removeEventListener('message', handleMessage);\n subscribers.clear();\n },\n\n init(newConfig: BridgeConfig) {\n resolvedConfig.apiKey = newConfig.apiKey;\n resolvedConfig.host = newConfig.host || resolvedConfig.host;\n },\n };\n\n return bridge;\n}\n","import { createQumraBridge } from './core/bridge.js';\nimport type { QumraBridge, BridgeConfig } from './core/types.js';\n\n(function initQumra() {\n // Prevent double initialization\n if ((window as any).qumra) return;\n\n const apiKeyMeta = document.querySelector('meta[name=\"qumra-api-key\"]');\n const hostMeta = document.querySelector('meta[name=\"qumra-host\"]');\n\n if (!apiKeyMeta) {\n // No meta tag — expose an uninitialized bridge that requires manual init()\n (window as any).qumra = createUninitializedBridge();\n return;\n }\n\n const config: BridgeConfig = {\n apiKey: apiKeyMeta.getAttribute('content')!,\n host: hostMeta?.getAttribute('content') || undefined,\n };\n\n (window as any).qumra = createQumraBridge(config);\n (window as any).qumra.ready();\n})();\n\nfunction createUninitializedBridge(): QumraBridge {\n let realBridge: QumraBridge | null = null;\n\n const ERROR_MSG =\n '[qumra] Bridge not initialized. Add <meta name=\"qumra-api-key\" content=\"...\"> before the script tag, or call qumra.init({ apiKey: \"...\" }).';\n\n function assertInitialized(): asserts realBridge is QumraBridge {\n if (!realBridge) throw new Error(ERROR_MSG);\n }\n\n const bridge: QumraBridge = {\n get config() {\n assertInitialized();\n return realBridge.config;\n },\n get context() {\n assertInitialized();\n return realBridge.context;\n },\n\n navigate(...args) {\n assertInitialized();\n return realBridge.navigate(...args);\n },\n toast: {\n show(...args) {\n assertInitialized();\n return realBridge.toast.show(...args);\n },\n hide(...args) {\n assertInitialized();\n return realBridge.toast.hide(...args);\n },\n },\n modal: {\n show(...args) {\n assertInitialized();\n return realBridge.modal.show(...args);\n },\n hide(...args) {\n assertInitialized();\n return realBridge.modal.hide(...args);\n },\n toggle(...args) {\n assertInitialized();\n return realBridge.modal.toggle(...args);\n },\n },\n saveBar: {\n show(...args) {\n assertInitialized();\n return realBridge.saveBar.show(...args);\n },\n hide(...args) {\n assertInitialized();\n return realBridge.saveBar.hide(...args);\n },\n toggle(...args) {\n assertInitialized();\n return realBridge.saveBar.toggle(...args);\n },\n },\n titleBar: {\n update(...args) {\n assertInitialized();\n return realBridge.titleBar.update(...args);\n },\n },\n fullscreen: {\n enter() {\n assertInitialized();\n return realBridge.fullscreen.enter();\n },\n exit() {\n assertInitialized();\n return realBridge.fullscreen.exit();\n },\n },\n loading(isLoading) {\n assertInitialized();\n return realBridge.loading(isLoading);\n },\n fetch(...args) {\n assertInitialized();\n return realBridge.fetch(...args);\n },\n\n dispatch(...args) {\n assertInitialized();\n return realBridge.dispatch(...args);\n },\n subscribe(...args) {\n assertInitialized();\n return realBridge.subscribe(...args);\n },\n getState() {\n assertInitialized();\n return realBridge.getState();\n },\n\n ready() {\n assertInitialized();\n return realBridge.ready();\n },\n destroy() {\n assertInitialized();\n return realBridge.destroy();\n },\n\n init(config: BridgeConfig) {\n realBridge = createQumraBridge(config);\n const self = (window as any).qumra;\n Object.keys(realBridge).forEach((key) => {\n if (key !== 'init') {\n (self as any)[key] = (realBridge as any)[key];\n }\n });\n realBridge.ready();\n },\n };\n\n return bridge;\n}\n"],"mappings":"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","names":["ActionType","HostEventType","createToastAPI","dispatch","counter","message","options","id","ActionType","createModalAPI","dispatch","id","ActionType","createNavigate","dispatch","url","options","ActionType","createSaveBarAPI","dispatch","id","ActionType","createTitleBarAPI","dispatch","options","ActionType","createFullscreenAPI","dispatch","ActionType","createLoading","dispatch","isLoading","ActionType","createAuthenticatedFetch","getState","url","init","sessionToken","headers","createQumraBridge","config","resolvedConfig","state","subscribers","isReady","dispatch","action","subscribe","type","callback","emit","data","callbacks","cb","error","handleMessage","event","originUrl","payload","HostEventType","createNavigate","createToastAPI","createModalAPI","createSaveBarAPI","createTitleBarAPI","createFullscreenAPI","createLoading","createAuthenticatedFetch","ActionType","newConfig","apiKeyMeta","hostMeta","createUninitializedBridge","config","createQumraBridge","realBridge","ERROR_MSG","assertInitialized","args","isLoading","self","key"]}
|
package/dist/utils/actions.d.ts
CHANGED
|
@@ -14,29 +14,29 @@ export interface ToastOptions {
|
|
|
14
14
|
message: string;
|
|
15
15
|
/** Duration in milliseconds to show the toast (0 = indefinite) */
|
|
16
16
|
duration?: number;
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/** Variant */
|
|
18
|
+
variant?: 'default' | 'success' | 'error' | 'warning' | 'info';
|
|
19
19
|
}
|
|
20
20
|
/** Options for opening a modal dialog */
|
|
21
21
|
export interface ModalOptions {
|
|
22
22
|
/** Title of the modal */
|
|
23
23
|
title: string;
|
|
24
|
-
/**
|
|
25
|
-
url?: string;
|
|
26
|
-
/** Message text to display (optional if url is provided) */
|
|
24
|
+
/** Message text to display */
|
|
27
25
|
message?: string;
|
|
28
26
|
/** Size of the modal */
|
|
29
27
|
size?: 'small' | 'medium' | 'large';
|
|
30
28
|
/** Primary action button configuration */
|
|
31
29
|
primaryAction?: {
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
/** Button label */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Button variant */
|
|
33
|
+
variant?: 'default' | 'destructive';
|
|
34
|
+
};
|
|
35
|
+
/** Secondary action button configuration */
|
|
36
|
+
secondaryAction?: {
|
|
37
|
+
/** Button label */
|
|
38
|
+
label: string;
|
|
34
39
|
};
|
|
35
|
-
/** Secondary action buttons */
|
|
36
|
-
secondaryActions?: Array<{
|
|
37
|
-
content: string;
|
|
38
|
-
onAction: () => void;
|
|
39
|
-
}>;
|
|
40
40
|
}
|
|
41
41
|
/** Options for updating the title bar */
|
|
42
42
|
export interface TitleBarOptions {
|
|
@@ -50,11 +50,26 @@ export interface TitleBarOptions {
|
|
|
50
50
|
url?: string;
|
|
51
51
|
}>;
|
|
52
52
|
}
|
|
53
|
+
/** A navigation menu item */
|
|
54
|
+
export interface NavigationMenuItem {
|
|
55
|
+
/** Display label */
|
|
56
|
+
label: string;
|
|
57
|
+
/** Route URL (used as unique identifier) */
|
|
58
|
+
url: string;
|
|
59
|
+
/** Icon name */
|
|
60
|
+
icon?: string;
|
|
61
|
+
/** Badge count or text */
|
|
62
|
+
badge?: number | string;
|
|
63
|
+
/** Whether the item is disabled */
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
/** Nested sub-items */
|
|
66
|
+
children?: NavigationMenuItem[];
|
|
67
|
+
}
|
|
53
68
|
/** Options for the save bar */
|
|
54
69
|
export interface SaveBarOptions {
|
|
55
|
-
/** Primary save button text
|
|
70
|
+
/** Primary save button text */
|
|
56
71
|
saveLabel?: string;
|
|
57
|
-
/** Discard/cancel button text
|
|
72
|
+
/** Discard/cancel button text */
|
|
58
73
|
discardLabel?: string;
|
|
59
74
|
}
|
|
60
75
|
/**
|
|
@@ -72,10 +87,22 @@ export declare const ActionType: {
|
|
|
72
87
|
readonly MODAL_OPEN: "APP::MODAL::OPEN";
|
|
73
88
|
/** Close the current modal */
|
|
74
89
|
readonly MODAL_CLOSE: "APP::MODAL::CLOSE";
|
|
90
|
+
/** Modal primary action confirmed (from host) */
|
|
91
|
+
readonly MODAL_CONFIRM: "HOST::MODAL::CONFIRM";
|
|
92
|
+
/** Modal cancelled/dismissed (from host) */
|
|
93
|
+
readonly MODAL_CANCEL: "HOST::MODAL::CANCEL";
|
|
75
94
|
/** Show the save bar (for unsaved changes) */
|
|
76
95
|
readonly SAVE_BAR_SHOW: "APP::SAVE_BAR::SHOW";
|
|
77
96
|
/** Hide the save bar */
|
|
78
97
|
readonly SAVE_BAR_HIDE: "APP::SAVE_BAR::HIDE";
|
|
98
|
+
/** Save bar save button clicked (from host) */
|
|
99
|
+
readonly SAVE_BAR_SAVE: "APP::SAVE_BAR::SAVE";
|
|
100
|
+
/** Save bar discard button clicked (from host) */
|
|
101
|
+
readonly SAVE_BAR_DISCARD: "APP::SAVE_BAR::DISCARD";
|
|
102
|
+
/** Save completed successfully (to host) */
|
|
103
|
+
readonly SAVE_BAR_SAVE_COMPLETE: "APP::SAVE_BAR::SAVE_COMPLETE";
|
|
104
|
+
/** Save failed with error (to host) */
|
|
105
|
+
readonly SAVE_BAR_SAVE_ERROR: "APP::SAVE_BAR::SAVE_ERROR";
|
|
79
106
|
/** Update the title bar */
|
|
80
107
|
readonly TITLE_BAR_UPDATE: "APP::TITLE_BAR::UPDATE";
|
|
81
108
|
/** Start a loading state */
|
|
@@ -90,6 +117,12 @@ export declare const ActionType: {
|
|
|
90
117
|
readonly FULLSCREEN_ENTER: "APP::FULLSCREEN::ENTER";
|
|
91
118
|
/** Exit fullscreen mode */
|
|
92
119
|
readonly FULLSCREEN_EXIT: "APP::FULLSCREEN::EXIT";
|
|
120
|
+
/** Update navigation menu items (to host) */
|
|
121
|
+
readonly NAVIGATION_UPDATE: "APP::NAVIGATION::UPDATE";
|
|
122
|
+
/** Set active navigation item (to host) */
|
|
123
|
+
readonly NAVIGATION_SET_ACTIVE: "APP::NAVIGATION::SET_ACTIVE";
|
|
124
|
+
/** Host requests navigation to a URL (from host) */
|
|
125
|
+
readonly NAVIGATION_NAVIGATE: "HOST::NAVIGATION::NAVIGATE";
|
|
93
126
|
};
|
|
94
127
|
/**
|
|
95
128
|
* Create a navigate action
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/utils/actions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/utils/actions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe;IACf,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;CAChE;AAED,yCAAyC;AACzC,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,0CAA0C;IAC1C,aAAa,CAAC,EAAE;QACd,mBAAmB;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,qBAAqB;QACrB,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;KACrC,CAAC;IACF,4CAA4C;IAC5C,eAAe,CAAC,EAAE;QAChB,mBAAmB;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAED,6BAA6B;AAC7B,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAED,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB,wBAAwB;;IAExB,gCAAgC;;IAEhC,0CAA0C;;IAE1C,0BAA0B;;IAE1B,8BAA8B;;IAE9B,iDAAiD;;IAEjD,4CAA4C;;IAE5C,8CAA8C;;IAE9C,wBAAwB;;IAExB,+CAA+C;;IAE/C,kDAAkD;;IAElD,4CAA4C;;IAE5C,uCAAuC;;IAEvC,2BAA2B;;IAE3B,4BAA4B;;IAE5B,6BAA6B;;IAE7B,mCAAmC;;IAEnC,2CAA2C;;IAE3C,4BAA4B;;IAE5B,2BAA2B;;IAE3B,6CAA6C;;IAE7C,2CAA2C;;IAE3C,oDAAoD;;CAE5C,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACxB,eAAe,CAQjB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GACtC,eAAe,CASjB;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,eAAe,CAI3C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAWhE;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAI5C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,eAAe,CAQrE;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,eAAe,CAI7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,CASxE;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,eAAe,CAI9C;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,eAAe,CAI7C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAIjD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,eAAe,CAIhD"}
|
package/dist/utils/actions.js
CHANGED
|
@@ -17,10 +17,22 @@ export const ActionType = {
|
|
|
17
17
|
MODAL_OPEN: 'APP::MODAL::OPEN',
|
|
18
18
|
/** Close the current modal */
|
|
19
19
|
MODAL_CLOSE: 'APP::MODAL::CLOSE',
|
|
20
|
+
/** Modal primary action confirmed (from host) */
|
|
21
|
+
MODAL_CONFIRM: 'HOST::MODAL::CONFIRM',
|
|
22
|
+
/** Modal cancelled/dismissed (from host) */
|
|
23
|
+
MODAL_CANCEL: 'HOST::MODAL::CANCEL',
|
|
20
24
|
/** Show the save bar (for unsaved changes) */
|
|
21
25
|
SAVE_BAR_SHOW: 'APP::SAVE_BAR::SHOW',
|
|
22
26
|
/** Hide the save bar */
|
|
23
27
|
SAVE_BAR_HIDE: 'APP::SAVE_BAR::HIDE',
|
|
28
|
+
/** Save bar save button clicked (from host) */
|
|
29
|
+
SAVE_BAR_SAVE: 'APP::SAVE_BAR::SAVE',
|
|
30
|
+
/** Save bar discard button clicked (from host) */
|
|
31
|
+
SAVE_BAR_DISCARD: 'APP::SAVE_BAR::DISCARD',
|
|
32
|
+
/** Save completed successfully (to host) */
|
|
33
|
+
SAVE_BAR_SAVE_COMPLETE: 'APP::SAVE_BAR::SAVE_COMPLETE',
|
|
34
|
+
/** Save failed with error (to host) */
|
|
35
|
+
SAVE_BAR_SAVE_ERROR: 'APP::SAVE_BAR::SAVE_ERROR',
|
|
24
36
|
/** Update the title bar */
|
|
25
37
|
TITLE_BAR_UPDATE: 'APP::TITLE_BAR::UPDATE',
|
|
26
38
|
/** Start a loading state */
|
|
@@ -35,6 +47,12 @@ export const ActionType = {
|
|
|
35
47
|
FULLSCREEN_ENTER: 'APP::FULLSCREEN::ENTER',
|
|
36
48
|
/** Exit fullscreen mode */
|
|
37
49
|
FULLSCREEN_EXIT: 'APP::FULLSCREEN::EXIT',
|
|
50
|
+
/** Update navigation menu items (to host) */
|
|
51
|
+
NAVIGATION_UPDATE: 'APP::NAVIGATION::UPDATE',
|
|
52
|
+
/** Set active navigation item (to host) */
|
|
53
|
+
NAVIGATION_SET_ACTIVE: 'APP::NAVIGATION::SET_ACTIVE',
|
|
54
|
+
/** Host requests navigation to a URL (from host) */
|
|
55
|
+
NAVIGATION_NAVIGATE: 'HOST::NAVIGATION::NAVIGATE',
|
|
38
56
|
};
|
|
39
57
|
/**
|
|
40
58
|
* Create a navigate action
|
|
@@ -63,7 +81,7 @@ export function showToast(message, options) {
|
|
|
63
81
|
payload: {
|
|
64
82
|
message,
|
|
65
83
|
duration: options?.duration ?? 3000,
|
|
66
|
-
|
|
84
|
+
variant: options?.variant || 'default',
|
|
67
85
|
},
|
|
68
86
|
};
|
|
69
87
|
}
|
|
@@ -86,19 +104,10 @@ export function openModal(options) {
|
|
|
86
104
|
type: ActionType.MODAL_OPEN,
|
|
87
105
|
payload: {
|
|
88
106
|
title: options.title,
|
|
89
|
-
url: options.url,
|
|
90
107
|
message: options.message,
|
|
91
|
-
size: options.size
|
|
92
|
-
primaryAction: options.primaryAction
|
|
93
|
-
|
|
94
|
-
content: options.primaryAction.content,
|
|
95
|
-
}
|
|
96
|
-
: undefined,
|
|
97
|
-
secondaryActions: options.secondaryActions
|
|
98
|
-
? options.secondaryActions.map((action) => ({
|
|
99
|
-
content: action.content,
|
|
100
|
-
}))
|
|
101
|
-
: undefined,
|
|
108
|
+
size: options.size ?? 'medium',
|
|
109
|
+
primaryAction: options.primaryAction,
|
|
110
|
+
secondaryAction: options.secondaryAction,
|
|
102
111
|
},
|
|
103
112
|
};
|
|
104
113
|
}
|
|
@@ -119,10 +128,10 @@ export function closeModal() {
|
|
|
119
128
|
export function showSaveBar(options) {
|
|
120
129
|
return {
|
|
121
130
|
type: ActionType.SAVE_BAR_SHOW,
|
|
122
|
-
payload: {
|
|
123
|
-
saveLabel: options
|
|
124
|
-
discardLabel: options
|
|
125
|
-
},
|
|
131
|
+
payload: options ? {
|
|
132
|
+
saveLabel: options.saveLabel,
|
|
133
|
+
discardLabel: options.discardLabel,
|
|
134
|
+
} : undefined,
|
|
126
135
|
};
|
|
127
136
|
}
|
|
128
137
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/utils/actions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/utils/actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,11 +46,19 @@ export declare class AppBridge {
|
|
|
46
46
|
private subscribers;
|
|
47
47
|
private messageHandler;
|
|
48
48
|
private isReady;
|
|
49
|
+
private isBrowser;
|
|
50
|
+
private navigateHandler?;
|
|
51
|
+
private static activeInstance;
|
|
49
52
|
/**
|
|
50
53
|
* Create a new AppBridge instance
|
|
51
54
|
* @param config Configuration object with apiKey and optional host
|
|
52
55
|
*/
|
|
53
56
|
constructor(config: AppBridgeConfig);
|
|
57
|
+
/**
|
|
58
|
+
* Set a handler for host-initiated navigation.
|
|
59
|
+
* Stored on the bridge so it survives Provider unmounts (e.g. 404 pages).
|
|
60
|
+
*/
|
|
61
|
+
setNavigateHandler(handler: (path: string) => void): void;
|
|
54
62
|
/**
|
|
55
63
|
* Handle incoming messages from the host
|
|
56
64
|
* @private
|
|
@@ -79,12 +87,21 @@ export declare class AppBridge {
|
|
|
79
87
|
*/
|
|
80
88
|
getState(): AppBridgeState;
|
|
81
89
|
/**
|
|
82
|
-
* Signal to the host that the app is ready
|
|
90
|
+
* Signal to the host that the app is ready.
|
|
91
|
+
* Also re-attaches the message listener if it was previously removed by destroy().
|
|
83
92
|
*/
|
|
84
93
|
ready(): void;
|
|
85
94
|
/**
|
|
86
|
-
*
|
|
95
|
+
* Called on Provider unmount. Intentionally keeps the message listener
|
|
96
|
+
* alive so the bridge can receive host events (e.g. navigation) even
|
|
97
|
+
* when the Provider unmounts (404 pages, error boundaries, etc.).
|
|
98
|
+
* Full cleanup happens in teardown() when a new instance replaces this one.
|
|
87
99
|
*/
|
|
88
100
|
destroy(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Full cleanup — only called when a new AppBridge instance replaces this one.
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
private teardown;
|
|
89
106
|
}
|
|
90
107
|
//# sourceMappingURL=app-bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-bridge.d.ts","sourceRoot":"","sources":["../../src/utils/app-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,OAAO,CAAU;
|
|
1
|
+
{"version":3,"file":"app-bridge.d.ts","sourceRoot":"","sources":["../../src/utils/app-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,eAAe,CAAC,CAAyB;IACjD,OAAO,CAAC,MAAM,CAAC,cAAc,CAA0B;IAEvD;;;OAGG;gBACS,MAAM,EAAE,eAAe;IA8BnC;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIzD;;;OAGG;IACH,OAAO,CAAC,aAAa;IAqDrB;;;OAGG;IACH,OAAO,CAAC,IAAI;IAaZ;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAYvC;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAiBlE;;;OAGG;IACH,QAAQ,IAAI,cAAc;IAI1B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAoBb;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAIf;;;OAGG;IACH,OAAO,CAAC,QAAQ;CAMjB"}
|
package/dist/utils/app-bridge.js
CHANGED
|
@@ -12,6 +12,7 @@ export class AppBridge {
|
|
|
12
12
|
* @param config Configuration object with apiKey and optional host
|
|
13
13
|
*/
|
|
14
14
|
constructor(config) {
|
|
15
|
+
this.isBrowser = typeof window !== 'undefined';
|
|
15
16
|
this.config = {
|
|
16
17
|
apiKey: config.apiKey,
|
|
17
18
|
host: config.host || 'https://app.qumra.cloud',
|
|
@@ -24,8 +25,22 @@ export class AppBridge {
|
|
|
24
25
|
this.isReady = false;
|
|
25
26
|
// Bind the message handler
|
|
26
27
|
this.messageHandler = this.handleMessage.bind(this);
|
|
27
|
-
//
|
|
28
|
-
|
|
28
|
+
// Deactivate any previous instance (prevents duplicates after Provider remount)
|
|
29
|
+
if (AppBridge.activeInstance && AppBridge.activeInstance !== this) {
|
|
30
|
+
AppBridge.activeInstance.teardown();
|
|
31
|
+
}
|
|
32
|
+
AppBridge.activeInstance = this;
|
|
33
|
+
// Listen for messages from the host (client-only)
|
|
34
|
+
if (this.isBrowser) {
|
|
35
|
+
window.addEventListener('message', this.messageHandler);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Set a handler for host-initiated navigation.
|
|
40
|
+
* Stored on the bridge so it survives Provider unmounts (e.g. 404 pages).
|
|
41
|
+
*/
|
|
42
|
+
setNavigateHandler(handler) {
|
|
43
|
+
this.navigateHandler = handler;
|
|
29
44
|
}
|
|
30
45
|
/**
|
|
31
46
|
* Handle incoming messages from the host
|
|
@@ -58,6 +73,21 @@ export class AppBridge {
|
|
|
58
73
|
this.emit('HOST::LOADING::STOP', undefined);
|
|
59
74
|
return;
|
|
60
75
|
}
|
|
76
|
+
// Handle navigation from host — uses stored handler so it works
|
|
77
|
+
// even when the Provider has unmounted (e.g. 404 pages)
|
|
78
|
+
if (type === 'HOST::NAVIGATION::NAVIGATE') {
|
|
79
|
+
const path = payload?.path;
|
|
80
|
+
if (path) {
|
|
81
|
+
const pathname = path.split('?')[0];
|
|
82
|
+
this.dispatch({
|
|
83
|
+
type: 'APP::NAVIGATION::SET_ACTIVE',
|
|
84
|
+
payload: { path: pathname },
|
|
85
|
+
});
|
|
86
|
+
this.navigateHandler?.(path);
|
|
87
|
+
}
|
|
88
|
+
this.emit(type, payload);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
61
91
|
// Emit to subscribers
|
|
62
92
|
this.emit(type, payload);
|
|
63
93
|
}
|
|
@@ -83,6 +113,8 @@ export class AppBridge {
|
|
|
83
113
|
* @param action The action to dispatch
|
|
84
114
|
*/
|
|
85
115
|
dispatch(action) {
|
|
116
|
+
if (!this.isBrowser)
|
|
117
|
+
return;
|
|
86
118
|
const message = {
|
|
87
119
|
type: action.type,
|
|
88
120
|
payload: action.payload,
|
|
@@ -118,9 +150,15 @@ export class AppBridge {
|
|
|
118
150
|
return { ...this.state };
|
|
119
151
|
}
|
|
120
152
|
/**
|
|
121
|
-
* Signal to the host that the app is ready
|
|
153
|
+
* Signal to the host that the app is ready.
|
|
154
|
+
* Also re-attaches the message listener if it was previously removed by destroy().
|
|
122
155
|
*/
|
|
123
156
|
ready() {
|
|
157
|
+
if (!this.isBrowser)
|
|
158
|
+
return;
|
|
159
|
+
// Re-attach message listener (handles React StrictMode re-mounts)
|
|
160
|
+
window.removeEventListener('message', this.messageHandler);
|
|
161
|
+
window.addEventListener('message', this.messageHandler);
|
|
124
162
|
if (this.isReady) {
|
|
125
163
|
return;
|
|
126
164
|
}
|
|
@@ -133,11 +171,25 @@ export class AppBridge {
|
|
|
133
171
|
});
|
|
134
172
|
}
|
|
135
173
|
/**
|
|
136
|
-
*
|
|
174
|
+
* Called on Provider unmount. Intentionally keeps the message listener
|
|
175
|
+
* alive so the bridge can receive host events (e.g. navigation) even
|
|
176
|
+
* when the Provider unmounts (404 pages, error boundaries, etc.).
|
|
177
|
+
* Full cleanup happens in teardown() when a new instance replaces this one.
|
|
137
178
|
*/
|
|
138
179
|
destroy() {
|
|
180
|
+
// no-op — listener stays active
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Full cleanup — only called when a new AppBridge instance replaces this one.
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
teardown() {
|
|
187
|
+
if (!this.isBrowser)
|
|
188
|
+
return;
|
|
139
189
|
window.removeEventListener('message', this.messageHandler);
|
|
140
190
|
this.subscribers.clear();
|
|
191
|
+
this.navigateHandler = undefined;
|
|
141
192
|
}
|
|
142
193
|
}
|
|
194
|
+
AppBridge.activeInstance = null;
|
|
143
195
|
//# sourceMappingURL=app-bridge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-bridge.js","sourceRoot":"","sources":["../../src/utils/app-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwCH;;;GAGG;AACH,MAAM,OAAO,SAAS;
|
|
1
|
+
{"version":3,"file":"app-bridge.js","sourceRoot":"","sources":["../../src/utils/app-bridge.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qumra/jisr",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "React hooks and utilities for communicating with the Qumra Admin from embedded apps — navigation, toasts, modals, and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|