@lerx/promise-modal 0.2.0 → 0.2.2

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.
@@ -11,6 +11,8 @@ export declare class ModalManager {
11
11
  static get prerender(): Modal[];
12
12
  static set openHandler(handler: Fn<[Modal], void>);
13
13
  static get unanchored(): boolean;
14
+ static defineStyleSheet(styleId: string, css: string): void;
15
+ static applyStyleSheet(): void;
14
16
  static reset(): void;
15
17
  static open(modal: Modal): void;
16
18
  }
@@ -1,4 +1,5 @@
1
1
  export declare const useInitialize: () => {
2
2
  readonly anchorRef: import("react").RefObject<HTMLElement | null>;
3
3
  readonly handleInitialize: (root?: HTMLElement) => void;
4
+ readonly handleReset: () => void;
4
5
  };
@@ -0,0 +1 @@
1
+ export declare const style = "\n[data-anchor] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 1000;\n transition: background-color ease-in-out;\n}";
@@ -0,0 +1 @@
1
+ export declare const style = "\n[data-background] {\n display: none;\n position: fixed;\n inset: 0;\n z-index: -999;\n pointer-events: none;\n}\n\n[data-background] > * {\n pointer-events: none;\n}\n\n[data-background][data-active] {\n pointer-events: all;\n}\n\n[data-background][data-visible] {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n";
@@ -0,0 +1 @@
1
+ export declare const style = "\n[data-foreground] {\n pointer-events: none;\n display: none;\n position: fixed;\n inset: 0;\n z-index: 1;\n}\n\n[data-foreground][data-active] > * {\n pointer-events: all;\n}\n\n[data-foreground][data-visible] {\n display: flex !important;\n justify-content: center;\n align-items: center;\n}\n";
@@ -0,0 +1 @@
1
+ export declare const style = "\n[data-presenter] {\n position: fixed;\n inset: 0;\n pointer-events: none;\n overflow: hidden;\n";
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ const react = require('react');
5
5
  const convert = require('@winglet/common-utils/convert');
6
6
  const hook = require('@winglet/react-utils/hook');
7
7
  const lib = require('@winglet/common-utils/lib');
8
- const css = require('@emotion/css');
8
+ const styleManager = require('@winglet/react-utils/style-manager');
9
9
  const reactDom = require('react-dom');
10
10
  const array = require('@winglet/common-utils/array');
11
11
  const hoc = require('@winglet/react-utils/hoc');
