@ultraviolet/ui 1.9.0 → 1.10.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.
- package/dist/index.d.ts +40 -72
- package/dist/src/components/Button/index.js +2 -0
- package/dist/src/components/Modal/Dialog.js +151 -0
- package/dist/src/components/Modal/Disclosure.js +39 -0
- package/dist/src/components/Modal/Modal.js +111 -0
- package/dist/src/components/Modal/constants.js +50 -0
- package/dist/src/components/Tooltip/index.js +2 -0
- package/dist/src/index.js +1 -1
- package/dist/src/internalComponents/Popup/index.js +8 -6
- package/package.json +5 -5
- package/dist/src/components/Modal/index.js +0 -283
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ import { ReactDatePickerProps } from 'react-datepicker';
|
|
|
14
14
|
import { Serie, LineSvgProps } from '@nivo/line';
|
|
15
15
|
import { ScaleSpec } from '@nivo/scales';
|
|
16
16
|
import { PopoverStateReturn } from 'reakit/Popover';
|
|
17
|
-
import { DialogProps, DialogStateReturn } from 'reakit/Dialog';
|
|
18
17
|
import Select, { OptionProps, Props, CommonProps as CommonProps$1, GroupBase } from 'react-select';
|
|
19
18
|
import { ToastOptions } from 'react-toastify';
|
|
20
19
|
|
|
@@ -1401,86 +1400,51 @@ type PasswordStrengthMeterProps$1 = {
|
|
|
1401
1400
|
};
|
|
1402
1401
|
declare const Meter: ({ strength, title, value, className, "data-testid": dataTestId, id, }: PasswordStrengthMeterProps$1) => JSX.Element;
|
|
1403
1402
|
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
center: string;
|
|
1417
|
-
left: string;
|
|
1418
|
-
right: string;
|
|
1419
|
-
top: string;
|
|
1420
|
-
'top-left': string;
|
|
1421
|
-
'top-right': string;
|
|
1422
|
-
};
|
|
1423
|
-
type ModalPlacement = keyof typeof MODAL_PLACEMENT;
|
|
1424
|
-
declare const MODAL_ANIMATION: {
|
|
1425
|
-
fold: {
|
|
1426
|
-
enter: _emotion_react.Keyframes;
|
|
1427
|
-
leave: _emotion_react.Keyframes;
|
|
1428
|
-
};
|
|
1429
|
-
scaleBack: {
|
|
1430
|
-
enter: _emotion_react.Keyframes;
|
|
1431
|
-
leave: _emotion_react.Keyframes;
|
|
1432
|
-
};
|
|
1433
|
-
scaleUp: {
|
|
1434
|
-
enter: _emotion_react.Keyframes;
|
|
1435
|
-
leave: _emotion_react.Keyframes;
|
|
1436
|
-
};
|
|
1437
|
-
sketch: {
|
|
1438
|
-
enter: _emotion_react.Keyframes;
|
|
1439
|
-
leave: _emotion_react.Keyframes;
|
|
1440
|
-
};
|
|
1441
|
-
slideBottom: {
|
|
1442
|
-
enter: _emotion_react.Keyframes;
|
|
1443
|
-
leave: _emotion_react.Keyframes;
|
|
1444
|
-
};
|
|
1445
|
-
slideLeft: {
|
|
1446
|
-
enter: _emotion_react.Keyframes;
|
|
1447
|
-
leave: _emotion_react.Keyframes;
|
|
1448
|
-
};
|
|
1449
|
-
slideRight: {
|
|
1450
|
-
enter: _emotion_react.Keyframes;
|
|
1451
|
-
leave: _emotion_react.Keyframes;
|
|
1452
|
-
};
|
|
1453
|
-
slideTop: {
|
|
1454
|
-
enter: _emotion_react.Keyframes;
|
|
1455
|
-
leave: _emotion_react.Keyframes;
|
|
1456
|
-
};
|
|
1457
|
-
zoom: {
|
|
1458
|
-
enter: _emotion_react.Keyframes;
|
|
1459
|
-
leave: _emotion_react.Keyframes;
|
|
1460
|
-
};
|
|
1403
|
+
type ModalSize = 'large' | 'medium' | 'small' | 'xsmall' | 'xxsmall';
|
|
1404
|
+
type ModalPlacement = 'bottom' | 'bottom-left' | 'bottom-right' | 'center' | 'top' | 'top-left' | 'top-right' | 'right' | 'left';
|
|
1405
|
+
type ModalState = {
|
|
1406
|
+
onOpen: () => void;
|
|
1407
|
+
onClose: () => void;
|
|
1408
|
+
toggle: () => void;
|
|
1409
|
+
visible: boolean;
|
|
1410
|
+
modalId: string;
|
|
1411
|
+
/**
|
|
1412
|
+
* @deprecated use onClose
|
|
1413
|
+
*/
|
|
1414
|
+
hide: () => void;
|
|
1461
1415
|
};
|
|
1462
|
-
|
|
1463
|
-
type
|
|
1464
|
-
|
|
1465
|
-
|
|
1416
|
+
|
|
1417
|
+
type ModalProps = {
|
|
1418
|
+
id?: string;
|
|
1419
|
+
hideOnEsc?: boolean;
|
|
1420
|
+
hideOnClickOutside?: boolean;
|
|
1421
|
+
preventBodyScroll?: boolean;
|
|
1466
1422
|
ariaLabel?: string;
|
|
1467
|
-
|
|
1468
|
-
customDialogBackdropStyles?: JSX.IntrinsicAttributes['css'];
|
|
1469
|
-
customDialogStyles?: JSX.IntrinsicAttributes['css'];
|
|
1470
|
-
disclosure?: DisclosureParam;
|
|
1471
|
-
height?: string;
|
|
1423
|
+
disclosure?: ReactNode | ((state: ModalState) => ReactNode);
|
|
1472
1424
|
isClosable?: boolean;
|
|
1473
|
-
modal?: boolean;
|
|
1474
1425
|
onClose?: () => void;
|
|
1475
1426
|
onBeforeClose?: () => Promise<void> | void;
|
|
1476
1427
|
opened?: boolean;
|
|
1477
1428
|
placement?: ModalPlacement;
|
|
1478
|
-
|
|
1479
|
-
|
|
1429
|
+
size?: ModalSize;
|
|
1430
|
+
/**
|
|
1431
|
+
* @deprecated You should use size prop instead
|
|
1432
|
+
*/
|
|
1433
|
+
width?: ModalSize;
|
|
1434
|
+
children: ReactNode | ((args: ModalState) => ReactNode);
|
|
1480
1435
|
className?: string;
|
|
1481
1436
|
'data-testid'?: string;
|
|
1437
|
+
backdropClassName?: string;
|
|
1438
|
+
/**
|
|
1439
|
+
* @deprecated You should use backdropClassName instead
|
|
1440
|
+
*/
|
|
1441
|
+
customDialogBackdropStyles?: react__default.JSX.IntrinsicAttributes['css'];
|
|
1442
|
+
/**
|
|
1443
|
+
* @deprecated You should use className instead
|
|
1444
|
+
*/
|
|
1445
|
+
customDialogStyles?: react__default.JSX.IntrinsicAttributes['css'];
|
|
1482
1446
|
};
|
|
1483
|
-
declare const Modal:
|
|
1447
|
+
declare const Modal: ({ ariaLabel, id, children, disclosure, hideOnClickOutside, hideOnEsc, isClosable, onClose, onBeforeClose, opened, placement, preventBodyScroll, size, className, "data-testid": dataTestId, backdropClassName, width, customDialogStyles, customDialogBackdropStyles, }: ModalProps) => _emotion_react_jsx_runtime.JSX.Element;
|
|
1484
1448
|
|
|
1485
1449
|
type NoticeProps = {
|
|
1486
1450
|
children: ReactNode;
|
|
@@ -1657,6 +1621,10 @@ type TooltipProps$1 = {
|
|
|
1657
1621
|
*/
|
|
1658
1622
|
text?: ReactNode;
|
|
1659
1623
|
className?: string;
|
|
1624
|
+
/**
|
|
1625
|
+
* It will add `width: 100%` to the tooltip container.
|
|
1626
|
+
*/
|
|
1627
|
+
containerFullWidth?: boolean;
|
|
1660
1628
|
/**
|
|
1661
1629
|
* It will force display tooltip. This can be useful if you need to always display the tooltip without hover needed.
|
|
1662
1630
|
*/
|
|
@@ -2337,7 +2305,7 @@ type ToggleProps = {
|
|
|
2337
2305
|
};
|
|
2338
2306
|
declare const Toggle: react.ForwardRefExoticComponent<ToggleProps & react.RefAttributes<HTMLInputElement>>;
|
|
2339
2307
|
|
|
2340
|
-
type TooltipProps = Pick<ComponentProps<typeof Popup>, 'id' | 'children' | 'maxWidth' | 'placement' | 'text' | 'className' | 'visible' | 'innerRef' | 'role' | 'data-testid'>;
|
|
2308
|
+
type TooltipProps = Pick<ComponentProps<typeof Popup>, 'id' | 'children' | 'maxWidth' | 'placement' | 'text' | 'className' | 'visible' | 'innerRef' | 'role' | 'data-testid' | 'containerFullWidth'>;
|
|
2341
2309
|
declare const Tooltip: react.ForwardRefExoticComponent<TooltipProps & react.RefAttributes<HTMLDivElement>>;
|
|
2342
2310
|
|
|
2343
2311
|
type VerificationCodeProps = {
|
|
@@ -260,6 +260,7 @@ const Button = /*#__PURE__*/forwardRef((_ref10, ref) => {
|
|
|
260
260
|
const Component = VARIANTS_COMPONENTS[variant].link;
|
|
261
261
|
return jsx(Tooltip, {
|
|
262
262
|
text: tooltip,
|
|
263
|
+
containerFullWidth: fullWidth,
|
|
263
264
|
children: jsx(Component, {
|
|
264
265
|
role: role,
|
|
265
266
|
className: className,
|
|
@@ -289,6 +290,7 @@ const Button = /*#__PURE__*/forwardRef((_ref10, ref) => {
|
|
|
289
290
|
const Component = VARIANTS_COMPONENTS[variant].button;
|
|
290
291
|
return jsx(Tooltip, {
|
|
291
292
|
text: tooltip,
|
|
293
|
+
containerFullWidth: fullWidth,
|
|
292
294
|
children: jsx(Component, {
|
|
293
295
|
role: role,
|
|
294
296
|
className: className,
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import _styled from '@emotion/styled/base';
|
|
2
|
+
import { useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { MODAL_WIDTH, MODAL_PLACEMENT } from './constants.js';
|
|
5
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const StyledBackdrop = /*#__PURE__*/_styled("div", {
|
|
8
|
+
target: "e1cqen9h1"
|
|
9
|
+
})("position:fixed;top:0;right:0;height:0;width:0;overflow:hidden;background-color:", _ref => {
|
|
10
|
+
let {
|
|
11
|
+
theme
|
|
12
|
+
} = _ref;
|
|
13
|
+
return theme.colors.overlay;
|
|
14
|
+
}, ";&[data-open='true']{padding:", _ref2 => {
|
|
15
|
+
let {
|
|
16
|
+
theme
|
|
17
|
+
} = _ref2;
|
|
18
|
+
return theme.space['2'];
|
|
19
|
+
}, ";overflow:auto;display:flex;bottom:0;left:0;height:100%;width:100%;}");
|
|
20
|
+
const StyledDialog = /*#__PURE__*/_styled("dialog", {
|
|
21
|
+
target: "e1cqen9h0"
|
|
22
|
+
})("background-color:", _ref3 => {
|
|
23
|
+
let {
|
|
24
|
+
theme
|
|
25
|
+
} = _ref3;
|
|
26
|
+
return theme.colors.neutral.backgroundWeakElevated;
|
|
27
|
+
}, ";position:relative;border-radius:", _ref4 => {
|
|
28
|
+
let {
|
|
29
|
+
theme
|
|
30
|
+
} = _ref4;
|
|
31
|
+
return theme.radii.default;
|
|
32
|
+
}, ";border:0;padding:", _ref5 => {
|
|
33
|
+
let {
|
|
34
|
+
theme
|
|
35
|
+
} = _ref5;
|
|
36
|
+
return theme.space['3'];
|
|
37
|
+
}, ";width:", MODAL_WIDTH.medium, "px;box-shadow:", _ref6 => {
|
|
38
|
+
let {
|
|
39
|
+
theme
|
|
40
|
+
} = _ref6;
|
|
41
|
+
return theme.shadows.modal;
|
|
42
|
+
}, ";", /*#__PURE__*/Object.entries(MODAL_WIDTH).map(_ref7 => {
|
|
43
|
+
let [size, value] = _ref7;
|
|
44
|
+
return `
|
|
45
|
+
&[data-size="${size}"] {
|
|
46
|
+
width: ${value}px;
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
}), " ", /*#__PURE__*/Object.entries(MODAL_PLACEMENT).map(_ref8 => {
|
|
50
|
+
let [placement, value] = _ref8;
|
|
51
|
+
return `
|
|
52
|
+
&[data-placement="${placement}"] {
|
|
53
|
+
${value}
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
}), ";");
|
|
57
|
+
const Dialog = _ref9 => {
|
|
58
|
+
let {
|
|
59
|
+
children,
|
|
60
|
+
open,
|
|
61
|
+
placement,
|
|
62
|
+
onClose,
|
|
63
|
+
hideOnClickOutside,
|
|
64
|
+
size,
|
|
65
|
+
id,
|
|
66
|
+
ariaLabel,
|
|
67
|
+
className,
|
|
68
|
+
'data-testid': dataTestId,
|
|
69
|
+
preventBodyScroll,
|
|
70
|
+
hideOnEsc,
|
|
71
|
+
backdropClassName,
|
|
72
|
+
dialogCss,
|
|
73
|
+
backdropCss
|
|
74
|
+
} = _ref9;
|
|
75
|
+
const containerRef = useRef(document.createElement('div'));
|
|
76
|
+
const onCloseRef = useRef(onClose);
|
|
77
|
+
|
|
78
|
+
// Portal to put the modal in
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const element = containerRef.current;
|
|
81
|
+
if (open) {
|
|
82
|
+
document.body.appendChild(element);
|
|
83
|
+
}
|
|
84
|
+
return () => {
|
|
85
|
+
if (document.body.contains(element)) {
|
|
86
|
+
document.body.removeChild(element);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}, [open]);
|
|
90
|
+
|
|
91
|
+
// Save the reassignment of eventHandler in the useEffect below
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
onCloseRef.current = onClose;
|
|
94
|
+
}, [onClose]);
|
|
95
|
+
|
|
96
|
+
// Handle hide on esc press
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
const handleEscPress = event => {
|
|
99
|
+
if (event.key === 'Escape' && hideOnEsc) {
|
|
100
|
+
onCloseRef.current();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
if (open) {
|
|
104
|
+
document.addEventListener('keyup', handleEscPress);
|
|
105
|
+
}
|
|
106
|
+
return () => {
|
|
107
|
+
document.removeEventListener('keyup', handleEscPress);
|
|
108
|
+
};
|
|
109
|
+
}, [open, onCloseRef, hideOnEsc]);
|
|
110
|
+
|
|
111
|
+
// Handle body scroll
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (open && preventBodyScroll) {
|
|
114
|
+
document.body.style.overflow = 'hidden';
|
|
115
|
+
} else {
|
|
116
|
+
document.body.style.overflow = 'auto';
|
|
117
|
+
}
|
|
118
|
+
}, [preventBodyScroll, open]);
|
|
119
|
+
|
|
120
|
+
// Stop click to prevent unexpected dialog close
|
|
121
|
+
const stopClick = useCallback(event => {
|
|
122
|
+
event.stopPropagation();
|
|
123
|
+
}, []);
|
|
124
|
+
|
|
125
|
+
// Stop key up : used when having inputs in modals
|
|
126
|
+
const stopKeyUp = useCallback(event => {
|
|
127
|
+
event.stopPropagation();
|
|
128
|
+
}, []);
|
|
129
|
+
return /*#__PURE__*/createPortal(jsx(StyledBackdrop, {
|
|
130
|
+
"data-open": open,
|
|
131
|
+
onClick: hideOnClickOutside ? onClose : undefined,
|
|
132
|
+
className: backdropClassName,
|
|
133
|
+
css: backdropCss,
|
|
134
|
+
"data-testid": dataTestId ? `${dataTestId}-backdrop` : undefined,
|
|
135
|
+
children: jsx(StyledDialog, {
|
|
136
|
+
css: dialogCss,
|
|
137
|
+
onKeyUp: stopKeyUp,
|
|
138
|
+
className: className,
|
|
139
|
+
id: id,
|
|
140
|
+
"data-testid": dataTestId,
|
|
141
|
+
"aria-label": ariaLabel,
|
|
142
|
+
"data-placement": placement,
|
|
143
|
+
"data-size": size,
|
|
144
|
+
open: open,
|
|
145
|
+
onClick: stopClick,
|
|
146
|
+
children: open ? children : null
|
|
147
|
+
})
|
|
148
|
+
}), containerRef.current);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export { Dialog };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, isValidElement, cloneElement, createRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const Disclosure = _ref => {
|
|
4
|
+
let {
|
|
5
|
+
disclosure,
|
|
6
|
+
handleOpen,
|
|
7
|
+
visible,
|
|
8
|
+
handleClose,
|
|
9
|
+
toggle,
|
|
10
|
+
id
|
|
11
|
+
} = _ref;
|
|
12
|
+
const disclosureRef = /*#__PURE__*/createRef();
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const element = disclosureRef.current;
|
|
15
|
+
element?.addEventListener('click', handleOpen);
|
|
16
|
+
return () => {
|
|
17
|
+
element?.removeEventListener('click', handleOpen);
|
|
18
|
+
};
|
|
19
|
+
}, [handleOpen, disclosureRef]);
|
|
20
|
+
if (typeof disclosure === 'function') {
|
|
21
|
+
return disclosure({
|
|
22
|
+
visible,
|
|
23
|
+
onClose: handleClose,
|
|
24
|
+
toggle,
|
|
25
|
+
onOpen: handleOpen,
|
|
26
|
+
modalId: id,
|
|
27
|
+
hide: handleClose
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if ( /*#__PURE__*/isValidElement(disclosure)) {
|
|
31
|
+
return /*#__PURE__*/cloneElement(disclosure, {
|
|
32
|
+
...disclosure.props,
|
|
33
|
+
ref: disclosureRef
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { Disclosure };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import _styled from '@emotion/styled/base';
|
|
2
|
+
import { useState, useId, useCallback } from 'react';
|
|
3
|
+
import { Button } from '../Button/index.js';
|
|
4
|
+
import { Dialog } from './Dialog.js';
|
|
5
|
+
import { Disclosure } from './Disclosure.js';
|
|
6
|
+
import { jsxs, Fragment, jsx } from '@emotion/react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
const StyledContainer = /*#__PURE__*/_styled("div", {
|
|
9
|
+
target: "e227mx40"
|
|
10
|
+
})("position:absolute;top:", _ref => {
|
|
11
|
+
let {
|
|
12
|
+
theme
|
|
13
|
+
} = _ref;
|
|
14
|
+
return theme.space['2'];
|
|
15
|
+
}, ";right:", _ref2 => {
|
|
16
|
+
let {
|
|
17
|
+
theme
|
|
18
|
+
} = _ref2;
|
|
19
|
+
return theme.space['2'];
|
|
20
|
+
}, ";");
|
|
21
|
+
const Modal = _ref3 => {
|
|
22
|
+
let {
|
|
23
|
+
ariaLabel = 'modal',
|
|
24
|
+
id,
|
|
25
|
+
children,
|
|
26
|
+
disclosure,
|
|
27
|
+
hideOnClickOutside = true,
|
|
28
|
+
hideOnEsc = true,
|
|
29
|
+
isClosable = true,
|
|
30
|
+
onClose,
|
|
31
|
+
onBeforeClose,
|
|
32
|
+
opened = false,
|
|
33
|
+
placement = 'center',
|
|
34
|
+
preventBodyScroll = true,
|
|
35
|
+
size,
|
|
36
|
+
className,
|
|
37
|
+
'data-testid': dataTestId,
|
|
38
|
+
backdropClassName,
|
|
39
|
+
width = 'small',
|
|
40
|
+
customDialogStyles,
|
|
41
|
+
customDialogBackdropStyles
|
|
42
|
+
} = _ref3;
|
|
43
|
+
const [visible, setVisible] = useState(opened);
|
|
44
|
+
const controlId = useId();
|
|
45
|
+
const handleOpen = useCallback(() => {
|
|
46
|
+
setVisible(true);
|
|
47
|
+
}, []);
|
|
48
|
+
const handleClose = useCallback(() => {
|
|
49
|
+
if (onClose) {
|
|
50
|
+
onClose();
|
|
51
|
+
} else {
|
|
52
|
+
const promise = onBeforeClose?.();
|
|
53
|
+
if (promise && 'catch' in promise) {
|
|
54
|
+
promise.catch(undefined);
|
|
55
|
+
}
|
|
56
|
+
setVisible(false);
|
|
57
|
+
}
|
|
58
|
+
}, [onBeforeClose, onClose]);
|
|
59
|
+
const handleToggle = useCallback(() => {
|
|
60
|
+
setVisible(current => !current);
|
|
61
|
+
}, []);
|
|
62
|
+
const finalId = id ?? controlId;
|
|
63
|
+
const finalSize = size ?? width;
|
|
64
|
+
return jsxs(Fragment, {
|
|
65
|
+
children: [jsx(Disclosure, {
|
|
66
|
+
id: finalId,
|
|
67
|
+
handleOpen: handleOpen,
|
|
68
|
+
disclosure: disclosure,
|
|
69
|
+
handleClose: handleClose,
|
|
70
|
+
visible: visible,
|
|
71
|
+
toggle: handleToggle
|
|
72
|
+
}), jsx(Dialog, {
|
|
73
|
+
open: visible,
|
|
74
|
+
placement: placement,
|
|
75
|
+
size: finalSize,
|
|
76
|
+
ariaLabel: ariaLabel,
|
|
77
|
+
hideOnClickOutside: hideOnClickOutside,
|
|
78
|
+
hideOnEsc: hideOnEsc,
|
|
79
|
+
preventBodyScroll: preventBodyScroll,
|
|
80
|
+
onClose: handleClose,
|
|
81
|
+
className: className,
|
|
82
|
+
backdropClassName: backdropClassName,
|
|
83
|
+
"data-testid": dataTestId,
|
|
84
|
+
id: finalId,
|
|
85
|
+
dialogCss: customDialogStyles,
|
|
86
|
+
backdropCss: customDialogBackdropStyles,
|
|
87
|
+
children: jsxs(Fragment, {
|
|
88
|
+
children: [typeof children === 'function' ? children({
|
|
89
|
+
visible,
|
|
90
|
+
onClose: handleClose,
|
|
91
|
+
onOpen: handleOpen,
|
|
92
|
+
toggle: handleToggle,
|
|
93
|
+
modalId: finalId,
|
|
94
|
+
hide: handleClose
|
|
95
|
+
}) : children, jsx(StyledContainer, {
|
|
96
|
+
children: isClosable ? jsx(Button, {
|
|
97
|
+
"data-testid": dataTestId ? `${dataTestId}-close-button` : undefined,
|
|
98
|
+
onClick: handleClose,
|
|
99
|
+
variant: "ghost",
|
|
100
|
+
size: "small",
|
|
101
|
+
icon: "close",
|
|
102
|
+
sentiment: "neutral",
|
|
103
|
+
"aria-label": "close"
|
|
104
|
+
}) : null
|
|
105
|
+
})]
|
|
106
|
+
})
|
|
107
|
+
})]
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export { Modal };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const MODAL_WIDTH = {
|
|
2
|
+
large: 850,
|
|
3
|
+
medium: 708,
|
|
4
|
+
small: 616,
|
|
5
|
+
xsmall: 400,
|
|
6
|
+
xxsmall: 360
|
|
7
|
+
};
|
|
8
|
+
const MODAL_PLACEMENT = {
|
|
9
|
+
bottom: `
|
|
10
|
+
margin: auto;
|
|
11
|
+
margin-bottom: 0;
|
|
12
|
+
`,
|
|
13
|
+
'bottom-left': `
|
|
14
|
+
margin: auto;
|
|
15
|
+
margin-left: 0;
|
|
16
|
+
margin-bottom: 0;
|
|
17
|
+
`,
|
|
18
|
+
'bottom-right': `
|
|
19
|
+
margin: auto;
|
|
20
|
+
margin-right: 0;
|
|
21
|
+
margin-bottom: 0;
|
|
22
|
+
`,
|
|
23
|
+
center: `
|
|
24
|
+
margin: auto;
|
|
25
|
+
`,
|
|
26
|
+
left: `
|
|
27
|
+
margin: auto;
|
|
28
|
+
margin-left: 0;
|
|
29
|
+
`,
|
|
30
|
+
right: `
|
|
31
|
+
margin: auto;
|
|
32
|
+
margin-right: 0;
|
|
33
|
+
`,
|
|
34
|
+
top: `
|
|
35
|
+
margin: auto;
|
|
36
|
+
margin-top: 0px;
|
|
37
|
+
`,
|
|
38
|
+
'top-left': `
|
|
39
|
+
margin: auto;
|
|
40
|
+
margin-left: 0;
|
|
41
|
+
margin-top: 0;
|
|
42
|
+
`,
|
|
43
|
+
'top-right': `
|
|
44
|
+
margin: auto;
|
|
45
|
+
margin-right: 0;
|
|
46
|
+
margin-top: 0;
|
|
47
|
+
`
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { MODAL_PLACEMENT, MODAL_WIDTH };
|
|
@@ -9,6 +9,7 @@ const Tooltip = /*#__PURE__*/forwardRef((_ref, tooltipRef) => {
|
|
|
9
9
|
placement = 'auto',
|
|
10
10
|
id,
|
|
11
11
|
className,
|
|
12
|
+
containerFullWidth,
|
|
12
13
|
maxWidth = 232,
|
|
13
14
|
visible,
|
|
14
15
|
innerRef,
|
|
@@ -21,6 +22,7 @@ const Tooltip = /*#__PURE__*/forwardRef((_ref, tooltipRef) => {
|
|
|
21
22
|
role: role,
|
|
22
23
|
"data-testid": dataTestId,
|
|
23
24
|
className: className,
|
|
25
|
+
containerFullWidth: containerFullWidth,
|
|
24
26
|
maxWidth: maxWidth,
|
|
25
27
|
visible: visible,
|
|
26
28
|
placement: placement,
|
package/dist/src/index.js
CHANGED
|
@@ -28,7 +28,7 @@ export { List } from './components/List/index.js';
|
|
|
28
28
|
export { Loader } from './components/Loader/index.js';
|
|
29
29
|
export { Menu } from './components/Menu/index.js';
|
|
30
30
|
export { Meter } from './components/Meter/Meter.js';
|
|
31
|
-
export { Modal } from './components/Modal/
|
|
31
|
+
export { Modal } from './components/Modal/Modal.js';
|
|
32
32
|
export { Notice } from './components/Notice/index.js';
|
|
33
33
|
export { NumberInput } from './components/NumberInput/index.js';
|
|
34
34
|
export { Pagination } from './components/Pagination/index.js';
|
|
@@ -57,7 +57,7 @@ const StyledTooltip = /*#__PURE__*/_styled('div', {
|
|
|
57
57
|
maxWidth
|
|
58
58
|
} = _ref5;
|
|
59
59
|
return maxWidth;
|
|
60
|
-
}, "px;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
|
|
60
|
+
}, "px;word-break:break-all;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
|
|
61
61
|
let {
|
|
62
62
|
positions
|
|
63
63
|
} = _ref6;
|
|
@@ -97,11 +97,11 @@ const StyledTooltip = /*#__PURE__*/_styled('div', {
|
|
|
97
97
|
const StyledChildrenContainer = /*#__PURE__*/_styled("div", {
|
|
98
98
|
target: "efkq4700"
|
|
99
99
|
})(process.env.NODE_ENV === "production" ? {
|
|
100
|
-
name: "
|
|
101
|
-
styles: "display:inherit"
|
|
100
|
+
name: "jhu4ja",
|
|
101
|
+
styles: "display:inherit;&[data-container-full-width='true']{width:100%;}"
|
|
102
102
|
} : {
|
|
103
|
-
name: "
|
|
104
|
-
styles: "display:inherit",
|
|
103
|
+
name: "jhu4ja",
|
|
104
|
+
styles: "display:inherit;&[data-container-full-width='true']{width:100%;}",
|
|
105
105
|
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
106
106
|
});
|
|
107
107
|
const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
@@ -111,6 +111,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
111
111
|
placement = 'auto',
|
|
112
112
|
id,
|
|
113
113
|
className,
|
|
114
|
+
containerFullWidth,
|
|
114
115
|
maxWidth = 232,
|
|
115
116
|
visible,
|
|
116
117
|
innerRef,
|
|
@@ -250,9 +251,10 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
250
251
|
ref: childrenRef,
|
|
251
252
|
tabIndex: 0,
|
|
252
253
|
onKeyDown: onKeyDown,
|
|
254
|
+
"data-container-full-width": containerFullWidth,
|
|
253
255
|
children: children
|
|
254
256
|
});
|
|
255
|
-
}, [children, generatedId, isControlled, onKeyDown, onPointerEvent]);
|
|
257
|
+
}, [children, containerFullWidth, generatedId, isControlled, onKeyDown, onPointerEvent]);
|
|
256
258
|
if (!text) {
|
|
257
259
|
if (typeof children === 'function') return null;
|
|
258
260
|
return jsx(Fragment, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultraviolet/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Ultraviolet UI",
|
|
5
5
|
"homepage": "https://github.com/scaleway/ultraviolet#readme",
|
|
6
6
|
"repository": {
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"react-dom": "18.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@babel/core": "7.22.
|
|
42
|
+
"@babel/core": "7.22.11",
|
|
43
43
|
"@emotion/babel-plugin": "11.11.0",
|
|
44
44
|
"@emotion/react": "11.11.1",
|
|
45
45
|
"@emotion/styled": "11.11.0",
|
|
46
|
-
"@types/react": "18.2.
|
|
46
|
+
"@types/react": "18.2.14",
|
|
47
47
|
"@types/react-datepicker": "4.15.0",
|
|
48
|
-
"@types/react-dom": "18.2.
|
|
48
|
+
"@types/react-dom": "18.2.6",
|
|
49
49
|
"react": "18.2.0",
|
|
50
50
|
"react-dom": "18.2.0"
|
|
51
51
|
},
|
|
@@ -68,6 +68,6 @@
|
|
|
68
68
|
"react-use-clipboard": "1.0.9",
|
|
69
69
|
"reakit": "1.3.11",
|
|
70
70
|
"@ultraviolet/themes": "1.2.1",
|
|
71
|
-
"@ultraviolet/icons": "1.3.
|
|
71
|
+
"@ultraviolet/icons": "1.3.1"
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import _styled from '@emotion/styled/base';
|
|
2
|
-
import { css } from '@emotion/react';
|
|
3
|
-
import { memo, useEffect, useCallback, isValidElement, useRef, cloneElement } from 'react';
|
|
4
|
-
import { useDialogState, DialogBackdrop, Dialog, DialogDisclosure } from 'reakit/Dialog';
|
|
5
|
-
import { Button } from '../Button/index.js';
|
|
6
|
-
import { jsxs, Fragment, jsx } from '@emotion/react/jsx-runtime';
|
|
7
|
-
import { unfoldIn, unfoldOut, scaleForward, scaleBack, scaleUp, scaleDown, sketchIn, sketchOut, slideFromBottom, slideToBottom, slideFromLeft, slideToLeft, slideFromRight, slideToRight, slideFromTop, slideToTop, zoomIn, zoomOut } from '../../utils/animations.js';
|
|
8
|
-
|
|
9
|
-
function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
|
|
10
|
-
const MODAL_WIDTH = {
|
|
11
|
-
large: 850,
|
|
12
|
-
medium: 708,
|
|
13
|
-
small: 616,
|
|
14
|
-
xsmall: 400,
|
|
15
|
-
xxsmall: 360
|
|
16
|
-
};
|
|
17
|
-
const MODAL_PLACEMENT = {
|
|
18
|
-
bottom: `
|
|
19
|
-
margin: auto;
|
|
20
|
-
margin-bottom: 0;
|
|
21
|
-
`,
|
|
22
|
-
'bottom-left': `
|
|
23
|
-
margin: auto;
|
|
24
|
-
margin-left: 0;
|
|
25
|
-
margin-bottom: 0;
|
|
26
|
-
`,
|
|
27
|
-
'bottom-right': `
|
|
28
|
-
margin: auto;
|
|
29
|
-
margin-right: 0;
|
|
30
|
-
margin-bottom: 0;
|
|
31
|
-
`,
|
|
32
|
-
center: `
|
|
33
|
-
margin: auto;
|
|
34
|
-
`,
|
|
35
|
-
left: `
|
|
36
|
-
margin: auto;
|
|
37
|
-
margin-left: 0;
|
|
38
|
-
`,
|
|
39
|
-
right: `
|
|
40
|
-
margin: auto;
|
|
41
|
-
margin-right: 0;
|
|
42
|
-
`,
|
|
43
|
-
top: `
|
|
44
|
-
margin: auto;
|
|
45
|
-
margin-top: 0px;
|
|
46
|
-
`,
|
|
47
|
-
'top-left': `
|
|
48
|
-
margin: auto;
|
|
49
|
-
margin-left: 0;
|
|
50
|
-
margin-top: 0;
|
|
51
|
-
`,
|
|
52
|
-
'top-right': `
|
|
53
|
-
margin: auto;
|
|
54
|
-
margin-right: 0;
|
|
55
|
-
margin-top: 0;
|
|
56
|
-
`
|
|
57
|
-
};
|
|
58
|
-
const MODAL_ANIMATION = {
|
|
59
|
-
fold: {
|
|
60
|
-
enter: unfoldIn,
|
|
61
|
-
leave: unfoldOut
|
|
62
|
-
},
|
|
63
|
-
scaleBack: {
|
|
64
|
-
enter: scaleForward,
|
|
65
|
-
leave: scaleBack
|
|
66
|
-
},
|
|
67
|
-
scaleUp: {
|
|
68
|
-
enter: scaleUp,
|
|
69
|
-
leave: scaleDown
|
|
70
|
-
},
|
|
71
|
-
sketch: {
|
|
72
|
-
enter: sketchIn,
|
|
73
|
-
leave: sketchOut
|
|
74
|
-
},
|
|
75
|
-
slideBottom: {
|
|
76
|
-
enter: slideFromBottom,
|
|
77
|
-
leave: slideToBottom
|
|
78
|
-
},
|
|
79
|
-
slideLeft: {
|
|
80
|
-
enter: slideFromLeft,
|
|
81
|
-
leave: slideToLeft
|
|
82
|
-
},
|
|
83
|
-
slideRight: {
|
|
84
|
-
enter: slideFromRight,
|
|
85
|
-
leave: slideToRight
|
|
86
|
-
},
|
|
87
|
-
slideTop: {
|
|
88
|
-
enter: slideFromTop,
|
|
89
|
-
leave: slideToTop
|
|
90
|
-
},
|
|
91
|
-
zoom: {
|
|
92
|
-
enter: zoomIn,
|
|
93
|
-
leave: zoomOut
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
const backdropAnimatedStyle = `
|
|
97
|
-
opacity: 0;
|
|
98
|
-
transition: opacity 250ms ease-in-out;
|
|
99
|
-
&[data-enter] {
|
|
100
|
-
opacity: 1;
|
|
101
|
-
transition: opacity 250ms ease-in-out;
|
|
102
|
-
}
|
|
103
|
-
&[data-leave] {
|
|
104
|
-
opacity: 0;
|
|
105
|
-
transition: opacity 400ms ease-in-out;
|
|
106
|
-
}
|
|
107
|
-
`;
|
|
108
|
-
const dialogAnimatedStyle = _ref => {
|
|
109
|
-
let {
|
|
110
|
-
animation
|
|
111
|
-
} = _ref;
|
|
112
|
-
return /*#__PURE__*/css("opacity:0;&[data-enter]{opacity:1;transition:opacity 500ms ease-in-out;animation:", MODAL_ANIMATION[animation].enter, " 500ms cubic-bezier(0.165, 0.84, 0.44, 1) forwards;}&[data-leave]{opacity:0;transition:opacity 500ms ease-in-out;animation:", MODAL_ANIMATION[animation].leave, " 500ms cubic-bezier(0.165, 0.84, 0.44, 1) forwards;}");
|
|
113
|
-
};
|
|
114
|
-
const Disclosure = _ref2 => {
|
|
115
|
-
let {
|
|
116
|
-
disclosure,
|
|
117
|
-
dialog
|
|
118
|
-
} = _ref2;
|
|
119
|
-
// if you need dialog inside your component, use function, otherwise component is fine
|
|
120
|
-
const target = /*#__PURE__*/isValidElement(disclosure) ? disclosure : disclosure(dialog);
|
|
121
|
-
const innerRef = useRef(target);
|
|
122
|
-
return (
|
|
123
|
-
// @ts-expect-error reakit types are invalid, no need to pass as something, default is div
|
|
124
|
-
jsx(DialogDisclosure, {
|
|
125
|
-
...dialog,
|
|
126
|
-
onClick: event => {
|
|
127
|
-
// This allow to use onClick for speficique case like traking.
|
|
128
|
-
target?.props?.onClick?.(event);
|
|
129
|
-
},
|
|
130
|
-
ref: innerRef,
|
|
131
|
-
children: disclosureProps => /*#__PURE__*/cloneElement(target, disclosureProps)
|
|
132
|
-
})
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
const MemoDisclosure = /*#__PURE__*/memo(Disclosure);
|
|
136
|
-
const StyledDialogBackdrop = /*#__PURE__*/_styled(DialogBackdrop, {
|
|
137
|
-
target: "ebywm9u2"
|
|
138
|
-
})("display:flex;position:fixed;overflow:auto;padding:16px;top:0;bottom:0;right:0;left:0;opacity:1;background-color:", _ref3 => {
|
|
139
|
-
let {
|
|
140
|
-
theme
|
|
141
|
-
} = _ref3;
|
|
142
|
-
return theme.colors.overlay;
|
|
143
|
-
}, ";", _ref4 => {
|
|
144
|
-
let {
|
|
145
|
-
animated
|
|
146
|
-
} = _ref4;
|
|
147
|
-
return animated && backdropAnimatedStyle;
|
|
148
|
-
}, ";");
|
|
149
|
-
const StyledDialog = /*#__PURE__*/_styled(Dialog, {
|
|
150
|
-
shouldForwardProp: prop => !['animation', 'placement', 'width', 'height', 'bordered'].includes(prop),
|
|
151
|
-
target: "ebywm9u1"
|
|
152
|
-
})("background-color:", _ref5 => {
|
|
153
|
-
let {
|
|
154
|
-
theme
|
|
155
|
-
} = _ref5;
|
|
156
|
-
return theme.colors.neutral.backgroundWeakElevated;
|
|
157
|
-
}, ";position:relative;border-radius:", _ref6 => {
|
|
158
|
-
let {
|
|
159
|
-
bordered,
|
|
160
|
-
theme
|
|
161
|
-
} = _ref6;
|
|
162
|
-
return bordered ? theme.radii.default : theme.radii.none;
|
|
163
|
-
}, ";border:0;padding:32px;", _ref7 => {
|
|
164
|
-
let {
|
|
165
|
-
placement
|
|
166
|
-
} = _ref7;
|
|
167
|
-
return MODAL_PLACEMENT[placement];
|
|
168
|
-
}, " width:", _ref8 => {
|
|
169
|
-
let {
|
|
170
|
-
width
|
|
171
|
-
} = _ref8;
|
|
172
|
-
return MODAL_WIDTH[width];
|
|
173
|
-
}, "px;min-height:", _ref9 => {
|
|
174
|
-
let {
|
|
175
|
-
height
|
|
176
|
-
} = _ref9;
|
|
177
|
-
return height;
|
|
178
|
-
}, ";box-shadow:", _ref10 => {
|
|
179
|
-
let {
|
|
180
|
-
theme
|
|
181
|
-
} = _ref10;
|
|
182
|
-
return theme.shadows.modal;
|
|
183
|
-
}, ";opacity:1;&::before{content:'';height:100%;width:100%;}", _ref11 => {
|
|
184
|
-
let {
|
|
185
|
-
animated,
|
|
186
|
-
animation
|
|
187
|
-
} = _ref11;
|
|
188
|
-
return animated && dialogAnimatedStyle({
|
|
189
|
-
animation
|
|
190
|
-
});
|
|
191
|
-
}, ";");
|
|
192
|
-
const StyledContainer = /*#__PURE__*/_styled("div", {
|
|
193
|
-
target: "ebywm9u0"
|
|
194
|
-
})(process.env.NODE_ENV === "production" ? {
|
|
195
|
-
name: "et21s3",
|
|
196
|
-
styles: "display:flex;flex-grow:1;flex-wrap:wrap;justify-content:flex-end;position:absolute;top:16px;right:16px;left:16px"
|
|
197
|
-
} : {
|
|
198
|
-
name: "et21s3",
|
|
199
|
-
styles: "display:flex;flex-grow:1;flex-wrap:wrap;justify-content:flex-end;position:absolute;top:16px;right:16px;left:16px",
|
|
200
|
-
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
201
|
-
});
|
|
202
|
-
const Modal = /*#__PURE__*/memo(_ref12 => {
|
|
203
|
-
let {
|
|
204
|
-
animated = false,
|
|
205
|
-
animation = 'zoom',
|
|
206
|
-
ariaLabel = 'modal',
|
|
207
|
-
id,
|
|
208
|
-
bordered = true,
|
|
209
|
-
children,
|
|
210
|
-
customDialogBackdropStyles,
|
|
211
|
-
customDialogStyles = {},
|
|
212
|
-
disclosure,
|
|
213
|
-
height = 'initial',
|
|
214
|
-
hideOnClickOutside = true,
|
|
215
|
-
hideOnEsc = true,
|
|
216
|
-
isClosable = true,
|
|
217
|
-
modal = true,
|
|
218
|
-
onClose,
|
|
219
|
-
onBeforeClose,
|
|
220
|
-
opened = false,
|
|
221
|
-
placement = 'center',
|
|
222
|
-
preventBodyScroll = true,
|
|
223
|
-
width = 'small',
|
|
224
|
-
className,
|
|
225
|
-
'data-testid': dataTestId
|
|
226
|
-
} = _ref12;
|
|
227
|
-
const dialog = useDialogState({
|
|
228
|
-
animated,
|
|
229
|
-
baseId: id,
|
|
230
|
-
modal,
|
|
231
|
-
visible: opened
|
|
232
|
-
});
|
|
233
|
-
const {
|
|
234
|
-
setVisible
|
|
235
|
-
} = dialog;
|
|
236
|
-
useEffect(() => setVisible(opened), [setVisible, opened]);
|
|
237
|
-
const onCloseCallBack = useCallback(async () => {
|
|
238
|
-
await onBeforeClose?.();
|
|
239
|
-
dialog.toggle();
|
|
240
|
-
}, [dialog, onBeforeClose]);
|
|
241
|
-
return jsxs(Fragment, {
|
|
242
|
-
children: [disclosure && jsx(MemoDisclosure, {
|
|
243
|
-
dialog: dialog,
|
|
244
|
-
disclosure: disclosure
|
|
245
|
-
}), jsx(StyledDialogBackdrop, {
|
|
246
|
-
...dialog,
|
|
247
|
-
css: customDialogBackdropStyles,
|
|
248
|
-
children: jsx(StyledDialog, {
|
|
249
|
-
"aria-label": ariaLabel,
|
|
250
|
-
role: "dialog",
|
|
251
|
-
tabIndex: 0,
|
|
252
|
-
animation: animation,
|
|
253
|
-
bordered: bordered,
|
|
254
|
-
height: height,
|
|
255
|
-
placement: placement,
|
|
256
|
-
width: width,
|
|
257
|
-
css: customDialogStyles,
|
|
258
|
-
hideOnClickOutside: hideOnClickOutside,
|
|
259
|
-
hideOnEsc: hideOnEsc,
|
|
260
|
-
preventBodyScroll: preventBodyScroll,
|
|
261
|
-
...dialog,
|
|
262
|
-
hide: onClose || onCloseCallBack,
|
|
263
|
-
className: className,
|
|
264
|
-
"data-testid": dataTestId,
|
|
265
|
-
children: jsxs(Fragment, {
|
|
266
|
-
children: [dialog.visible && (typeof children === 'function' ? children(dialog) : children), jsx(StyledContainer, {
|
|
267
|
-
children: isClosable && jsx(Button, {
|
|
268
|
-
"data-testid": dataTestId ? `${dataTestId}-close-button` : undefined,
|
|
269
|
-
onClick: onClose || onCloseCallBack,
|
|
270
|
-
variant: "ghost",
|
|
271
|
-
size: "small",
|
|
272
|
-
icon: "close",
|
|
273
|
-
sentiment: "neutral",
|
|
274
|
-
"aria-label": "close"
|
|
275
|
-
})
|
|
276
|
-
})]
|
|
277
|
-
})
|
|
278
|
-
})
|
|
279
|
-
})]
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
export { MODAL_ANIMATION, MODAL_PLACEMENT, MODAL_WIDTH, Modal };
|