@lerx/promise-modal 0.8.1 → 0.8.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.
@@ -1,2 +1,2 @@
1
- import type { ModalIdProps } from '../../types';
2
- export declare const Presenter: import("react").MemoExoticComponent<({ modalId }: ModalIdProps) => import("react/jsx-runtime").JSX.Element>;
1
+ import type { PresenterProps } from '../../types';
2
+ export declare const Presenter: import("react").MemoExoticComponent<({ modalId, getValue, increment }: PresenterProps) => import("react/jsx-runtime").JSX.Element>;
@@ -1,4 +1,5 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
+ import type { Fn } from '../../@aileron/declare';
2
3
  import type { BackgroundComponent, FooterOptions, ForegroundComponent, ModalBackground, PromptContentProps, PromptFooterRender, PromptInputProps } from '../../types';
3
4
  interface PromptProps<InputValue, BackgroundValue = any> {
4
5
  group?: string;
@@ -6,8 +7,8 @@ interface PromptProps<InputValue, BackgroundValue = any> {
6
7
  subtitle?: ReactNode;
7
8
  content?: ReactNode | ComponentType<PromptContentProps>;
8
9
  defaultValue?: InputValue;
9
- Input: (props: PromptInputProps<InputValue>) => ReactNode;
10
- disabled?: (value: InputValue) => boolean;
10
+ Input: Fn<[props: PromptInputProps<InputValue>], ReactNode>;
11
+ disabled?: Fn<[value: InputValue], boolean>;
11
12
  returnOnCancel?: boolean;
12
13
  background?: ModalBackground<BackgroundValue>;
13
14
  footer?: PromptFooterRender<InputValue> | FooterOptions | false;
@@ -1,4 +1,5 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
+ import type { Fn } from '../../../@aileron/declare';
2
3
  import type { FooterOptions, ManagedEntity, PromptContentProps, PromptFooterRender, PromptInputProps, PromptModal } from '../../../types';
3
4
  import { AbstractNode } from './AbstractNode';
4
5
  type PromptNodeProps<T, B> = PromptModal<T, B> & ManagedEntity;
@@ -7,8 +8,8 @@ export declare class PromptNode<T, B> extends AbstractNode<T, B> {
7
8
  readonly type: 'prompt';
8
9
  readonly content?: ReactNode | ComponentType<PromptContentProps>;
9
10
  readonly defaultValue: T | undefined;
10
- readonly Input: (props: PromptInputProps<T>) => ReactNode;
11
- readonly disabled?: (value: T) => boolean;
11
+ readonly Input: Fn<[props: PromptInputProps<T>], ReactNode>;
12
+ readonly disabled?: Fn<[value: T], boolean>;
12
13
  readonly returnOnCancel?: boolean;
13
14
  readonly footer?: PromptFooterRender<T> | FooterOptions | false;
14
15
  constructor({ id, group, initiator, type, title, subtitle, content, defaultValue, Input, disabled, returnOnCancel, footer, background, dimmed, manualDestroy, closeOnBackdropClick, resolve, ForegroundComponent, BackgroundComponent, }: PromptNodeProps<T, B>);
package/dist/index.cjs CHANGED
@@ -811,19 +811,24 @@ const style$1 = `
811
811
  `;
812
812
  ModalManager.defineStyleSheet('presenter', style$1);
813
813
 
814
- const { getValue, increment } = lib.counterFactory(1);
815
- const Presenter = react.memo(({ modalId }) => {
814
+ const Presenter = react.memo(({ modalId, getValue, increment }) => {
816
815
  const ref = react.useRef(null);
817
816
  const options = useConfigurationOptions();
818
817
  const { modal } = useModal(modalId);
819
818
  useSubscribeModal(modal);
820
- const handleChangeOrder = react.useCallback(() => {
819
+ hook.useOnMountLayout(() => {
821
820
  if (ref.current === null)
822
821
  return;
823
- if (ref.current.style.zIndex === '' + options.zIndex + getValue())
822
+ ref.current.style.zIndex = '' + (options.zIndex + increment());
823
+ });
824
+ const handleChangeOrder = react.useCallback(() => {
825
+ const element = ref.current;
826
+ if (element === null)
827
+ return;
828
+ if (element.style.zIndex === '' + (options.zIndex + getValue()))
824
829
  return;
825
- ref.current.style.zIndex = '' + options.zIndex + increment();
826
- }, [options.zIndex]);
830
+ element.style.zIndex = '' + (options.zIndex + increment());
831
+ }, [getValue, increment, options.zIndex]);
827
832
  return (jsxRuntime.jsxs("div", { ref: ref, className: presenter, children: [jsxRuntime.jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsxRuntime.jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
828
833
  });
829
834
 
@@ -841,6 +846,7 @@ const style = `
841
846
  }`;
842
847
  ModalManager.defineStyleSheet('anchor', style);
843
848
 
849
+ const { getValue, increment, reset } = lib.counterFactory(0);
844
850
  const AnchorInner = () => {
845
851
  const [version, update] = hook.useVersion();
846
852
  const { modalIds, setUpdater } = useModalManagerContext();
@@ -849,11 +855,13 @@ const AnchorInner = () => {
849
855
  }, [setUpdater, update]);
850
856
  const options = useConfigurationOptions();
851
857
  const dimmed = useActiveModalCount(validateDimmable, version);
858
+ if (!dimmed)
859
+ reset();
852
860
  return (jsxRuntime.jsx("div", { className: anchor, style: {
853
861
  '--z-index': options.zIndex,
854
862
  transitionDuration: options.duration,
855
863
  backgroundColor: dimmed ? options.backdrop : 'transparent',
856
- }, children: array.map(modalIds, (id) => (jsxRuntime.jsx(Presenter, { modalId: id }, id))) }));
864
+ }, children: array.map(modalIds, (id) => (jsxRuntime.jsx(Presenter, { modalId: id, getValue: getValue, increment: increment, reset: reset }, id))) }));
857
865
  };
858
866
  const validateDimmable = (modal) => modal?.visible && modal.dimmed;
859
867
  const Anchor = react.memo(hoc.withErrorBoundary(AnchorInner));
package/dist/index.mjs CHANGED
@@ -809,19 +809,24 @@ const style$1 = `
809
809
  `;
810
810
  ModalManager.defineStyleSheet('presenter', style$1);
811
811
 
812
- const { getValue, increment } = counterFactory(1);
813
- const Presenter = memo(({ modalId }) => {
812
+ const Presenter = memo(({ modalId, getValue, increment }) => {
814
813
  const ref = useRef(null);
815
814
  const options = useConfigurationOptions();
816
815
  const { modal } = useModal(modalId);
817
816
  useSubscribeModal(modal);
818
- const handleChangeOrder = useCallback(() => {
817
+ useOnMountLayout(() => {
819
818
  if (ref.current === null)
820
819
  return;
821
- if (ref.current.style.zIndex === '' + options.zIndex + getValue())
820
+ ref.current.style.zIndex = '' + (options.zIndex + increment());
821
+ });
822
+ const handleChangeOrder = useCallback(() => {
823
+ const element = ref.current;
824
+ if (element === null)
825
+ return;
826
+ if (element.style.zIndex === '' + (options.zIndex + getValue()))
822
827
  return;
823
- ref.current.style.zIndex = '' + options.zIndex + increment();
824
- }, [options.zIndex]);
828
+ element.style.zIndex = '' + (options.zIndex + increment());
829
+ }, [getValue, increment, options.zIndex]);
825
830
  return (jsxs("div", { ref: ref, className: presenter, children: [jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
826
831
  });
827
832
 
@@ -839,6 +844,7 @@ const style = `
839
844
  }`;
840
845
  ModalManager.defineStyleSheet('anchor', style);
841
846
 
847
+ const { getValue, increment, reset } = counterFactory(0);
842
848
  const AnchorInner = () => {
843
849
  const [version, update] = useVersion();
844
850
  const { modalIds, setUpdater } = useModalManagerContext();
@@ -847,11 +853,13 @@ const AnchorInner = () => {
847
853
  }, [setUpdater, update]);
848
854
  const options = useConfigurationOptions();
849
855
  const dimmed = useActiveModalCount(validateDimmable, version);
856
+ if (!dimmed)
857
+ reset();
850
858
  return (jsx("div", { className: anchor, style: {
851
859
  '--z-index': options.zIndex,
852
860
  transitionDuration: options.duration,
853
861
  backgroundColor: dimmed ? options.backdrop : 'transparent',
854
- }, children: map(modalIds, (id) => (jsx(Presenter, { modalId: id }, id))) }));
862
+ }, children: map(modalIds, (id) => (jsx(Presenter, { modalId: id, getValue: getValue, increment: increment, reset: reset }, id))) }));
855
863
  };
856
864
  const validateDimmable = (modal) => modal?.visible && modal.dimmed;
857
865
  const Anchor = memo(withErrorBoundary(AnchorInner));
@@ -1,10 +1,12 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
- import type { Dictionary } from '../@aileron/declare';
2
+ import type { Dictionary, Fn } from '../@aileron/declare';
3
3
  import type { BaseModal, ContentComponentProps, FooterOptions } from './base';
4
- export type AlertFooterRender<Context extends Dictionary = object> = (props: {
5
- onConfirm: VoidFunction;
6
- context: Context;
7
- }) => ReactNode;
4
+ export type AlertFooterRender<Context extends Dictionary = object> = Fn<[
5
+ props: {
6
+ onConfirm: Fn;
7
+ context: Context;
8
+ }
9
+ ], ReactNode>;
8
10
  export type AlertContentProps<Context extends Dictionary = object> = Pick<ContentComponentProps<Context>, 'onConfirm'>;
9
11
  export interface AlertModal<B = any, Context extends Dictionary = object> extends BaseModal<void, B> {
10
12
  type: 'alert';
@@ -1,5 +1,5 @@
1
1
  import type { ComponentType, PropsWithChildren, ReactNode } from 'react';
2
- import type { Dictionary } from '../@aileron/declare';
2
+ import type { Dictionary, Fn } from '../@aileron/declare';
3
3
  import type { ModalBackground } from './background';
4
4
  import type { ModalFrameProps } from './modal';
5
5
  export interface BaseModal<T, B> {
@@ -10,15 +10,15 @@ export interface BaseModal<T, B> {
10
10
  dimmed?: boolean;
11
11
  manualDestroy?: boolean;
12
12
  closeOnBackdropClick?: boolean;
13
- resolve: (result: T | null) => void;
13
+ resolve: Fn<[result: T | null]>;
14
14
  ForegroundComponent?: ForegroundComponent;
15
15
  BackgroundComponent?: BackgroundComponent;
16
16
  }
17
17
  export type ForegroundComponent = ComponentType<PropsWithChildren<ModalFrameProps>>;
18
18
  export type BackgroundComponent = ComponentType<ModalFrameProps>;
19
19
  export interface ContentComponentProps<Context extends Dictionary = object> {
20
- onConfirm: VoidFunction;
21
- onCancel: VoidFunction;
20
+ onConfirm: Fn;
21
+ onCancel: Fn;
22
22
  context: Context;
23
23
  }
24
24
  export type WrapperComponentProps<Context extends Dictionary = object> = PropsWithChildren<{
@@ -36,7 +36,7 @@ export type FooterComponentProps<Context extends Dictionary = object> = {
36
36
  cancelLabel?: ReactNode;
37
37
  hideCancel?: boolean;
38
38
  disabled?: boolean;
39
- onConfirm: VoidFunction;
40
- onCancel?: VoidFunction;
39
+ onConfirm: Fn;
40
+ onCancel?: Fn;
41
41
  context: Context;
42
42
  };
@@ -1,11 +1,13 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
- import type { Dictionary } from '../@aileron/declare';
2
+ import type { Dictionary, Fn } from '../@aileron/declare';
3
3
  import type { BaseModal, ContentComponentProps, FooterOptions } from './base';
4
- export type ConfirmFooterRender<Context extends Dictionary = object> = (props: {
5
- onConfirm: VoidFunction;
6
- onCancel: VoidFunction;
7
- context: Context;
8
- }) => ReactNode;
4
+ export type ConfirmFooterRender<Context extends Dictionary = object> = Fn<[
5
+ props: {
6
+ onConfirm: Fn;
7
+ onCancel: Fn;
8
+ context: Context;
9
+ }
10
+ ], ReactNode>;
9
11
  export type ConfirmContentProps<Context extends Dictionary = object> = ContentComponentProps<Context>;
10
12
  export interface ConfirmModal<B = any, Context extends Dictionary = object> extends BaseModal<boolean, B> {
11
13
  type: 'confirm';
@@ -19,29 +19,35 @@ export type ModalFrameProps<Context extends Dictionary = object, B = any> = {
19
19
  manualDestroy: boolean;
20
20
  closeOnBackdropClick: boolean;
21
21
  background?: ModalBackground<B>;
22
- onConfirm: () => void;
23
- onClose: () => void;
24
- onChange: (value: any) => void;
25
- onDestroy: () => void;
22
+ onConfirm: Fn;
23
+ onClose: Fn;
24
+ onChange: Fn<[value: any]>;
25
+ onDestroy: Fn;
26
26
  onChangeOrder: Fn;
27
27
  context: Context;
28
28
  };
29
- export interface ModalIdProps {
29
+ interface ModalIdProps {
30
30
  modalId: ModalNode['id'];
31
31
  }
32
+ export interface PresenterProps extends ModalIdProps {
33
+ getValue: Fn<[], number>;
34
+ increment: Fn<[], number>;
35
+ reset: Fn<[], number>;
36
+ }
32
37
  export interface ModalLayerProps extends ModalIdProps {
33
38
  onChangeOrder: Fn;
34
39
  }
35
40
  export interface ModalHandlersWithId {
36
- onConfirm: (modalId: ModalNode['id']) => void;
37
- onClose: (modalId: ModalNode['id']) => void;
38
- onChange: (modalId: ModalNode['id'], value: any) => void;
39
- onDestroy: (modalId: ModalNode['id']) => void;
41
+ onConfirm: Fn<[modalId: ModalNode['id']]>;
42
+ onClose: Fn<[modalId: ModalNode['id']]>;
43
+ onChange: Fn<[modalId: ModalNode['id'], value: any]>;
44
+ onDestroy: Fn<[modalId: ModalNode['id']]>;
40
45
  }
41
46
  export type ModalActions = {
42
47
  modal: ModalNode | undefined;
43
- onConfirm: () => void;
44
- onClose: () => void;
45
- onChange: (value: any) => void;
46
- onDestroy: () => void;
48
+ onConfirm: Fn;
49
+ onClose: Fn;
50
+ onChange: Fn<[value: any]>;
51
+ onDestroy: Fn;
47
52
  };
53
+ export {};
@@ -1,20 +1,22 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
- import type { Dictionary, SetStateFn } from '../@aileron/declare';
2
+ import type { Dictionary, Fn, SetStateFn } from '../@aileron/declare';
3
3
  import type { BaseModal, ContentComponentProps, FooterOptions } from './base';
4
- export type PromptFooterRender<T, Context extends Dictionary = object> = (props: {
5
- value: T | undefined;
6
- onChange: SetStateFn<T | undefined>;
7
- onConfirm: VoidFunction;
8
- onCancel: VoidFunction;
9
- disabled: boolean;
10
- context: Context;
11
- }) => ReactNode;
4
+ export type PromptFooterRender<T, Context extends Dictionary = object> = Fn<[
5
+ props: {
6
+ value: T | undefined;
7
+ onChange: SetStateFn<T | undefined>;
8
+ onConfirm: Fn;
9
+ onCancel: Fn;
10
+ disabled: boolean;
11
+ context: Context;
12
+ }
13
+ ], ReactNode>;
12
14
  export interface PromptInputProps<T, Context extends Dictionary = object> {
13
15
  value?: T;
14
16
  defaultValue?: T;
15
17
  onChange: SetStateFn<T | undefined>;
16
- onConfirm: VoidFunction;
17
- onCancel: VoidFunction;
18
+ onConfirm: Fn;
19
+ onCancel: Fn;
18
20
  context: Context;
19
21
  }
20
22
  export type PromptContentProps<Context extends Dictionary = object> = ContentComponentProps<Context>;
@@ -22,8 +24,8 @@ export interface PromptModal<T = any, B = any, Context extends Dictionary = obje
22
24
  type: 'prompt';
23
25
  content?: ReactNode | ComponentType<PromptContentProps<Context>>;
24
26
  defaultValue?: T;
25
- Input: (props: PromptInputProps<T, Context>) => ReactNode;
26
- disabled?: (value: T | undefined) => boolean;
27
+ Input: Fn<[props: PromptInputProps<T, Context>], ReactNode>;
28
+ disabled?: Fn<[value: T | undefined], boolean>;
27
29
  returnOnCancel?: boolean;
28
30
  footer?: PromptFooterRender<T, Context> | FooterOptions | false;
29
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lerx/promise-modal",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Universal React modal utility that can be used outside React components with promise-based results for alert, confirm, and prompt modals",
5
5
  "keywords": [
6
6
  "react",