@@ -21,15 +21,14 @@ class ModalManager {
21
21
  return (ModalManager.#active = true);
22
22
  }
23
23
  static #anchor = null;
24
+ static #scope = `promise-modal-${lib.getRandomString(36)}`;
24
25
  static anchor(options) {
25
- if (ModalManager.#anchor) {
26
- const anchor = document.getElementById(ModalManager.#anchor.id);
27
- if (anchor)
28
- return anchor;
29
- }
26
+ if (ModalManager.#anchor)
27
+ return ModalManager.#anchor;
30
28
  const { tag = 'div', prefix = 'promise-modal', root = document.body, } = options || {};
31
29
  const node = document.createElement(tag);
32
30
  node.setAttribute('id', `${prefix}-${lib.getRandomString(36)}`);
31
+ node.setAttribute('data-scope', ModalManager.#scope);
33
32
  root.appendChild(node);
34
33
  ModalManager.#anchor = node;
35
34
  return node;
@@ -46,11 +45,21 @@ class ModalManager {
46
45
  static get unanchored() {
47
46
  return !ModalManager.#anchor;
48
47
  }
48
+ static #styleManager = styleManager.styleManagerFactory(ModalManager.#scope);
49
+ static #styleSheetDefinition = new Map();
50
+ static defineStyleSheet(styleId, css) {
51
+ ModalManager.#styleSheetDefinition.set(styleId, styleManager.compressCss(css));
52
+ }
53
+ static applyStyleSheet() {
54
+ for (const [styleId, css] of ModalManager.#styleSheetDefinition)
55
+ ModalManager.#styleManager(styleId, css, true);
56
+ }
49
57
  static reset() {
50
58
  ModalManager.#active = false;
51
59
  ModalManager.#anchor = null;
52
60
  ModalManager.#prerenderList = [];
53
61
  ModalManager.#openHandler = (modal) => ModalManager.#prerenderList.push(modal);
62
+ styleManager.destroyScope(ModalManager.#scope);
54
63
  }
55
64
  static open(modal) {
56
65
  ModalManager.#openHandler(modal);
@@ -329,30 +338,16 @@ const nodeFactory = (modal) => {
329
338
  const DEFAULT_ANIMATION_DURATION = '300ms';
330
339
  const DEFAULT_BACKDROP_COLOR = 'rgba(0, 0, 0, 0.5)';
331
340
 
332
- const fallback = css.css `
333
- margin: unset;
334
- `;
335
- const frame = css.css `
336
- display: flex;
337
- flex-direction: column;
338
- justify-content: center;
339
- align-items: center;
340
- background-color: white;
341
- padding: 20px 80px;
342
- gap: 10px;
343
- border: 1px solid black;
344
- `;
345
-
346
341
  const FallbackTitle = ({ children }) => {
347
- return jsxRuntime.jsx("h2", { className: fallback, children: children });
342
+ return jsxRuntime.jsx("h2", { style: { margin: 'unset' }, children: children });
348
343
  };
349
344
 
350
345
  const FallbackSubtitle = ({ children }) => {
351
- return jsxRuntime.jsx("h3", { className: fallback, children: children });
346
+ return jsxRuntime.jsx("h3", { style: { margin: 'unset' }, children: children });
352
347
  };
353
348
 
354
349
  const FallbackContent = ({ children }) => {
355
- return jsxRuntime.jsx("div", { className: fallback, children: children });
350
+ return jsxRuntime.jsx("div", { style: { margin: 'unset' }, children: children });
356
351
  };
357
352
 
358
353
  const FallbackFooter = ({ confirmLabel, hideConfirm = false, cancelLabel, hideCancel = false, disabled, onConfirm, onCancel, }) => {
@@ -392,10 +387,18 @@ const FallbackForegroundFrame = react.forwardRef(({ id, onChangeOrder, children
392
387
  const offset = stacked ? (id % MAX_MODAL_COUNT) * 35 : 0;
393
388
  return [level, offset];
394
389
  }, [activeCount, id]);
395
- return (jsxRuntime.jsx("div", { ref: ref, className: frame, onClick: onChangeOrder, style: {
390
+ return (jsxRuntime.jsx("div", { ref: ref, onClick: onChangeOrder, style: {
396
391
  marginBottom: `calc(25vh + ${level}px)`,
397
392
  marginLeft: `${level}px`,
398
393
  transform: `translate(${offset}px, ${offset}px)`,
394
+ display: 'flex',
395
+ flexDirection: 'column',
396
+ justifyContent: 'center',
397
+ alignItems: 'center',
398
+ backgroundColor: 'white',
399
+ padding: '20px 80px',
400
+ gap: '10px',
401
+ border: '1px solid black',
399
402
  }, children: children }));
400
403
  });
401
404
 
@@ -497,9 +500,6 @@ const ModalManagerContextProvider = react.memo(({ usePathname, children, }) => {
497
500
  return [...aliveIds, modal.id];
498
501
  });
499
502
  };
500
- return () => {
501
- ModalManager.reset();
502
- };
503
503
  });
504
504
  react.useLayoutEffect(() => {
505
505
  for (const id of modalIdsRef.current) {
@@ -622,25 +622,31 @@ const usePathname = () => {
622
622
  return { pathname };
623
623
  };
624
624
 
625
- const background = css.css `
625
+ const style$3 = `
626
+ [data-background] {
626
627
  display: none;
627
628
  position: fixed;
628
629
  inset: 0;
629
630
  z-index: -999;
630
631
  pointer-events: none;
631
- > * {
632
- pointer-events: none;
633
- }
634
- `;
635
- const active$1 = css.css `
632
+ }
633
+
634
+ [data-background] > * {
635
+ pointer-events: none;
636
+ }
637
+
638
+ [data-background][data-active] {
636
639
  pointer-events: all;
637
- `;
638
- const visible$1 = css.css `
640
+ }
641
+
642
+ [data-background][data-visible] {
639
643
  display: flex;
640
644
  align-items: center;
641
645
  justify-content: center;
646
+ }
642
647
  `;
643
648
 
649
+ ModalManager.defineStyleSheet('background', style$3);
644
650
  const BackgroundFrame = ({ modalId, onChangeOrder, }) => {
645
651
  const { BackgroundComponent } = useConfigurationContext();
646
652
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -653,30 +659,9 @@ const BackgroundFrame = ({ modalId, onChangeOrder, }) => {
653
659
  const Background = react.useMemo(() => modal?.BackgroundComponent || BackgroundComponent, [BackgroundComponent, modal]);
654
660
  if (!modal)
655
661
  return null;
656
- return (jsxRuntime.jsx("div", { className: css.cx(background, {
657
- [visible$1]: modal.manualDestroy ? modal.alive : modal.visible,
658
- [active$1]: modal.closeOnBackdropClick && modal.visible,
659
- }), onClick: handleClose, children: Background && (jsxRuntime.jsx(Background, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext })) }));
662
+ return (jsxRuntime.jsx("div", { "data-background": true, "data-active": styleManager.dataCondition(modal.closeOnBackdropClick && modal.visible), "data-visible": styleManager.dataCondition(modal.manualDestroy ? modal.alive : modal.visible), onClick: handleClose, children: Background && (jsxRuntime.jsx(Background, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext })) }));
660
663
  };
661
664
 
662
- const foreground = css.css `
663
- pointer-events: none;
664
- display: none;
665
- position: fixed;
666
- inset: 0;
667
- z-index: 1;
668
- `;
669
- const active = css.css `
670
- > * {
671
- pointer-events: all;
672
- }
673
- `;
674
- const visible = css.css `
675
- display: flex !important;
676
- justify-content: center;
677
- align-items: center;
678
- `;
679
-
680
665
  const AlertInner = react.memo(({ modal, handlers }) => {
681
666
  const { title, subtitle, content, footer } = react.useMemo(() => modal, [modal]);
682
667
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -754,6 +739,27 @@ const PromptInner = react.memo(({ modal, handlers }) => {
754
739
  })) : (jsxRuntime.jsx(FooterComponent, { disabled: disabled, onConfirm: handleConfirm, onCancel: handleClose, confirmLabel: footer?.confirm, cancelLabel: footer?.cancel, hideConfirm: footer?.hideConfirm, hideCancel: footer?.hideCancel, context: userDefinedContext })))] }));
755
740
  });
756
741
 
742
+ const style$2 = `
743
+ [data-foreground] {
744
+ pointer-events: none;
745
+ display: none;
746
+ position: fixed;
747
+ inset: 0;
748
+ z-index: 1;
749
+ }
750
+
751
+ [data-foreground][data-active] > * {
752
+ pointer-events: all;
753
+ }
754
+
755
+ [data-foreground][data-visible] {
756
+ display: flex !important;
757
+ justify-content: center;
758
+ align-items: center;
759
+ }
760
+ `;
761
+
762
+ ModalManager.defineStyleSheet('foreground', style$2);
757
763
  const ForegroundFrame = ({ modalId, onChangeOrder, }) => {
758
764
  const { ForegroundComponent } = useConfigurationContext();
759
765
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -761,10 +767,7 @@ const ForegroundFrame = ({ modalId, onChangeOrder, }) => {
761
767
  const Foreground = react.useMemo(() => modal?.ForegroundComponent || ForegroundComponent, [ForegroundComponent, modal]);
762
768
  if (!modal)
763
769
  return null;
764
- return (jsxRuntime.jsx("div", { className: css.cx(foreground, {
765
- [visible]: modal.manualDestroy ? modal.alive : modal.visible,
766
- [active]: modal.visible,
767
- }), children: jsxRuntime.jsxs(Foreground, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext, children: [modal.type === 'alert' && (jsxRuntime.jsx(AlertInner, { modal: modal, handlers: { onConfirm } })), modal.type === 'confirm' && (jsxRuntime.jsx(ConfirmInner, { modal: modal, handlers: { onConfirm, onClose } })), modal.type === 'prompt' && (jsxRuntime.jsx(PromptInner, { modal: modal, handlers: { onChange, onConfirm, onClose } }))] }) }));
770
+ return (jsxRuntime.jsx("div", { "data-foreground": true, "data-active": styleManager.dataCondition(modal.visible), "data-visible": styleManager.dataCondition(modal.manualDestroy ? modal.alive : modal.visible), children: jsxRuntime.jsxs(Foreground, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext, children: [modal.type === 'alert' && (jsxRuntime.jsx(AlertInner, { modal: modal, handlers: { onConfirm } })), modal.type === 'confirm' && (jsxRuntime.jsx(ConfirmInner, { modal: modal, handlers: { onConfirm, onClose } })), modal.type === 'prompt' && (jsxRuntime.jsx(PromptInner, { modal: modal, handlers: { onChange, onConfirm, onClose } }))] }) }));
768
771
  };
769
772
 
770
773
  const useSubscribeModal = (modal) => {
@@ -778,13 +781,15 @@ const useSubscribeModal = (modal) => {
778
781
  return version;
779
782
  };
780
783
 
781
- const presenter = css.css `
784
+ const style$1 = `
785
+ [data-presenter] {
782
786
  position: fixed;
783
787
  inset: 0;
784
788
  pointer-events: none;
785
789
  overflow: hidden;
786
790
  `;
787
791
 
792
+ ModalManager.defineStyleSheet('presenter', style$1);
788
793
  const { increment } = lib.counterFactory(1);
789
794
  const Presenter = react.memo(({ modalId }) => {
790
795
  const ref = react.useRef(null);
@@ -795,20 +800,22 @@ const Presenter = react.memo(({ modalId }) => {
795
800
  ref.current.style.zIndex = `${increment()}`;
796
801
  }
797
802
  });
798
- return (jsxRuntime.jsxs("div", { ref: ref, className: presenter, children: [jsxRuntime.jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsxRuntime.jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
803
+ return (jsxRuntime.jsxs("div", { ref: ref, "data-presenter": true, children: [jsxRuntime.jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsxRuntime.jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
799
804
  });
800
805
 
801
- const anchor = css.css `
802
- display: flex;
803
- align-items: center;
804
- justify-content: center;
805
- position: fixed;
806
- inset: 0;
807
- pointer-events: none;
808
- z-index: 1000;
809
- transition: background-color ease-in-out;
810
- `;
811
-
806
+ const style = `
807
+ [data-anchor] {
808
+ display: flex;
809
+ align-items: center;
810
+ justify-content: center;
811
+ position: fixed;
812
+ inset: 0;
813
+ pointer-events: none;
814
+ z-index: 1000;
815
+ transition: background-color ease-in-out;
816
+ }`;
817
+
818
+ ModalManager.defineStyleSheet('anchor', style);
812
819
  const AnchorInner = () => {
813
820
  const [version, update] = hook.useVersion();
814
821
  const { modalIds, setUpdater } = useModalManagerContext();
@@ -817,7 +824,7 @@ const AnchorInner = () => {
817
824
  }, [setUpdater, update]);
818
825
  const options = useConfigurationOptions();
819
826
  const dimmed = useActiveModalCount(validateDimmable, version);
820
- return (jsxRuntime.jsx("div", { className: anchor, style: {
827
+ return (jsxRuntime.jsx("div", { "data-anchor": true, style: {
821
828
  transitionDuration: options.duration,
822
829
  backgroundColor: dimmed ? options.backdrop : 'transparent',
823
830
  }, children: array.map(modalIds, (id) => (jsxRuntime.jsx(Presenter, { modalId: id }, id))) }));
@@ -834,6 +841,7 @@ const useInitialize = () => {
834
841
  const handleInitialize = react.useCallback((root) => {
835
842
  if (permitted.current) {
836
843
  anchorRef.current = ModalManager.anchor({ root });
844
+ ModalManager.applyStyleSheet();
837
845
  update();
838
846
  }
839
847
  else
@@ -844,15 +852,19 @@ const useInitialize = () => {
844
852
  info: 'Something is wrong with the ModalProvider initialization...',
845
853
  });
846
854
  }, [update]);
855
+ const handleReset = react.useCallback(() => {
856
+ ModalManager.reset();
857
+ }, []);
847
858
  return {
848
859
  anchorRef,
849
860
  handleInitialize,
861
+ handleReset,
850
862
  };
851
863
  };
852
864
 
853
865
  const BootstrapProvider = react.forwardRef(({ usePathname: useExternalPathname, ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, context, children, }, handleRef) => {
854
866
  const usePathname$1 = react.useMemo(() => useExternalPathname || usePathname, [useExternalPathname]);
855
- const { anchorRef, handleInitialize } = useInitialize();
867
+ const { anchorRef, handleInitialize, handleReset } = useInitialize();
856
868
  react.useImperativeHandle(handleRef, () => ({
857
869
  initialize: handleInitialize,
858
870
  }), [handleInitialize]);
@@ -862,6 +874,7 @@ const BootstrapProvider = react.forwardRef(({ usePathname: useExternalPathname,
862
874
  return () => {
863
875
  if (anchorRef.current)
864
876
  anchorRef.current.remove();
877
+ handleReset();
865
878
  };
866
879
  });
867
880
  return (jsxRuntime.jsxs(react.Fragment, { children: [children, anchorRef.current &&
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@ import { createContext, useContext, useMemo, forwardRef, memo, useRef, useState,
3
3
  import { convertMsFromDuration } from '@winglet/common-utils/convert';
4
4
  import { useReference, useOnMountLayout, useHandle, useVersion, useOnMount } from '@winglet/react-utils/hook';
5
5
  import { getRandomString, counterFactory } from '@winglet/common-utils/lib';
6
- import { css, cx } from '@emotion/css';
6
+ import { styleManagerFactory, compressCss, destroyScope, dataCondition } from '@winglet/react-utils/style-manager';
7
7
  import { createPortal } from 'react-dom';
8
8
  import { map } from '@winglet/common-utils/array';
9
9
  import { withErrorBoundary } from '@winglet/react-utils/hoc';
@@ -19,15 +19,14 @@ class ModalManager {
19
19
  return (ModalManager.#active = true);
20
20
  }
21
21
  static #anchor = null;
22
+ static #scope = `promise-modal-${getRandomString(36)}`;
22
23
  static anchor(options) {
23
- if (ModalManager.#anchor) {
24
- const anchor = document.getElementById(ModalManager.#anchor.id);
25
- if (anchor)
26
- return anchor;
27
- }
24
+ if (ModalManager.#anchor)
25
+ return ModalManager.#anchor;
28
26
  const { tag = 'div', prefix = 'promise-modal', root = document.body, } = options || {};
29
27
  const node = document.createElement(tag);
30
28
  node.setAttribute('id', `${prefix}-${getRandomString(36)}`);
29
+ node.setAttribute('data-scope', ModalManager.#scope);
31
30
  root.appendChild(node);
32
31
  ModalManager.#anchor = node;
33
32
  return node;
@@ -44,11 +43,21 @@ class ModalManager {
44
43
  static get unanchored() {
45
44
  return !ModalManager.#anchor;
46
45
  }
46
+ static #styleManager = styleManagerFactory(ModalManager.#scope);
47
+ static #styleSheetDefinition = new Map();
48
+ static defineStyleSheet(styleId, css) {
49
+ ModalManager.#styleSheetDefinition.set(styleId, compressCss(css));
50
+ }
51
+ static applyStyleSheet() {
52
+ for (const [styleId, css] of ModalManager.#styleSheetDefinition)
53
+ ModalManager.#styleManager(styleId, css, true);
54
+ }
47
55
  static reset() {
48
56
  ModalManager.#active = false;
49
57
  ModalManager.#anchor = null;
50
58
  ModalManager.#prerenderList = [];
51
59
  ModalManager.#openHandler = (modal) => ModalManager.#prerenderList.push(modal);
60
+ destroyScope(ModalManager.#scope);
52
61
  }
53
62
  static open(modal) {
54
63
  ModalManager.#openHandler(modal);
@@ -327,30 +336,16 @@ const nodeFactory = (modal) => {
327
336
  const DEFAULT_ANIMATION_DURATION = '300ms';
328
337
  const DEFAULT_BACKDROP_COLOR = 'rgba(0, 0, 0, 0.5)';
329
338
 
330
- const fallback = css `
331
- margin: unset;
332
- `;
333
- const frame = css `
334
- display: flex;
335
- flex-direction: column;
336
- justify-content: center;
337
- align-items: center;
338
- background-color: white;
339
- padding: 20px 80px;
340
- gap: 10px;
341
- border: 1px solid black;
342
- `;
343
-
344
339
  const FallbackTitle = ({ children }) => {
345
- return jsx("h2", { className: fallback, children: children });
340
+ return jsx("h2", { style: { margin: 'unset' }, children: children });
346
341
  };
347
342
 
348
343
  const FallbackSubtitle = ({ children }) => {
349
- return jsx("h3", { className: fallback, children: children });
344
+ return jsx("h3", { style: { margin: 'unset' }, children: children });
350
345
  };
351
346
 
352
347
  const FallbackContent = ({ children }) => {
353
- return jsx("div", { className: fallback, children: children });
348
+ return jsx("div", { style: { margin: 'unset' }, children: children });
354
349
  };
355
350
 
356
351
  const FallbackFooter = ({ confirmLabel, hideConfirm = false, cancelLabel, hideCancel = false, disabled, onConfirm, onCancel, }) => {
@@ -390,10 +385,18 @@ const FallbackForegroundFrame = forwardRef(({ id, onChangeOrder, children }, ref
390
385
  const offset = stacked ? (id % MAX_MODAL_COUNT) * 35 : 0;
391
386
  return [level, offset];
392
387
  }, [activeCount, id]);
393
- return (jsx("div", { ref: ref, className: frame, onClick: onChangeOrder, style: {
388
+ return (jsx("div", { ref: ref, onClick: onChangeOrder, style: {
394
389
  marginBottom: `calc(25vh + ${level}px)`,
395
390
  marginLeft: `${level}px`,
396
391
  transform: `translate(${offset}px, ${offset}px)`,
392
+ display: 'flex',
393
+ flexDirection: 'column',
394
+ justifyContent: 'center',
395
+ alignItems: 'center',
396
+ backgroundColor: 'white',
397
+ padding: '20px 80px',
398
+ gap: '10px',
399
+ border: '1px solid black',
397
400
  }, children: children }));
398
401
  });
399
402
 
@@ -495,9 +498,6 @@ const ModalManagerContextProvider = memo(({ usePathname, children, }) => {
495
498
  return [...aliveIds, modal.id];
496
499
  });
497
500
  };
498
- return () => {
499
- ModalManager.reset();
500
- };
501
501
  });
502
502
  useLayoutEffect(() => {
503
503
  for (const id of modalIdsRef.current) {
@@ -620,25 +620,31 @@ const usePathname = () => {
620
620
  return { pathname };
621
621
  };
622
622
 
623
- const background = css `
623
+ const style$3 = `
624
+ [data-background] {
624
625
  display: none;
625
626
  position: fixed;
626
627
  inset: 0;
627
628
  z-index: -999;
628
629
  pointer-events: none;
629
- > * {
630
- pointer-events: none;
631
- }
632
- `;
633
- const active$1 = css `
630
+ }
631
+
632
+ [data-background] > * {
633
+ pointer-events: none;
634
+ }
635
+
636
+ [data-background][data-active] {
634
637
  pointer-events: all;
635
- `;
636
- const visible$1 = css `
638
+ }
639
+
640
+ [data-background][data-visible] {
637
641
  display: flex;
638
642
  align-items: center;
639
643
  justify-content: center;
644
+ }
640
645
  `;
641
646
 
647
+ ModalManager.defineStyleSheet('background', style$3);
642
648
  const BackgroundFrame = ({ modalId, onChangeOrder, }) => {
643
649
  const { BackgroundComponent } = useConfigurationContext();
644
650
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -651,30 +657,9 @@ const BackgroundFrame = ({ modalId, onChangeOrder, }) => {
651
657
  const Background = useMemo(() => modal?.BackgroundComponent || BackgroundComponent, [BackgroundComponent, modal]);
652
658
  if (!modal)
653
659
  return null;
654
- return (jsx("div", { className: cx(background, {
655
- [visible$1]: modal.manualDestroy ? modal.alive : modal.visible,
656
- [active$1]: modal.closeOnBackdropClick && modal.visible,
657
- }), onClick: handleClose, children: Background && (jsx(Background, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext })) }));
660
+ return (jsx("div", { "data-background": true, "data-active": dataCondition(modal.closeOnBackdropClick && modal.visible), "data-visible": dataCondition(modal.manualDestroy ? modal.alive : modal.visible), onClick: handleClose, children: Background && (jsx(Background, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext })) }));
658
661
  };
659
662
 
660
- const foreground = css `
661
- pointer-events: none;
662
- display: none;
663
- position: fixed;
664
- inset: 0;
665
- z-index: 1;
666
- `;
667
- const active = css `
668
- > * {
669
- pointer-events: all;
670
- }
671
- `;
672
- const visible = css `
673
- display: flex !important;
674
- justify-content: center;
675
- align-items: center;
676
- `;
677
-
678
663
  const AlertInner = memo(({ modal, handlers }) => {
679
664
  const { title, subtitle, content, footer } = useMemo(() => modal, [modal]);
680
665
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -752,6 +737,27 @@ const PromptInner = memo(({ modal, handlers }) => {
752
737
  })) : (jsx(FooterComponent, { disabled: disabled, onConfirm: handleConfirm, onCancel: handleClose, confirmLabel: footer?.confirm, cancelLabel: footer?.cancel, hideConfirm: footer?.hideConfirm, hideCancel: footer?.hideCancel, context: userDefinedContext })))] }));
753
738
  });
754
739
 
740
+ const style$2 = `
741
+ [data-foreground] {
742
+ pointer-events: none;
743
+ display: none;
744
+ position: fixed;
745
+ inset: 0;
746
+ z-index: 1;
747
+ }
748
+
749
+ [data-foreground][data-active] > * {
750
+ pointer-events: all;
751
+ }
752
+
753
+ [data-foreground][data-visible] {
754
+ display: flex !important;
755
+ justify-content: center;
756
+ align-items: center;
757
+ }
758
+ `;
759
+
760
+ ModalManager.defineStyleSheet('foreground', style$2);
755
761
  const ForegroundFrame = ({ modalId, onChangeOrder, }) => {
756
762
  const { ForegroundComponent } = useConfigurationContext();
757
763
  const { context: userDefinedContext } = useUserDefinedContext();
@@ -759,10 +765,7 @@ const ForegroundFrame = ({ modalId, onChangeOrder, }) => {
759
765
  const Foreground = useMemo(() => modal?.ForegroundComponent || ForegroundComponent, [ForegroundComponent, modal]);
760
766
  if (!modal)
761
767
  return null;
762
- return (jsx("div", { className: cx(foreground, {
763
- [visible]: modal.manualDestroy ? modal.alive : modal.visible,
764
- [active]: modal.visible,
765
- }), children: jsxs(Foreground, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext, children: [modal.type === 'alert' && (jsx(AlertInner, { modal: modal, handlers: { onConfirm } })), modal.type === 'confirm' && (jsx(ConfirmInner, { modal: modal, handlers: { onConfirm, onClose } })), modal.type === 'prompt' && (jsx(PromptInner, { modal: modal, handlers: { onChange, onConfirm, onClose } }))] }) }));
768
+ return (jsx("div", { "data-foreground": true, "data-active": dataCondition(modal.visible), "data-visible": dataCondition(modal.manualDestroy ? modal.alive : modal.visible), children: jsxs(Foreground, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext, children: [modal.type === 'alert' && (jsx(AlertInner, { modal: modal, handlers: { onConfirm } })), modal.type === 'confirm' && (jsx(ConfirmInner, { modal: modal, handlers: { onConfirm, onClose } })), modal.type === 'prompt' && (jsx(PromptInner, { modal: modal, handlers: { onChange, onConfirm, onClose } }))] }) }));
766
769
  };
767
770
 
768
771
  const useSubscribeModal = (modal) => {
@@ -776,13 +779,15 @@ const useSubscribeModal = (modal) => {
776
779
  return version;
777
780
  };
778
781
 
779
- const presenter = css `
782
+ const style$1 = `
783
+ [data-presenter] {
780
784
  position: fixed;
781
785
  inset: 0;
782
786
  pointer-events: none;
783
787
  overflow: hidden;
784
788
  `;
785
789
 
790
+ ModalManager.defineStyleSheet('presenter', style$1);
786
791
  const { increment } = counterFactory(1);
787
792
  const Presenter = memo(({ modalId }) => {
788
793
  const ref = useRef(null);
@@ -793,20 +798,22 @@ const Presenter = memo(({ modalId }) => {
793
798
  ref.current.style.zIndex = `${increment()}`;
794
799
  }
795
800
  });
796
- return (jsxs("div", { ref: ref, className: presenter, children: [jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
801
+ return (jsxs("div", { ref: ref, "data-presenter": true, children: [jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
797
802
  });
798
803
 
799
- const anchor = css `
800
- display: flex;
801
- align-items: center;
802
- justify-content: center;
803
- position: fixed;
804
- inset: 0;
805
- pointer-events: none;
806
- z-index: 1000;
807
- transition: background-color ease-in-out;
808
- `;
809
-
804
+ const style = `
805
+ [data-anchor] {
806
+ display: flex;
807
+ align-items: center;
808
+ justify-content: center;
809
+ position: fixed;
810
+ inset: 0;
811
+ pointer-events: none;
812
+ z-index: 1000;
813
+ transition: background-color ease-in-out;
814
+ }`;
815
+
816
+ ModalManager.defineStyleSheet('anchor', style);
810
817
  const AnchorInner = () => {
811
818
  const [version, update] = useVersion();
812
819
  const { modalIds, setUpdater } = useModalManagerContext();
@@ -815,7 +822,7 @@ const AnchorInner = () => {
815
822
  }, [setUpdater, update]);
816
823
  const options = useConfigurationOptions();
817
824
  const dimmed = useActiveModalCount(validateDimmable, version);
818
- return (jsx("div", { className: anchor, style: {
825
+ return (jsx("div", { "data-anchor": true, style: {
819
826
  transitionDuration: options.duration,
820
827
  backgroundColor: dimmed ? options.backdrop : 'transparent',
821
828
  }, children: map(modalIds, (id) => (jsx(Presenter, { modalId: id }, id))) }));
@@ -832,6 +839,7 @@ const useInitialize = () => {
832
839
  const handleInitialize = useCallback((root) => {
833
840
  if (permitted.current) {
834
841
  anchorRef.current = ModalManager.anchor({ root });
842
+ ModalManager.applyStyleSheet();
835
843
  update();
836
844
  }
837
845
  else
@@ -842,15 +850,19 @@ const useInitialize = () => {
842
850
  info: 'Something is wrong with the ModalProvider initialization...',
843
851
  });
844
852
  }, [update]);
853
+ const handleReset = useCallback(() => {
854
+ ModalManager.reset();
855
+ }, []);
845
856
  return {
846
857
  anchorRef,
847
858
  handleInitialize,
859
+ handleReset,
848
860
  };
849
861
  };
850
862
 
851
863
  const BootstrapProvider = forwardRef(({ usePathname: useExternalPathname, ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, context, children, }, handleRef) => {
852
864
  const usePathname$1 = useMemo(() => useExternalPathname || usePathname, [useExternalPathname]);
853
- const { anchorRef, handleInitialize } = useInitialize();
865
+ const { anchorRef, handleInitialize, handleReset } = useInitialize();
854
866
  useImperativeHandle(handleRef, () => ({
855
867
  initialize: handleInitialize,
856
868
  }), [handleInitialize]);
@@ -860,6 +872,7 @@ const BootstrapProvider = forwardRef(({ usePathname: useExternalPathname, Foregr
860
872
  return () => {
861
873
  if (anchorRef.current)
862
874
  anchorRef.current.remove();
875
+ handleReset();
863
876
  };
864
877
  });
865
878
  return (jsxs(Fragment, { children: [children, anchorRef.current &&
package/package.json CHANGED
@@ -1,6 +1,24 @@
1
1
  {
2
2
  "name": "@lerx/promise-modal",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
+ "description": "Universal React modal utility that can be used outside React components with promise-based results for alert, confirm, and prompt modals",
5
+ "keywords": [
6
+ "react",
7
+ "modal",
8
+ "promise",
9
+ "alert",
10
+ "confirm",
11
+ "prompt",
12
+ "typescript",
13
+ "utility",
14
+ "ui-components",
15
+ "dialog",
16
+ "popup",
17
+ "toast",
18
+ "notification",
19
+ "modal-utility",
20
+ "imperative-ui"
21
+ ],
4
22
  "repository": {
5
23
  "type": "git",
6
24
  "url": "https://github.com/vincent-kk/albatrion.git",
@@ -31,11 +49,12 @@
31
49
  "scripts": {
32
50
  "build": "rollup -c && yarn build:types",
33
51
  "build-storybook": "storybook build",
52
+ "build:publish:npm": "yarn build && yarn publish:npm",
34
53
  "build:types": "tsc -p ./tsconfig.declarations.json && tsc-alias -p ./tsconfig.declarations.json",
35
54
  "format": "prettier --write \"src/**/*.ts\" \"src/**/*.tsx\"",
36
55
  "lint": "eslint \"src/**/*.{ts,tsx}\"",
37
56
  "make-dependency-graph": "npx depcruise src --config .dependency-cruiser.js --output-type dot > dependency-graph.dot && dot -Tpng dependency-graph.dot -o dependency-graph.png",
38
- "publish:npm": "yarn build && yarn npm publish --access public",
57
+ "publish:npm": "yarn npm publish --access public",
39
58
  "size-limit": "size-limit",
40
59
  "start": "yarn build && yarn storybook",
41
60
  "storybook": "storybook dev -p 6006",
@@ -46,9 +65,8 @@
46
65
  "version:patch": "yarn version patch"
47
66
  },
48
67
  "dependencies": {
49
- "@emotion/css": "^11.0.0",
50
- "@winglet/common-utils": "^0.2.0",
51
- "@winglet/react-utils": "^0.2.0"
68
+ "@winglet/common-utils": "^0.2.1",
69
+ "@winglet/react-utils": "^0.2.2"
52
70
  },
53
71
  "devDependencies": {
54
72
  "@chromatic-com/storybook": "^3.2.6",
@@ -1 +0,0 @@
1
- export declare const anchor: string;
@@ -1,3 +0,0 @@
1
- export declare const background: string;
2
- export declare const active: string;
3
- export declare const visible: string;
@@ -1,2 +0,0 @@
1
- export declare const fallback: string;
2
- export declare const frame: string;
@@ -1,3 +0,0 @@
1
- export declare const foreground: string;
2
- export declare const active: string;
3
- export declare const visible: string;
@@ -1 +0,0 @@
1
- export declare const presenter: string;