@ultraviolet/ui 1.11.2 → 1.14.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.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +208 -6
  3. package/dist/react-datepicker/dist/react-datepicker.min.css.js +1 -1
  4. package/dist/src/components/ActionBar/index.js +7 -0
  5. package/dist/src/components/Alert/index.js +3 -0
  6. package/dist/src/components/Avatar/index.js +4 -0
  7. package/dist/src/components/Badge/index.js +5 -5
  8. package/dist/src/components/Banner/index.js +3 -0
  9. package/dist/src/components/BarChart/index.js +2 -0
  10. package/dist/src/components/BarStack/index.js +4 -0
  11. package/dist/src/components/Breadcrumbs/index.js +3 -0
  12. package/dist/src/components/Bullet/index.js +3 -0
  13. package/dist/src/components/Button/index.js +8 -1
  14. package/dist/src/components/Card/index.js +4 -0
  15. package/dist/src/components/Carousel/index.js +3 -0
  16. package/dist/src/components/Checkbox/index.js +140 -102
  17. package/dist/src/components/CheckboxGroup/index.js +3 -0
  18. package/dist/src/components/CopyButton/index.js +3 -0
  19. package/dist/src/components/DateInput/index.js +5 -0
  20. package/dist/src/components/EmptyState/index.js +3 -0
  21. package/dist/src/components/Expandable/index.js +6 -0
  22. package/dist/src/components/LineChart/index.js +2 -0
  23. package/dist/src/components/Link/index.js +4 -0
  24. package/dist/src/components/List/index.js +4 -0
  25. package/dist/src/components/Loader/index.js +4 -0
  26. package/dist/src/components/Menu/index.js +7 -0
  27. package/dist/src/components/Meter/{Meter.js → index.js} +6 -3
  28. package/dist/src/components/Modal/Dialog.js +4 -2
  29. package/dist/src/components/Modal/{Modal.js → index.js} +6 -1
  30. package/dist/src/components/Notice/index.js +3 -0
  31. package/dist/src/components/NumberInput/index.js +4 -0
  32. package/dist/src/components/Pagination/index.js +2 -1
  33. package/dist/src/components/PasswordCheck/index.js +5 -0
  34. package/dist/src/components/PasswordStrengthMeter/index.js +1 -0
  35. package/dist/src/components/PieChart/index.js +2 -0
  36. package/dist/src/components/Popover/index.js +4 -0
  37. package/dist/src/components/ProgressBar/index.js +3 -0
  38. package/dist/src/components/Radio/index.js +44 -36
  39. package/dist/src/components/RadioGroup/index.js +3 -0
  40. package/dist/src/components/Row/index.js +4 -0
  41. package/dist/src/components/SelectInput/index.js +4 -0
  42. package/dist/src/components/SelectableCard/index.js +4 -0
  43. package/dist/src/components/Separator/index.js +3 -0
  44. package/dist/src/components/Skeleton/index.js +5 -0
  45. package/dist/src/components/Snippet/index.js +4 -0
  46. package/dist/src/components/Stack/index.js +9 -1
  47. package/dist/src/components/Status/index.js +3 -0
  48. package/dist/src/components/StepList/index.js +1 -0
  49. package/dist/src/components/Stepper/index.js +3 -0
  50. package/dist/src/components/SwitchButton/index.js +3 -0
  51. package/dist/src/components/Table/index.js +4 -0
  52. package/dist/src/components/Tabs/index.js +4 -0
  53. package/dist/src/components/Tag/index.js +5 -0
  54. package/dist/src/components/TagInput/index.js +1 -0
  55. package/dist/src/components/TagList/index.js +4 -0
  56. package/dist/src/components/Text/index.js +4 -0
  57. package/dist/src/components/TextInput/index.js +5 -0
  58. package/dist/src/components/TimeInput/index.js +2 -0
  59. package/dist/src/components/Toaster/index.js +8 -0
  60. package/dist/src/components/Toggle/index.js +3 -0
  61. package/dist/src/components/ToggleGroup/index.js +3 -0
  62. package/dist/src/components/Tooltip/index.js +4 -0
  63. package/dist/src/components/VerificationCode/index.js +4 -0
  64. package/dist/src/index.js +2 -2
  65. package/dist/src/internalComponents/Popup/index.js +47 -7
  66. package/package.json +4 -4
