@ultraviolet/ui 1.17.0 → 1.18.0
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 +6 -0
- package/dist/src/components/Checkbox/index.js +13 -10
- package/dist/src/components/MenuV2/index.js +2 -0
- package/dist/src/components/Modal/Dialog.js +20 -28
- package/dist/src/components/Popover/index.js +2 -11
- package/dist/src/components/Skeleton/Square.js +12 -0
- package/dist/src/components/Skeleton/index.js +7 -5
- package/dist/src/internalComponents/Popup/index.js +23 -18
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -1769,6 +1769,8 @@ type PopupProps = {
|
|
|
1769
1769
|
tabIndex?: number;
|
|
1770
1770
|
onKeyDown?: KeyboardEventHandler;
|
|
1771
1771
|
'aria-haspopup'?: HTMLAttributes<HTMLDivElement>['aria-haspopup'];
|
|
1772
|
+
hideOnClickOutside?: boolean;
|
|
1773
|
+
needDebounce?: boolean;
|
|
1772
1774
|
};
|
|
1773
1775
|
declare const Popup: react.ForwardRefExoticComponent<PopupProps & react.RefAttributes<HTMLDivElement>>;
|
|
1774
1776
|
|
|
@@ -1975,6 +1977,10 @@ declare const variants$1: {
|
|
|
1975
1977
|
readonly slider: ({ length }: {
|
|
1976
1978
|
length?: number | undefined;
|
|
1977
1979
|
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
1980
|
+
readonly square: _emotion_styled.StyledComponent<{
|
|
1981
|
+
theme?: _emotion_react.Theme | undefined;
|
|
1982
|
+
as?: react.ElementType<any> | undefined;
|
|
1983
|
+
}, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
1978
1984
|
};
|
|
1979
1985
|
type SkeletonVariant = keyof typeof variants$1;
|
|
1980
1986
|
type SkeletonProps = {
|
|
@@ -41,10 +41,10 @@ const CheckboxIconContainer = _ref4 => {
|
|
|
41
41
|
const theme = useTheme();
|
|
42
42
|
return jsxs("g", {
|
|
43
43
|
children: [jsx(InnerCheckbox, {
|
|
44
|
-
x: "
|
|
45
|
-
y: "
|
|
46
|
-
width: "
|
|
47
|
-
height: "
|
|
44
|
+
x: "4",
|
|
45
|
+
y: "4",
|
|
46
|
+
width: "16",
|
|
47
|
+
height: "16",
|
|
48
48
|
rx: theme.radii.small,
|
|
49
49
|
strokeWidth: "2"
|
|
50
50
|
}), children]
|
|
@@ -129,11 +129,11 @@ const CheckboxInput = /*#__PURE__*/_styled('input', {
|
|
|
129
129
|
theme
|
|
130
130
|
} = _ref18;
|
|
131
131
|
return theme.colors.danger.background;
|
|
132
|
-
}, ";outline:
|
|
132
|
+
}, ";outline:1px solid ", _ref19 => {
|
|
133
133
|
let {
|
|
134
134
|
theme
|
|
135
135
|
} = _ref19;
|
|
136
|
-
return theme.
|
|
136
|
+
return theme.shadows.focusPrimary;
|
|
137
137
|
}, ";", InnerCheckbox, "{stroke:", _ref20 => {
|
|
138
138
|
let {
|
|
139
139
|
theme
|
|
@@ -154,11 +154,11 @@ const CheckboxInput = /*#__PURE__*/_styled('input', {
|
|
|
154
154
|
theme
|
|
155
155
|
} = _ref23;
|
|
156
156
|
return theme.colors.danger.background;
|
|
157
|
-
}, ";outline:
|
|
157
|
+
}, ";outline:1px solid ", _ref24 => {
|
|
158
158
|
let {
|
|
159
159
|
theme
|
|
160
160
|
} = _ref24;
|
|
161
|
-
return theme.
|
|
161
|
+
return theme.shadows.focusDanger;
|
|
162
162
|
}, ";", InnerCheckbox, "{stroke:", _ref25 => {
|
|
163
163
|
let {
|
|
164
164
|
theme
|
|
@@ -445,12 +445,15 @@ const Checkbox = /*#__PURE__*/forwardRef((_ref64, ref) => {
|
|
|
445
445
|
}), !progress ? jsx(StyledIcon, {
|
|
446
446
|
size: size,
|
|
447
447
|
viewBox: "0 0 24 24",
|
|
448
|
+
fill: "none",
|
|
448
449
|
children: jsx(CheckboxIconContainer, {
|
|
449
450
|
children: state !== 'indeterminate' ? jsx("path", {
|
|
450
451
|
fillRule: "evenodd",
|
|
451
452
|
clipRule: "evenodd",
|
|
452
|
-
width:
|
|
453
|
-
height:
|
|
453
|
+
width: 12,
|
|
454
|
+
height: 9,
|
|
455
|
+
x: "5",
|
|
456
|
+
y: "4",
|
|
454
457
|
d: "M15.6678 5.26709C16.0849 5.6463 16.113 6.28907 15.7307 6.70276L9.29172 13.6705C9.10291 13.8748 8.83818 13.9937 8.55884 13.9998C8.2795 14.0058 8.0098 13.8984 7.81223 13.7024L4.30004 10.2185C3.89999 9.82169 3.89999 9.17831 4.30004 8.78149C4.70009 8.38467 5.34869 8.38467 5.74874 8.78149L8.50441 11.5149L14.2205 5.32951C14.6028 4.91583 15.2508 4.88788 15.6678 5.26709Z",
|
|
455
458
|
fill: "white"
|
|
456
459
|
}) : jsx(CheckMixedMark, {
|
|
@@ -94,33 +94,12 @@ const Dialog = _ref9 => {
|
|
|
94
94
|
onCloseRef.current = onClose;
|
|
95
95
|
}, [onClose]);
|
|
96
96
|
|
|
97
|
-
//
|
|
97
|
+
// On open focus the modal
|
|
98
98
|
useEffect(() => {
|
|
99
|
-
const handleEscPress = event => {
|
|
100
|
-
if (event.key === 'Escape' && hideOnEsc) {
|
|
101
|
-
event.preventDefault();
|
|
102
|
-
event.stopPropagation();
|
|
103
|
-
onCloseRef.current();
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
99
|
if (open) {
|
|
107
100
|
dialogRef.current?.focus();
|
|
108
|
-
document.body.addEventListener('keyup', handleEscPress, {
|
|
109
|
-
capture: true
|
|
110
|
-
});
|
|
111
|
-
document.body.addEventListener('keydown', handleEscPress, {
|
|
112
|
-
capture: true
|
|
113
|
-
});
|
|
114
101
|
}
|
|
115
|
-
|
|
116
|
-
document.body.removeEventListener('keyup', handleEscPress, {
|
|
117
|
-
capture: true
|
|
118
|
-
});
|
|
119
|
-
document.body.removeEventListener('keydown', handleEscPress, {
|
|
120
|
-
capture: true
|
|
121
|
-
});
|
|
122
|
-
};
|
|
123
|
-
}, [open, onCloseRef, hideOnEsc]);
|
|
102
|
+
}, [open]);
|
|
124
103
|
|
|
125
104
|
// Handle body scroll
|
|
126
105
|
useEffect(() => {
|
|
@@ -143,10 +122,23 @@ const Dialog = _ref9 => {
|
|
|
143
122
|
event.stopPropagation();
|
|
144
123
|
}, []);
|
|
145
124
|
|
|
146
|
-
//
|
|
147
|
-
const
|
|
125
|
+
// handle key up : used when having inputs in modals - useful for hideOnEsc
|
|
126
|
+
const handleKeyUp = useCallback(event => {
|
|
148
127
|
event.stopPropagation();
|
|
149
|
-
|
|
128
|
+
if (event.key === 'Escape' && hideOnEsc) {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
onCloseRef.current();
|
|
131
|
+
}
|
|
132
|
+
}, [hideOnEsc]);
|
|
133
|
+
const handleClose = useCallback(event => {
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
if (hideOnClickOutside) {
|
|
136
|
+
onCloseRef.current();
|
|
137
|
+
} else {
|
|
138
|
+
// Because overlay is not focusable we can't handle hideOnEsc properly
|
|
139
|
+
dialogRef.current?.focus();
|
|
140
|
+
}
|
|
141
|
+
}, [hideOnClickOutside]);
|
|
150
142
|
|
|
151
143
|
// Enable focus trap inside the modal
|
|
152
144
|
const handleFocusTrap = useCallback(event => {
|
|
@@ -185,14 +177,14 @@ const Dialog = _ref9 => {
|
|
|
185
177
|
};
|
|
186
178
|
return /*#__PURE__*/createPortal(jsx(StyledBackdrop, {
|
|
187
179
|
"data-open": open,
|
|
188
|
-
onClick:
|
|
180
|
+
onClick: handleClose,
|
|
189
181
|
className: backdropClassName,
|
|
190
182
|
css: backdropCss,
|
|
191
183
|
"data-testid": dataTestId ? `${dataTestId}-backdrop` : undefined,
|
|
192
184
|
onFocus: stopFocus,
|
|
193
185
|
children: jsx(StyledDialog, {
|
|
194
186
|
css: dialogCss,
|
|
195
|
-
onKeyUp:
|
|
187
|
+
onKeyUp: handleKeyUp,
|
|
196
188
|
onKeyDown: handleFocusTrap,
|
|
197
189
|
className: className,
|
|
198
190
|
id: id,
|
|
@@ -118,17 +118,6 @@ const Popover = _ref6 => {
|
|
|
118
118
|
useEffect(() => {
|
|
119
119
|
setLocalVisible(visible);
|
|
120
120
|
}, [visible]);
|
|
121
|
-
const handleClickOutside = useCallback(event => {
|
|
122
|
-
if (ref.current && !ref.current.contains(event.target)) {
|
|
123
|
-
onClose?.();
|
|
124
|
-
}
|
|
125
|
-
}, [onClose]);
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
document.addEventListener('click', handleClickOutside, true);
|
|
128
|
-
return () => {
|
|
129
|
-
document.removeEventListener('click', handleClickOutside, true);
|
|
130
|
-
};
|
|
131
|
-
}, [handleClickOutside]);
|
|
132
121
|
|
|
133
122
|
// When space key is pressed we show the popover
|
|
134
123
|
const onKeyDownSpace = useCallback(event => {
|
|
@@ -146,6 +135,8 @@ const Popover = _ref6 => {
|
|
|
146
135
|
innerRef.current?.focus();
|
|
147
136
|
}, [onClose]);
|
|
148
137
|
return jsx(StyledPopup, {
|
|
138
|
+
hideOnClickOutside: true,
|
|
139
|
+
needDebounce: false,
|
|
149
140
|
visible: localVisible,
|
|
150
141
|
placement: placement,
|
|
151
142
|
text: jsx(ContentWrapper, {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import _styled from '@emotion/styled/base';
|
|
2
|
+
|
|
3
|
+
const Square = /*#__PURE__*/_styled("div", {
|
|
4
|
+
target: "e1uz28830"
|
|
5
|
+
})("height:100%;width:100%;max-width:100%;background-color:", _ref => {
|
|
6
|
+
let {
|
|
7
|
+
theme
|
|
8
|
+
} = _ref;
|
|
9
|
+
return theme.colors.neutral.borderWeak;
|
|
10
|
+
}, ";");
|
|
11
|
+
|
|
12
|
+
export { Square };
|
|
@@ -7,6 +7,7 @@ import { Donut } from './Donut.js';
|
|
|
7
7
|
import { Line } from './Line.js';
|
|
8
8
|
import { List } from './List.js';
|
|
9
9
|
import { Slider } from './Slider.js';
|
|
10
|
+
import { Square } from './Square.js';
|
|
10
11
|
import { jsxs, jsx } from '@emotion/react/jsx-runtime';
|
|
11
12
|
|
|
12
13
|
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)."; }
|
|
@@ -21,11 +22,11 @@ const shineAnimation = keyframes`
|
|
|
21
22
|
const StyledContainer = /*#__PURE__*/_styled("div", {
|
|
22
23
|
target: "e183x2r81"
|
|
23
24
|
})(process.env.NODE_ENV === "production" ? {
|
|
24
|
-
name: "
|
|
25
|
-
styles: "position:relative;
|
|
25
|
+
name: "158ltsb",
|
|
26
|
+
styles: "position:relative;width:100%;overflow:hidden;cursor:progress;display:flex;flex-flow:column;height:100%"
|
|
26
27
|
} : {
|
|
27
|
-
name: "
|
|
28
|
-
styles: "position:relative;
|
|
28
|
+
name: "158ltsb",
|
|
29
|
+
styles: "position:relative;width:100%;overflow:hidden;cursor:progress;display:flex;flex-flow:column;height:100%",
|
|
29
30
|
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
30
31
|
});
|
|
31
32
|
const StyledDiv = /*#__PURE__*/_styled("div", {
|
|
@@ -63,7 +64,8 @@ const variants = {
|
|
|
63
64
|
donut: Donut,
|
|
64
65
|
line: Line,
|
|
65
66
|
list: List,
|
|
66
|
-
slider: Slider
|
|
67
|
+
slider: Slider,
|
|
68
|
+
square: Square
|
|
67
69
|
};
|
|
68
70
|
/**
|
|
69
71
|
* Skeleton component is used to indicate that the data is loading.
|
|
@@ -7,7 +7,7 @@ import { jsx, Fragment, jsxs } from '@emotion/react/jsx-runtime';
|
|
|
7
7
|
|
|
8
8
|
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)."; }
|
|
9
9
|
const ANIMATION_DURATION = 230; // in ms
|
|
10
|
-
|
|
10
|
+
const DEBOUNCE_DURATION = 200;
|
|
11
11
|
function noop() {}
|
|
12
12
|
const animation = positions => keyframes`
|
|
13
13
|
0% {
|
|
@@ -121,7 +121,9 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
121
121
|
onClose,
|
|
122
122
|
tabIndex = 0,
|
|
123
123
|
onKeyDown,
|
|
124
|
-
'aria-haspopup': ariaHasPopup
|
|
124
|
+
'aria-haspopup': ariaHasPopup,
|
|
125
|
+
hideOnClickOutside = false,
|
|
126
|
+
needDebounce = true
|
|
125
127
|
} = _ref13;
|
|
126
128
|
const childrenRef = useRef(null);
|
|
127
129
|
useImperativeHandle(innerRef, () => childrenRef.current);
|
|
@@ -176,8 +178,8 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
176
178
|
unmountTooltip();
|
|
177
179
|
onClose?.();
|
|
178
180
|
}, ANIMATION_DURATION);
|
|
179
|
-
},
|
|
180
|
-
}, [onClose, unmountTooltip]);
|
|
181
|
+
}, needDebounce ? DEBOUNCE_DURATION : 0);
|
|
182
|
+
}, [needDebounce, onClose, unmountTooltip]);
|
|
181
183
|
|
|
182
184
|
/**
|
|
183
185
|
* When mouse hover or stop hovering children this function display or hide tooltip. A timeout is set to allow animation
|
|
@@ -244,7 +246,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
244
246
|
}
|
|
245
247
|
}, [unmountTooltip]);
|
|
246
248
|
|
|
247
|
-
// Handle hide on esc press
|
|
249
|
+
// Handle hide on esc press and hide on click outside
|
|
248
250
|
useEffect(() => {
|
|
249
251
|
const handleEscPress = event => {
|
|
250
252
|
if (event.key === 'Escape') {
|
|
@@ -253,23 +255,26 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
|
|
|
253
255
|
hideTooltip();
|
|
254
256
|
}
|
|
255
257
|
};
|
|
258
|
+
const handleClickOutside = event => {
|
|
259
|
+
const tooltipCurrent = innerTooltipRef.current;
|
|
260
|
+
const childrenCurrent = childrenRef.current;
|
|
261
|
+
if (tooltipCurrent && hideOnClickOutside) {
|
|
262
|
+
if (event.target && event.target !== tooltipCurrent && event.target !== childrenCurrent && !childrenCurrent?.contains(event.target) && !tooltipCurrent.contains(event.target)) {
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
event.stopPropagation();
|
|
265
|
+
hideTooltip();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
256
269
|
if (visibleInDom) {
|
|
257
|
-
document.body.addEventListener('keyup', handleEscPress
|
|
258
|
-
|
|
259
|
-
});
|
|
260
|
-
document.body.addEventListener('keydown', handleEscPress, {
|
|
261
|
-
capture: true
|
|
262
|
-
});
|
|
270
|
+
document.body.addEventListener('keyup', handleEscPress);
|
|
271
|
+
document.body.addEventListener('click', handleClickOutside);
|
|
263
272
|
}
|
|
264
273
|
return () => {
|
|
265
|
-
document.body.removeEventListener('keyup', handleEscPress
|
|
266
|
-
|
|
267
|
-
});
|
|
268
|
-
document.body.addEventListener('keydown', handleEscPress, {
|
|
269
|
-
capture: true
|
|
270
|
-
});
|
|
274
|
+
document.body.removeEventListener('keyup', handleEscPress);
|
|
275
|
+
document.body.removeEventListener('click', handleClickOutside);
|
|
271
276
|
};
|
|
272
|
-
}, [hideTooltip,
|
|
277
|
+
}, [hideTooltip, visibleInDom, innerTooltipRef, childrenRef, hideOnClickOutside]);
|
|
273
278
|
|
|
274
279
|
/**
|
|
275
280
|
* Will render children conditionally if children is a function or not.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultraviolet/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
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.
|
|
42
|
+
"@babel/core": "7.23.0",
|
|
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.
|
|
47
|
-
"@types/react-datepicker": "4.15.
|
|
48
|
-
"@types/react-dom": "18.2.
|
|
46
|
+
"@types/react": "18.2.25",
|
|
47
|
+
"@types/react-datepicker": "4.15.1",
|
|
48
|
+
"@types/react-dom": "18.2.10",
|
|
49
49
|
"react": "18.2.0",
|
|
50
50
|
"react-dom": "18.2.0"
|
|
51
51
|
},
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"deepmerge": "4.3.1",
|
|
63
63
|
"react-datepicker": "4.18.0",
|
|
64
64
|
"react-flatten-children": "1.1.2",
|
|
65
|
-
"react-select": "5.7.
|
|
65
|
+
"react-select": "5.7.7",
|
|
66
66
|
"react-toastify": "9.1.3",
|
|
67
67
|
"react-use-clipboard": "1.0.9",
|
|
68
68
|
"reakit": "1.3.11",
|
|
69
69
|
"@ultraviolet/themes": "1.2.1",
|
|
70
|
-
"@ultraviolet/icons": "2.
|
|
70
|
+
"@ultraviolet/icons": "2.2.0"
|
|
71
71
|
}
|
|
72
72
|
}
|