@rango-dev/ui 0.37.1-next.0 → 0.37.1-next.1

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.
@@ -2,9 +2,9 @@ import type { IconHighlight } from './MessageBox.styles.js';
2
2
  import type * as Stitches from '@stitches/react';
3
3
  import type { ReactNode } from 'react';
4
4
  type BaseProps = Stitches.VariantProps<typeof IconHighlight>;
5
- type BaseTypes = Exclude<BaseProps['type'], object>;
5
+ export type MessageType = Exclude<BaseProps['type'], object>;
6
6
  export interface PropTypes {
7
- type: BaseTypes;
7
+ type: MessageType;
8
8
  title: string;
9
9
  description?: string | ReactNode;
10
10
  icon?: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBox.types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/MessageBox/MessageBox.types.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,KAAK,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC7D,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAEpD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB"}
1
+ {"version":3,"file":"MessageBox.types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/MessageBox/MessageBox.types.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,KAAK,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB"}
@@ -1,2 +1,3 @@
1
1
  export * from './MessageBox.js';
2
+ export type { MessageType } from './MessageBox.types.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/MessageBox/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/MessageBox/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { ModalPropTypes } from './Modal.types.js';
2
2
  import type { PropsWithChildren } from 'react';
3
3
  import React from 'react';
4
- export declare function Modal(props: PropsWithChildren<ModalPropTypes>): React.JSX.Element;
4
+ export declare function Modal(props: PropsWithChildren<ModalPropTypes>): React.ReactPortal | null;
5
5
  //# sourceMappingURL=Modal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,KAAsC,MAAM,OAAO,CAAC;AAqB3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,cAAc,CAAC,qBAyG7D"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,KAAsC,MAAM,OAAO,CAAC;AAmB3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,cAAc,CAAC,4BAgI7D"}
@@ -0,0 +1,2 @@
1
+ export declare function forceReflow(node: HTMLElement): number;
2
+ //# sourceMappingURL=Modal.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.helpers.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Modal/Modal.helpers.ts"],"names":[],"mappings":"AACA,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,UAE5C"}
@@ -8,6 +8,7 @@ export interface ModalPropTypes {
8
8
  title?: string;
9
9
  open: boolean;
10
10
  onClose: () => void;
11
+ onExit?: () => void;
11
12
  anchor?: BaseAnchor;
12
13
  dismissible?: boolean;
13
14
  header?: React.ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Modal/Modal.types.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAEjD,KAAK,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,KAAK,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACnC,SAAS,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;KACtC,CAAC;IACF,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
1
+ {"version":3,"file":"Modal.types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Modal/Modal.types.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAEjD,KAAK,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,KAAK,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACnC,SAAS,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC;KACtC,CAAC;IACF,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/ui",
3
- "version": "0.37.1-next.0",
3
+ "version": "0.37.1-next.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -3,10 +3,10 @@ import type * as Stitches from '@stitches/react';
3
3
  import type { ReactNode } from 'react';
4
4
 
5
5
  type BaseProps = Stitches.VariantProps<typeof IconHighlight>;
6
- type BaseTypes = Exclude<BaseProps['type'], object>;
6
+ export type MessageType = Exclude<BaseProps['type'], object>;
7
7
 
8
8
  export interface PropTypes {
9
- type: BaseTypes;
9
+ type: MessageType;
10
10
  title: string;
11
11
  description?: string | ReactNode;
12
12
  icon?: ReactNode;
@@ -1 +1,2 @@
1
1
  export * from './MessageBox.js';
2
+ export type { MessageType } from './MessageBox.types.js';
@@ -0,0 +1,4 @@
1
+ // https://github.com/reactjs/react-transition-group/blob/master/src/CSSTransition.js#L48-L55
2
+ export function forceReflow(node: HTMLElement) {
3
+ return node.scrollTop;
4
+ }
@@ -10,6 +10,7 @@ import { Divider } from '../Divider/index.js';
10
10
  import { IconButton } from '../IconButton/index.js';
11
11
  import { Typography } from '../Typography/index.js';
12
12
 
13
+ import { forceReflow } from './Modal.helpers.js';
13
14
  import {
14
15
  BackDrop,
15
16
  Content,
@@ -19,14 +20,12 @@ import {
19
20
  ModalHeader,
20
21
  } from './Modal.styles.js';
21
22
 
22
- const CLOSED_DELAY = 600;
23
- const OPEN_DELAY = 100;
24
-
25
23
  export function Modal(props: PropsWithChildren<ModalPropTypes>) {
26
24
  const {
27
25
  title,
28
26
  open,
29
27
  onClose,
28
+ onExit,
30
29
  styles,
31
30
  anchor = 'bottom',
32
31
  container = document.body,
@@ -40,9 +39,14 @@ export function Modal(props: PropsWithChildren<ModalPropTypes>) {
40
39
  hasCloseIcon = true,
41
40
  } = props;
42
41
 
43
- const [active, setActive] = useState(false);
44
- const [isMount, setIsMount] = useState(false);
45
- const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
42
+ const [status, setStatus] = useState<
43
+ 'unmounted' | 'mounted' | 'activated' | 'deactivated'
44
+ >('unmounted');
45
+ const active = status === 'activated';
46
+ const isMount =
47
+ status == 'mounted' || status === 'activated' || status === 'deactivated';
48
+ const modalContainerRef = useRef<HTMLElement | null>(null);
49
+ const exitCallbackRef = useRef<ModalPropTypes['onExit']>();
46
50
 
47
51
  const handleBackDropClick = (event: React.MouseEvent<HTMLDivElement>) => {
48
52
  event.stopPropagation();
@@ -51,80 +55,97 @@ export function Modal(props: PropsWithChildren<ModalPropTypes>) {
51
55
  onClose();
52
56
  }
53
57
  };
58
+
54
59
  useEffect(() => {
55
- if (container) {
56
- if (timeoutRef.current) {
57
- clearTimeout(timeoutRef.current);
58
- }
59
- if (open) {
60
- setIsMount(true);
61
- container.style.overflow = 'hidden';
62
- timeoutRef.current = setTimeout(() => {
63
- setActive(true);
64
- }, OPEN_DELAY);
65
- } else {
66
- setActive(false);
67
- timeoutRef.current = setTimeout(() => {
68
- setIsMount(false);
60
+ exitCallbackRef.current = onExit;
61
+ }, [onExit]);
62
+
63
+ useEffect(() => {
64
+ if (exitCallbackRef.current) {
65
+ modalContainerRef.current?.addEventListener(
66
+ 'transitionend',
67
+ exitCallbackRef.current
68
+ );
69
+ }
70
+
71
+ if (!open) {
72
+ if (status === 'activated') {
73
+ setStatus('deactivated');
74
+ modalContainerRef.current?.addEventListener('transitionend', () => {
75
+ setStatus('unmounted');
69
76
  container.style.removeProperty('overflow');
70
- }, CLOSED_DELAY);
77
+ });
78
+ } else {
79
+ setStatus('unmounted');
71
80
  }
81
+ } else {
82
+ setStatus('mounted');
83
+ container.style.overflow = 'hidden';
72
84
  }
85
+
73
86
  return () => {
74
- if (timeoutRef.current) {
75
- clearTimeout(timeoutRef.current);
87
+ if (exitCallbackRef.current) {
88
+ modalContainerRef.current?.removeEventListener(
89
+ 'transitionend',
90
+ exitCallbackRef.current
91
+ );
76
92
  }
77
93
  };
78
- }, [open, container]);
79
-
80
- return (
81
- <>
82
- {isMount &&
83
- container &&
84
- createPortal(
85
- <BackDrop
86
- active={active}
87
- onClick={handleBackDropClick}
88
- css={styles?.root}>
89
- <ModalContainer
90
- active={active}
91
- css={styles?.container}
92
- anchor={anchor}>
93
- {header ?? (
94
- <ModalHeader noTitle={!title && dismissible && !prefix}>
95
- {prefix}
96
- {title && (
97
- <Typography variant="title" size="small">
98
- {title}
99
- </Typography>
100
- )}
101
- <Flex>
102
- {suffix}
103
- {dismissible && hasCloseIcon && (
104
- <IconButton onClick={onClose} variant="ghost">
105
- <CloseIcon color="gray" size={14} />
106
- </IconButton>
107
- )}
108
- </Flex>
109
- </ModalHeader>
94
+ }, [open]);
95
+
96
+ useEffect(() => {
97
+ if (!!container && isMount) {
98
+ if (modalContainerRef.current) {
99
+ forceReflow(modalContainerRef.current);
100
+ }
101
+ setStatus('activated');
102
+ }
103
+ }, [isMount, container]);
104
+
105
+ if (status === 'unmounted' || !container) {
106
+ return null;
107
+ }
108
+
109
+ return createPortal(
110
+ <BackDrop active={active} onClick={handleBackDropClick} css={styles?.root}>
111
+ <ModalContainer
112
+ active={active}
113
+ css={styles?.container}
114
+ anchor={anchor}
115
+ ref={(ref) => (modalContainerRef.current = ref)}>
116
+ {header ?? (
117
+ <ModalHeader noTitle={!title && dismissible && !prefix}>
118
+ {prefix}
119
+ {title && (
120
+ <Typography variant="title" size="small">
121
+ {title}
122
+ </Typography>
123
+ )}
124
+ <Flex>
125
+ {suffix}
126
+ {dismissible && hasCloseIcon && (
127
+ <IconButton onClick={onClose} variant="ghost">
128
+ <CloseIcon color="gray" size={14} />
129
+ </IconButton>
110
130
  )}
111
- <Content css={styles?.content}>{children}</Content>
112
-
113
- <Footer css={styles?.footer}>
114
- {footer && <div className="footer__content">{footer}</div>}
115
-
116
- <div
117
- className={`footer__logo ${
118
- hasWatermark ? 'logo__show' : 'logo__hidden'
119
- }`}>
120
- <Divider size={12} />
121
- <BottomLogo />
122
- </div>
123
- </Footer>
124
- </ModalContainer>
125
- </BackDrop>,
126
- container
131
+ </Flex>
132
+ </ModalHeader>
127
133
  )}
128
- </>
134
+ <Content css={styles?.content}>{children}</Content>
135
+
136
+ <Footer css={styles?.footer}>
137
+ {footer && <div className="footer__content">{footer}</div>}
138
+
139
+ <div
140
+ className={`footer__logo ${
141
+ hasWatermark ? 'logo__show' : 'logo__hidden'
142
+ }`}>
143
+ <Divider size={12} />
144
+ <BottomLogo />
145
+ </div>
146
+ </Footer>
147
+ </ModalContainer>
148
+ </BackDrop>,
149
+ container
129
150
  );
130
151
  }
@@ -9,6 +9,7 @@ export interface ModalPropTypes {
9
9
  title?: string;
10
10
  open: boolean;
11
11
  onClose: () => void;
12
+ onExit?: () => void;
12
13
  anchor?: BaseAnchor;
13
14
  dismissible?: boolean;
14
15
  header?: React.ReactNode;