@@ -2,7 +2,8 @@ import _styled from '@emotion/styled/base';
2
2
  import { forwardRef, useId } from 'react';
3
3
  import { Stack } from '../Stack/index.js';
4
4
  import { Text } from '../Text/index.js';
5
- import { jsxs, jsx } from '@emotion/react/jsx-runtime';
5
+ import { Tooltip } from '../Tooltip/index.js';
6
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
6
7
 
7
8
  const SIZE = 24;
8
9
  const InnerCircleRing = /*#__PURE__*/_styled("circle", {
@@ -129,6 +130,9 @@ const MargedText = /*#__PURE__*/_styled(Text, {
129
130
  } = _ref18;
130
131
  return theme.space['4'];
131
132
  }, ";");
133
+ /**
134
+ * Radio component is used to select a single option from a list of options. It is a type of input component.
135
+ */
132
136
  const Radio = /*#__PURE__*/forwardRef((_ref19, ref) => {
133
137
  let {
134
138
  checked = false,
@@ -144,48 +148,52 @@ const Radio = /*#__PURE__*/forwardRef((_ref19, ref) => {
144
148
  className,
145
149
  autoFocus,
146
150
  onKeyDown,
151
+ tooltip,
147
152
  'aria-label': ariaLabel,
148
153
  'data-testid': dataTestId
149
154
  } = _ref19;
150
155
  const id = useId();
151
156
  const computedName = name ?? id;
152
- return jsxs(Stack, {
153
- gap: 0.5,
154
- children: [jsxs(RadioContainer, {
155
- "aria-disabled": disabled,
156
- className: className,
157
- "data-checked": checked,
158
- "data-error": error,
159
- "data-testid": dataTestId,
160
- children: [jsx(RadioInput, {
161
- type: "radio",
162
- "aria-invalid": !!error,
157
+ return jsx(Tooltip, {
158
+ text: tooltip,
159
+ children: jsxs(Stack, {
160
+ gap: 0.5,
161
+ children: [jsxs(RadioContainer, {
163
162
  "aria-disabled": disabled,
164
- "aria-label": ariaLabel,
165
- checked: checked,
166
- id: `${computedName}-${value}`,
167
- onChange: onChange,
168
- onFocus: onFocus,
169
- onKeyDown: onKeyDown,
170
- onBlur: onBlur,
171
- value: value,
172
- disabled: disabled,
173
- name: computedName,
174
- autoFocus: autoFocus,
175
- ref: ref
176
- }), jsx(Ring, {
177
- viewBox: "0 0 24 24",
178
- children: jsx(RadioMarkedIcon, {})
179
- }), label ? jsx("label", {
180
- htmlFor: `${computedName}-${value}`,
181
- children: label
163
+ className: className,
164
+ "data-checked": checked,
165
+ "data-error": error,
166
+ "data-testid": dataTestId,
167
+ children: [jsx(RadioInput, {
168
+ type: "radio",
169
+ "aria-invalid": !!error,
170
+ "aria-disabled": disabled,
171
+ "aria-label": ariaLabel,
172
+ checked: checked,
173
+ id: `${computedName}-${value}`,
174
+ onChange: onChange,
175
+ onFocus: onFocus,
176
+ onKeyDown: onKeyDown,
177
+ onBlur: onBlur,
178
+ value: value,
179
+ disabled: disabled,
180
+ name: computedName,
181
+ autoFocus: autoFocus,
182
+ ref: ref
183
+ }), jsx(Ring, {
184
+ viewBox: "0 0 24 24",
185
+ children: jsx(RadioMarkedIcon, {})
186
+ }), label ? jsx("label", {
187
+ htmlFor: `${computedName}-${value}`,
188
+ children: label
189
+ }) : null]
190
+ }), helper ? jsx(MargedText, {
191
+ as: "p",
192
+ variant: "bodySmall",
193
+ prominence: "weak",
194
+ children: helper
182
195
  }) : null]
183
- }), helper ? jsx(MargedText, {
184
- as: "p",
185
- variant: "bodySmall",
186
- prominence: "weak",
187
- children: helper
188
- }) : null]
196
+ })
189
197
  });
190
198
  });
191
199
 
@@ -70,6 +70,9 @@ const StyledRequiredIcon = /*#__PURE__*/_styled(Icon, {
70
70
  styles: "vertical-align:super",
71
71
  toString: _EMOTION_STRINGIFIED_CSS_ERROR__
72
72
  });
73
+ /**
74
+ * RadioGroup is a component that allows users to select one option from a list of options using radio.
75
+ */
73
76
  const RadioGroup = _ref2 => {
74
77
  let {
75
78
  legend,
@@ -19,6 +19,10 @@ const StyledRow = /*#__PURE__*/_styled('div', {
19
19
  justify-content: ${justifyContent};
20
20
  `;
21
21
  }, ";");
22
+ /**
23
+ * Row component is a wrapper for grid layout.
24
+ * @experimental This component is experimental and may be subject to breaking changes in the future.
25
+ */
22
26
  const Row = _ref2 => {
23
27
  let {
24
28
  className,
@@ -655,6 +655,10 @@ const FwdSelectInput = _ref20 => {
655
655
  "data-testid": dataTestId
656
656
  });
657
657
  };
658
+ /**
659
+ * SelectInput component is a wrapper around [react-select](https://react-select.com) component.
660
+ * It provides a styled select input with a label and an error message.
661
+ */
658
662
  const SelectInput = /*#__PURE__*/forwardRef((props, ref) => jsx(FwdSelectInput, {
659
663
  innerRef: ref,
660
664
  ...props
@@ -104,6 +104,10 @@ const StyledRadio = /*#__PURE__*/StyledElement.withComponent(Radio, {
104
104
  const StyledCheckbox = /*#__PURE__*/StyledElement.withComponent(Checkbox, {
105
105
  target: "e1s5n3hj3"
106
106
  });
107
+ /**
108
+ * SelectableCard is a component that can be used to create a radio or checkbox card.
109
+ * It can be used to create a list of selectable items or a single selectable item.
110
+ */
107
111
  const SelectableCard = /*#__PURE__*/forwardRef((_ref18, ref) => {
108
112
  let {
109
113
  name,
@@ -47,6 +47,9 @@ const StyledHr = /*#__PURE__*/_styled('hr', {
47
47
  } = _ref6;
48
48
  return hasIcon && `flex: 1;`;
49
49
  }, ";");
50
+ /**
51
+ * Separator component used to separate content with a horizontal or vertical line.
52
+ */
50
53
  const Separator = _ref7 => {
51
54
  let {
52
55
  direction = 'horizontal',
@@ -65,6 +65,11 @@ const variants = {
65
65
  list: List,
66
66
  slider: Slider
67
67
  };
68
+ /**
69
+ * Skeleton component is used to indicate that the data is loading.
70
+ * It is used to provide a better user experience by showing a temporary placeholder reflecting the dimensions of the
71
+ * content that will eventually be loaded on the screen.
72
+ */
68
73
  const Skeleton = _ref6 => {
69
74
  let {
70
75
  variant = 'blocks',
@@ -183,6 +183,10 @@ const CodeContent = _ref18 => {
183
183
  })
184
184
  });
185
185
  };
186
+ /**
187
+ * Snippet component is used to display code snippets with the ability to copy the code.
188
+ * It also has the ability to show/hide the code snippet if it has more than 4 lines.
189
+ */
186
190
  const Snippet = _ref19 => {
187
191
  let {
188
192
  children,
@@ -1,5 +1,9 @@
1
1
  import _styled from '@emotion/styled/base';
2
2
 
3
+ /**
4
+ * A Stack is a widget that organize children in a vertical or horizontal layout based on css Flex,
5
+ * it accepts few props to deal with spacing and align.
6
+ */
3
7
  const Stack = /*#__PURE__*/_styled('div', {
4
8
  shouldForwardProp: prop => !['gap', 'direction', 'alignItems', 'justifyContent', 'wrap'].includes(prop),
5
9
  target: "ehpbis70"
@@ -10,7 +14,9 @@ const Stack = /*#__PURE__*/_styled('div', {
10
14
  direction = 'column',
11
15
  alignItems = 'normal',
12
16
  justifyContent = 'normal',
13
- wrap = 'nowrap'
17
+ wrap = 'nowrap',
18
+ width,
19
+ flex
14
20
  } = _ref;
15
21
  return `
16
22
  gap: ${theme.space[gap]};
@@ -18,6 +24,8 @@ const Stack = /*#__PURE__*/_styled('div', {
18
24
  align-items: ${alignItems};
19
25
  justify-content: ${justifyContent};
20
26
  flex-wrap: ${typeof wrap === 'boolean' ? 'wrap' : wrap};
27
+ ${flex ? `flex: ${flex};` : ''}
28
+ ${width ? `width: ${width};` : ''}
21
29
  `;
22
30
  }, ";");
23
31
 
@@ -76,6 +76,9 @@ const StyledAnimatedCircle = /*#__PURE__*/_styled("span", {
76
76
  const Container = /*#__PURE__*/_styled("span", {
77
77
  target: "eny0xmn0"
78
78
  })("display:flex;width:", WIDTH, ";height:", HEIGHT, ";");
79
+ /**
80
+ * Status component used to display a colored circle with a tooltip for additional information.
81
+ */
79
82
  const Status = _ref10 => {
80
83
  let {
81
84
  animated = false,
@@ -62,6 +62,7 @@ const Item = _ref5 => {
62
62
  });
63
63
  };
64
64
  /**
65
+ * StepList component is used to display a list of steps.
65
66
  * @experimental This component is experimental and may be subject to breaking changes in the future.
66
67
  */
67
68
  const StepList = _ref6 => {
@@ -124,6 +124,9 @@ const StepperNumbers = _ref14 => {
124
124
  })]
125
125
  });
126
126
  };
127
+ /**
128
+ * Stepper component to show the progress of a process in a linear way.
129
+ */
127
130
  const Stepper = _ref15 => {
128
131
  let {
129
132
  children,
@@ -56,6 +56,9 @@ const StyledSelectableCard = /*#__PURE__*/_styled(SelectableCard, {
56
56
  } = _ref9;
57
57
  return theme.colors.primary.textWeak;
58
58
  }, ";}}");
59
+ /**
60
+ * SwitchButton is a component that allows the user to select between two options.
61
+ */
59
62
  const SwitchButton = _ref10 => {
60
63
  let {
61
64
  value,
@@ -73,6 +73,10 @@ const BaseTable = /*#__PURE__*/forwardRef((_ref2, ref) => {
73
73
  })
74
74
  });
75
75
  });
76
+
77
+ /**
78
+ * Table is a component that displays data in a tabular format.
79
+ */
76
80
  const Table = /*#__PURE__*/Object.assign(BaseTable, {
77
81
  Body,
78
82
  Row,
@@ -46,6 +46,10 @@ const TabsContainer = /*#__PURE__*/_styled("div", {
46
46
  return theme.colors.neutral.border;
47
47
  }, ";}&::-webkit-scrollbar{display:none;}");
48
48
  const SHADOW_THRESHOLD = 10;
49
+
50
+ /**
51
+ * Tabs component is used to display a set of tabs with a single tab selected at a time.
52
+ */
49
53
  const Tabs = _ref7 => {
50
54
  let {
51
55
  children = null,
@@ -119,6 +119,11 @@ const TagInner = _ref6 => {
119
119
  }) : null]
120
120
  });
121
121
  };
122
+
123
+ /**
124
+ * Tag component is used to display a short text description of an item. It can be used to display a category
125
+ * or any other metadata.
126
+ */
122
127
  const Tag = _ref7 => {
123
128
  let {
124
129
  children,
@@ -129,6 +129,7 @@ const convertTagArrayToTagStateArray = tags => (tags || [])?.map((tag, index) =>
129
129
  label: tag
130
130
  });
131
131
  /**
132
+ * TagInput is a component that allows users to input tags.
132
133
  * @experimental This component is experimental and may be subject to breaking changes in the future.
133
134
  */
134
135
  const TagInput = _ref9 => {
@@ -43,6 +43,10 @@ const StyledTagContainer = /*#__PURE__*/_styled("div", {
43
43
  }, ";");
44
44
  const DEFAULT_TAGS = [];
45
45
  const getTagLabel = tag => typeof tag === 'object' ? tag.label : tag;
46
+
47
+ /**
48
+ * This component is used to display a list of tags with a threshold and a popover when there are too many tags.
49
+ */
46
50
  const TagList = _ref5 => {
47
51
  let {
48
52
  maxLength = 600,
@@ -54,6 +54,10 @@ const StyledText = /*#__PURE__*/_styled('div', {
54
54
  shouldForwardProp: prop => !['as', 'placement', 'variant', 'sentiment', 'prominence', 'oneLine', 'disabled', 'italic', 'underline'].includes(prop),
55
55
  target: "e13y3mga0"
56
56
  })(generateStyles);
57
+
58
+ /**
59
+ * Text component is used to display text with different variants and sentiments.
60
+ */
57
61
  const Text = _ref2 => {
58
62
  let {
59
63
  variant,
@@ -326,6 +326,11 @@ const UnitLabel = /*#__PURE__*/_styled(Text, {
326
326
  } = _ref33;
327
327
  return theme.space['1'];
328
328
  }, " 0;line-height:18px;");
329
+
330
+ /**
331
+ * TextInput component allows users to input text, with options for customization and validation.
332
+ * It supports various input types and should be appropriately sized with clear labeling.
333
+ */
329
334
  const TextInput = /*#__PURE__*/forwardRef((_ref34, ref) => {
330
335
  let {
331
336
  'data-testid': dataTestId,
@@ -18,6 +18,8 @@ const defaultValue = {
18
18
  value: '00:00'
19
19
  };
20
20
  /**
21
+ * A time input component that allows users to select a time from a dropdown. The component is built on top of the
22
+ * `SelectInput` component.
21
23
  * @experimental This component is experimental and may be subject to breaking changes in the future.
22
24
  */
23
25
  const TimeInput = function (_temp) {
@@ -81,6 +81,14 @@ const toast = {
81
81
  children: children
82
82
  }), options)
83
83
  };
84
+ /**
85
+ * Display short information about an event that happen in the interface in a floating alert.
86
+ * Toaster is based on **react-tostify**, you can find a complete documentation
87
+ * [here](https://fkhadra.github.io/react-toastify/introduction/).
88
+ *
89
+ * Toaster is separated in two parts, first the `ToastContainer` which is where the div of the toast will be rendered,
90
+ * and second the `toast()` function which is used to display the toast.
91
+ */
84
92
  const ToastContainer = _ref5 => {
85
93
  let {
86
94
  newestOnTop,
@@ -153,6 +153,9 @@ const RequiredIcon = () => jsx("sup", {
153
153
  color: "danger"
154
154
  })
155
155
  });
156
+ /**
157
+ * Toggle component is used to toggle between two states (on/off, true/false, etc.).
158
+ */
156
159
  const Toggle = /*#__PURE__*/forwardRef((_ref23, ref) => {
157
160
  let {
158
161
  checked = false,
@@ -8,6 +8,9 @@ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
8
8
 
9
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
10
  const ToggleGroupContext = /*#__PURE__*/createContext(undefined);
11
+ /**
12
+ * ToggleGroup is a component that allows you to group a set of Toggle components together under the same legend.
13
+ */
11
14
  const ToggleGroupToggle = _ref => {
12
15
  let {
13
16
  disabled,
@@ -2,6 +2,10 @@ import { forwardRef } from 'react';
2
2
  import { jsx } from '@emotion/react/jsx-runtime';
3
3
  import { Popup } from '../../internalComponents/Popup/index.js';
4
4
 
5
+ /**
6
+ * Tooltip component is used to display additional information on hover or focus.
7
+ * It is used to explain the purpose of the element it is attached to.
8
+ */
5
9
  const Tooltip = /*#__PURE__*/forwardRef((_ref, tooltipRef) => {
6
10
  let {
7
11
  children,
@@ -52,6 +52,10 @@ const StyledInput = /*#__PURE__*/_styled("input", {
52
52
  return theme.colors.neutral.textWeak;
53
53
  }, ";}");
54
54
  const DEFAULT_ON_FUNCTION = () => {};
55
+
56
+ /**
57
+ * Verification code allows you to enter a code in multiple fields (4 by default).
58
+ */
55
59
  const VerificationCode = _ref9 => {
56
60
  let {
57
61
  disabled = false,
package/dist/src/index.js CHANGED
@@ -27,8 +27,8 @@ export { Link } from './components/Link/index.js';
27
27
  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
- export { Meter } from './components/Meter/Meter.js';
31
- export { Modal } from './components/Modal/Modal.js';
30
+ export { Meter } from './components/Meter/index.js';
31
+ export { Modal } from './components/Modal/index.js';
32
32
  export { Notice } from './components/Notice/index.js';
33
33
  export { CheckboxGroup, CheckboxGroupCheckbox } from './components/CheckboxGroup/index.js';
34
34
  export { NumberInput } from './components/NumberInput/index.js';
@@ -57,7 +57,7 @@ const StyledTooltip = /*#__PURE__*/_styled('div', {
57
57
  maxWidth
58
58
  } = _ref5;
59
59
  return maxWidth;
60
- }, "px;word-break:break-all;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
60
+ }, "px;overflow-wrap:break-word;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
61
61
  let {
62
62
  positions
63
63
  } = _ref6;
@@ -117,7 +117,8 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
117
117
  innerRef,
118
118
  role = 'tooltip',
119
119
  'data-testid': dataTestId,
120
- hasArrow = true
120
+ hasArrow = true,
121
+ onClose
121
122
  } = _ref13;
122
123
  const childrenRef = useRef(null);
123
124
  useImperativeHandle(innerRef, () => childrenRef.current);
@@ -161,6 +162,20 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
161
162
  window.removeEventListener('scroll', onScrollDetected, true);
162
163
  }, [onScrollDetected]);
163
164
 
165
+ /**
166
+ * This function is called when we need to hide tooltip. A timeout is set to allow animation end, then remove
167
+ * tooltip from dom.
168
+ */
169
+ const hideTooltip = useCallback(() => {
170
+ debounceTimer.current = setTimeout(() => {
171
+ setReverseAnimation(true);
172
+ timer.current = setTimeout(() => {
173
+ unmountTooltip();
174
+ onClose?.();
175
+ }, ANIMATION_DURATION);
176
+ }, 200);
177
+ }, [onClose, unmountTooltip]);
178
+
164
179
  /**
165
180
  * When mouse hover or stop hovering children this function display or hide tooltip. A timeout is set to allow animation
166
181
  * end, then remove tooltip from dom.
@@ -170,10 +185,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
170
185
  // There is debounce in order to avoid tooltip to flicker when we move the mouse from children to tooltip
171
186
  // Timer is used to follow the animation duration
172
187
  if (!isVisible && innerTooltipRef.current && !debounceTimer.current) {
173
- debounceTimer.current = setTimeout(() => {
174
- setReverseAnimation(true);
175
- timer.current = setTimeout(() => unmountTooltip(), ANIMATION_DURATION);
176
- }, 200);
188
+ hideTooltip();
177
189
  } else if (isVisible) {
178
190
  // This condition is for when we want to mount the tooltip
179
191
  // If the timer exists it means the tooltip was about to umount, but we hovered the children again,
@@ -191,7 +203,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
191
203
  }
192
204
  setVisibleInDom(true);
193
205
  }
194
- }, [innerTooltipRef, unmountTooltip]);
206
+ }, [hideTooltip, innerTooltipRef]);
195
207
 
196
208
  /**
197
209
  * Once tooltip is visible in the dom we can compute positions, then set it visible on screen and add event to
@@ -229,6 +241,33 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
229
241
  }
230
242
  }, [unmountTooltip]);
231
243
 
244
+ // Handle hide on esc press
245
+ useEffect(() => {
246
+ const handleEscPress = event => {
247
+ if (event.key === 'Escape') {
248
+ event.preventDefault();
249
+ event.stopPropagation();
250
+ hideTooltip();
251
+ }
252
+ };
253
+ if (visibleInDom) {
254
+ document.body.addEventListener('keyup', handleEscPress, {
255
+ capture: true
256
+ });
257
+ document.body.addEventListener('keydown', handleEscPress, {
258
+ capture: true
259
+ });
260
+ }
261
+ return () => {
262
+ document.body.removeEventListener('keyup', handleEscPress, {
263
+ capture: true
264
+ });
265
+ document.body.addEventListener('keydown', handleEscPress, {
266
+ capture: true
267
+ });
268
+ };
269
+ }, [hideTooltip, onClose, unmountTooltip, visibleInDom]);
270
+
232
271
  /**
233
272
  * Will render children conditionally if children is a function or not.
234
273
  */
@@ -244,6 +283,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
244
283
  }
245
284
  return jsx(StyledChildrenContainer, {
246
285
  "aria-describedby": generatedId,
286
+ "aria-controls": generatedId,
247
287
  onBlur: !isControlled ? onPointerEvent(false) : noop,
248
288
  onFocus: !isControlled ? onPointerEvent(true) : noop,
249
289
  onPointerEnter: !isControlled ? onPointerEvent(true) : noop,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultraviolet/ui",
3
- "version": "1.11.2",
3
+ "version": "1.14.0",
4
4
  "description": "Ultraviolet UI",
5
5
  "homepage": "https://github.com/scaleway/ultraviolet#readme",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  "react-dom": "18.2.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@babel/core": "7.22.15",
42
+ "@babel/core": "7.22.17",
43
43
  "@emotion/babel-plugin": "11.11.0",
44
44
  "@emotion/react": "11.11.1",
45
45
  "@emotion/styled": "11.11.0",
@@ -61,13 +61,13 @@
61
61
  "@scaleway/use-media": "2.0.1",
62
62
  "deepmerge": "4.3.1",
63
63
  "prop-types": "15.8.1",
64
- "react-datepicker": "4.16.0",
64
+ "react-datepicker": "4.17.0",
65
65
  "react-flatten-children": "1.1.2",
66
66
  "react-select": "5.7.4",
67
67
  "react-toastify": "9.1.3",
68
68
  "react-use-clipboard": "1.0.9",
69
69
  "reakit": "1.3.11",
70
70
  "@ultraviolet/themes": "1.2.1",
71
- "@ultraviolet/icons": "2.0.1"
71
+ "@ultraviolet/icons": "2.0.2"
72
72
  }
73
73
  }