@ultraviolet/ui 1.21.1 → 1.23.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 CHANGED
@@ -1153,12 +1153,14 @@ type BannerProps = {
1153
1153
  linkText?: string;
1154
1154
  linkHref?: string;
1155
1155
  image?: ReactNode;
1156
+ closable?: boolean;
1156
1157
  className?: string;
1158
+ ['data-testid']?: string;
1157
1159
  };
1158
1160
  /**
1159
1161
  * Banner component is used to display an informative message to the user with style.
1160
1162
  */
1161
- declare const Banner: ({ variant, size, title, children, direction, onClose, buttonText, onClickButton, linkText, linkHref, image, className, }: BannerProps) => _emotion_react_jsx_runtime.JSX.Element | null;
1163
+ declare const Banner: ({ variant, size, title, children, direction, onClose, buttonText, onClickButton, linkText, linkHref, image, className, closable, "data-testid": dataTestId, }: BannerProps) => _emotion_react_jsx_runtime.JSX.Element | null;
1162
1164
 
1163
1165
  type BarChartToolTipProps = {
1164
1166
  color: string;
@@ -1951,6 +1953,8 @@ declare const Popover: react.ForwardRefExoticComponent<{
1951
1953
  onClose?: (() => void) | undefined;
1952
1954
  className?: string | undefined;
1953
1955
  'data-testid'?: string | undefined;
1956
+ maxWidth?: string | undefined;
1957
+ maxHeight?: string | undefined;
1954
1958
  } & Pick<{
1955
1959
  id?: string | undefined;
1956
1960
  children: ReactNode | ((renderProps: {
@@ -1961,7 +1965,7 @@ declare const Popover: react.ForwardRefExoticComponent<{
1961
1965
  onPointerLeave: () => void;
1962
1966
  ref: react.RefObject<HTMLDivElement>;
1963
1967
  }) => ReactNode);
1964
- maxWidth?: number | undefined;
1968
+ maxWidth?: string | number | undefined;
1965
1969
  placement?: PopupPlacement | undefined;
1966
1970
  text?: ReactNode;
1967
1971
  className?: string | undefined;
@@ -1977,6 +1981,8 @@ declare const Popover: react.ForwardRefExoticComponent<{
1977
1981
  'aria-haspopup'?: boolean | "menu" | "dialog" | "grid" | "listbox" | "tree" | "false" | "true" | undefined;
1978
1982
  hideOnClickOutside?: boolean | undefined;
1979
1983
  needDebounce?: boolean | undefined;
1984
+ maxHeight?: string | number | undefined;
1985
+ disableAnimation?: boolean | undefined;
1980
1986
  } & react.RefAttributes<HTMLDivElement>, "placement"> & react.RefAttributes<HTMLDivElement>>;
1981
1987
 
1982
1988
  type PopupProps = {
@@ -1992,7 +1998,7 @@ type PopupProps = {
1992
1998
  onPointerLeave: () => void;
1993
1999
  ref: RefObject<HTMLDivElement>;
1994
2000
  }) => ReactNode);
1995
- maxWidth?: number;
2001
+ maxWidth?: number | string;
1996
2002
  /**
1997
2003
  * `auto` placement will change the position of the tooltip if it doesn't fit in the viewport.
1998
2004
  */
@@ -2020,6 +2026,14 @@ type PopupProps = {
2020
2026
  'aria-haspopup'?: HTMLAttributes<HTMLDivElement>['aria-haspopup'];
2021
2027
  hideOnClickOutside?: boolean;
2022
2028
  needDebounce?: boolean;
2029
+ /**
2030
+ * If you set a max height keep in mind that the animation is disabled, or it will not work properly on some browsers.
2031
+ */
2032
+ maxHeight?: string | number;
2033
+ /**
2034
+ * Will remove the animation on the popup if set to false.
2035
+ */
2036
+ disableAnimation?: boolean;
2023
2037
  };
2024
2038
  /**
2025
2039
  * @experimental This component is experimental and may be subject to breaking changes in the future.
@@ -2842,16 +2856,21 @@ type DisclosureProps = {
2842
2856
  type DisclosureElement = ((disclosure: DisclosureProps) => ReactElement<ButtonHTMLAttributes<HTMLButtonElement>>) | (ReactElement<ButtonHTMLAttributes<HTMLButtonElement>> & {
2843
2857
  ref?: Ref<HTMLButtonElement>;
2844
2858
  });
2859
+ type ChildMenuProps = {
2860
+ toggle: () => void;
2861
+ };
2845
2862
  type MenuProps = {
2846
2863
  id?: string;
2847
2864
  ariaLabel?: string;
2848
2865
  placement?: ComponentProps<typeof Popup>['placement'];
2849
- children?: ReactNode;
2866
+ children?: ReactNode | (({ toggle }: ChildMenuProps) => ReactNode);
2850
2867
  className?: string;
2851
2868
  disclosure: DisclosureElement;
2852
2869
  hasArrow?: boolean;
2853
2870
  visible?: boolean;
2854
2871
  'data-testid'?: string;
2872
+ maxHeight?: string;
2873
+ maxWidth?: string;
2855
2874
  };
2856
2875
  /**
2857
2876
  * A menu is a widget that offers a list of choices to the user, such as a set of actions or functions.
@@ -40,7 +40,7 @@ const styles = _ref => {
40
40
  return null;
41
41
  };
42
42
  const Container = /*#__PURE__*/_styled('div', {
43
- shouldForwardProp: prop => !['variant', 'size'].includes(prop),
43
+ shouldForwardProp: prop => !['variant', 'size', 'padding'].includes(prop),
44
44
  target: "e1kdwp5x1"
45
45
  })("padding:", _ref2 => {
46
46
  let {
@@ -100,7 +100,9 @@ const Banner = _ref8 => {
100
100
  linkText,
101
101
  linkHref,
102
102
  image,
103
- className
103
+ className,
104
+ closable = true,
105
+ 'data-testid': dataTestId
104
106
  } = _ref8;
105
107
  const {
106
108
  theme
@@ -112,6 +114,7 @@ const Banner = _ref8 => {
112
114
  variant: variant,
113
115
  size: size,
114
116
  className: className,
117
+ "data-testid": dataTestId,
115
118
  children: [jsx(ImageStack, {
116
119
  size: size,
117
120
  justifyContent: "center",
@@ -165,7 +168,7 @@ const Banner = _ref8 => {
165
168
  children: linkText
166
169
  }) : null]
167
170
  })]
168
- }), jsx(Button, {
171
+ }), closable ? jsx(Button, {
169
172
  icon: "close",
170
173
  size: "small",
171
174
  name: "close",
@@ -175,7 +178,7 @@ const Banner = _ref8 => {
175
178
  setOpened(false);
176
179
  onClose?.();
177
180
  }
178
- })]
181
+ }) : null]
179
182
  });
180
183
  };
181
184
 
@@ -51,7 +51,9 @@ const FwdMenu = /*#__PURE__*/forwardRef((_ref7, ref) => {
51
51
  placement = 'bottom',
52
52
  visible = false,
53
53
  className,
54
- 'data-testid': dataTestId
54
+ 'data-testid': dataTestId,
55
+ maxHeight,
56
+ maxWidth
55
57
  } = _ref7;
56
58
  const [isVisible, setIsVisible] = useState(visible);
57
59
  const popupRef = useRef(null);
@@ -105,11 +107,15 @@ const FwdMenu = /*#__PURE__*/forwardRef((_ref7, ref) => {
105
107
  ref: popupRef,
106
108
  onClose: onClose,
107
109
  tabIndex: -1,
110
+ maxHeight: maxHeight,
111
+ maxWidth: maxWidth,
108
112
  text: jsx(MenuList, {
109
113
  "data-testid": dataTestId,
110
114
  className: className,
111
115
  role: "menu",
112
- children: children
116
+ children: typeof children === 'function' ? children({
117
+ toggle: toggleVisible
118
+ }) : children
113
119
  }),
114
120
  children: finalDisclosure
115
121
  });
@@ -13,7 +13,7 @@ const SIZES_WIDTH = {
13
13
  };
14
14
  const StyledPopup = /*#__PURE__*/_styled(Popup, {
15
15
  shouldForwardProp: prop => !['sentiment', 'size'].includes(prop),
16
- target: "ejpxv5a0"
16
+ target: "ejpxv5a1"
17
17
  })("padding:", _ref => {
18
18
  let {
19
19
  theme
@@ -55,18 +55,28 @@ const StyledPopup = /*#__PURE__*/_styled(Popup, {
55
55
  }
56
56
  `;
57
57
  }, ";");
58
- const ContentWrapper = _ref5 => {
58
+
59
+ // This is to avoid having text inherit color from popup (which is white on white background)
60
+ const StyledStack = /*#__PURE__*/_styled(Stack, {
61
+ target: "ejpxv5a0"
62
+ })("color:", _ref5 => {
63
+ let {
64
+ theme
65
+ } = _ref5;
66
+ return theme.colors.neutral.text;
67
+ }, ";");
68
+ const ContentWrapper = _ref6 => {
59
69
  let {
60
70
  title,
61
71
  onClose,
62
72
  children,
63
73
  sentiment
64
- } = _ref5;
74
+ } = _ref6;
65
75
  const buttonRef = useRef(null);
66
76
  useEffect(() => {
67
77
  buttonRef.current?.focus();
68
78
  }, []);
69
- return jsxs(Stack, {
79
+ return jsxs(StyledStack, {
70
80
  gap: 1,
71
81
  children: [jsxs(Stack, {
72
82
  direction: "row",
@@ -99,7 +109,7 @@ const ContentWrapper = _ref5 => {
99
109
  * Popover component is used to display additional information or actions on top of the main content of the page.
100
110
  * It is usually triggered by clicking on a button. It includes a title, a close button and a content area.
101
111
  */
102
- const Popover = /*#__PURE__*/forwardRef((_ref6, ref) => {
112
+ const Popover = /*#__PURE__*/forwardRef((_ref7, ref) => {
103
113
  let {
104
114
  visible = false,
105
115
  children,
@@ -110,8 +120,10 @@ const Popover = /*#__PURE__*/forwardRef((_ref6, ref) => {
110
120
  size = 'medium',
111
121
  onClose,
112
122
  className,
123
+ maxWidth,
124
+ maxHeight,
113
125
  'data-testid': dataTestId
114
- } = _ref6;
126
+ } = _ref7;
115
127
  const innerRef = useRef(null);
116
128
  const [localVisible, setLocalVisible] = useState(visible);
117
129
 
@@ -155,6 +167,8 @@ const Popover = /*#__PURE__*/forwardRef((_ref6, ref) => {
155
167
  innerRef: innerRef,
156
168
  onClose: localOnClose,
157
169
  onKeyDown: onKeyDownSpace,
170
+ maxWidth: maxWidth,
171
+ maxHeight: maxHeight,
158
172
  children: children
159
173
  });
160
174
  });
@@ -6,8 +6,8 @@ import { DEFAULT_POSITIONS, computePositions, ARROW_WIDTH } from './helpers.js';
6
6
  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
- const ANIMATION_DURATION = 230; // in ms
10
- const DEBOUNCE_DURATION = 200;
9
+ const DEFAULT_ANIMATION_DURATION = 230; // in ms
10
+ const DEFAULT_DEBOUNCE_DURATION = 200;
11
11
  function noop() {}
12
12
  const animation = positions => keyframes`
13
13
  0% {
@@ -30,7 +30,7 @@ const exitAnimation = positions => keyframes`
30
30
  }
31
31
  `;
32
32
  const StyledTooltip = /*#__PURE__*/_styled('div', {
33
- shouldForwardProp: prop => !['maxWidth', 'positions', 'reverseAnimation'].includes(prop),
33
+ shouldForwardProp: prop => !['maxWidth', 'positions', 'reverseAnimation', 'maxHeight', 'animationDuration'].includes(prop),
34
34
  target: "e4h1g861"
35
35
  })("background:", _ref => {
36
36
  let {
@@ -56,42 +56,54 @@ const StyledTooltip = /*#__PURE__*/_styled('div', {
56
56
  let {
57
57
  maxWidth
58
58
  } = _ref5;
59
- return maxWidth;
60
- }, "px;overflow-wrap:break-word;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
59
+ return typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth;
60
+ }, ";max-height:", _ref6 => {
61
61
  let {
62
- positions
62
+ maxHeight
63
63
  } = _ref6;
64
- return positions.tooltipPosition;
65
- }, ";animation:", _ref7 => {
64
+ return typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;
65
+ }, ";overflow:", _ref7 => {
66
66
  let {
67
- positions,
68
- reverseAnimation
67
+ maxHeight
69
68
  } = _ref7;
70
- return /*#__PURE__*/css(ANIMATION_DURATION, "ms ", !reverseAnimation ? animation(positions) : exitAnimation(positions), " forwards;");
71
- }, ";&[data-has-arrow='true']{&::after{content:' ';position:absolute;top:", _ref8 => {
69
+ return maxHeight ? 'auto' : undefined;
70
+ }, ";overflow-wrap:break-word;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref8 => {
72
71
  let {
73
72
  positions
74
73
  } = _ref8;
74
+ return positions.tooltipPosition;
75
+ }, ";animation:", _ref9 => {
76
+ let {
77
+ positions,
78
+ reverseAnimation,
79
+ maxHeight,
80
+ animationDuration
81
+ } = _ref9;
82
+ return maxHeight || animationDuration === 0 || animationDuration === undefined ? undefined : /*#__PURE__*/css(animationDuration, "ms ", !reverseAnimation ? animation(positions) : exitAnimation(positions), " forwards;");
83
+ }, ";&[data-has-arrow='true']{&::after{content:' ';position:absolute;top:", _ref10 => {
84
+ let {
85
+ positions
86
+ } = _ref10;
75
87
  return positions.arrowTop;
76
- }, "px;left:", _ref9 => {
88
+ }, "px;left:", _ref11 => {
77
89
  let {
78
90
  positions
79
- } = _ref9;
91
+ } = _ref11;
80
92
  return positions.arrowLeft;
81
- }, "px;transform:", _ref10 => {
93
+ }, "px;transform:", _ref12 => {
82
94
  let {
83
95
  positions
84
- } = _ref10;
96
+ } = _ref12;
85
97
  return positions.arrowTransform;
86
- }, " rotate(", _ref11 => {
98
+ }, " rotate(", _ref13 => {
87
99
  let {
88
100
  positions
89
- } = _ref11;
101
+ } = _ref13;
90
102
  return positions.rotate;
91
- }, "deg);margin-left:-", ARROW_WIDTH, "px;border-width:", ARROW_WIDTH, "px;border-style:solid;border-color:", _ref12 => {
103
+ }, "deg);margin-left:-", ARROW_WIDTH, "px;border-width:", ARROW_WIDTH, "px;border-style:solid;border-color:", _ref14 => {
92
104
  let {
93
105
  theme
94
- } = _ref12;
106
+ } = _ref14;
95
107
  return theme.colors.neutral.backgroundStronger;
96
108
  }, " transparent transparent transparent;pointer-events:none;}}");
97
109
  const StyledChildrenContainer = /*#__PURE__*/_styled("div", {
@@ -107,7 +119,7 @@ const StyledChildrenContainer = /*#__PURE__*/_styled("div", {
107
119
  /**
108
120
  * @experimental This component is experimental and may be subject to breaking changes in the future.
109
121
  */
110
- const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
122
+ const Popup = /*#__PURE__*/forwardRef((_ref15, ref) => {
111
123
  let {
112
124
  children,
113
125
  text = '',
@@ -116,6 +128,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
116
128
  className,
117
129
  containerFullWidth,
118
130
  maxWidth = 232,
131
+ maxHeight,
119
132
  visible,
120
133
  innerRef,
121
134
  role = 'tooltip',
@@ -126,14 +139,18 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
126
139
  onKeyDown,
127
140
  'aria-haspopup': ariaHasPopup,
128
141
  hideOnClickOutside = false,
129
- needDebounce = true
130
- } = _ref13;
142
+ needDebounce = true,
143
+ disableAnimation = false
144
+ } = _ref15;
131
145
  const childrenRef = useRef(null);
132
146
  useImperativeHandle(innerRef, () => childrenRef.current);
133
147
  const innerTooltipRef = useRef(null);
134
148
  useImperativeHandle(ref, () => innerTooltipRef.current);
135
149
  const timer = useRef();
136
150
 
151
+ // There are some issue when mixing animation and maxHeight on some browsers, so we disable animation if maxHeight is set.
152
+ const animationDuration = disableAnimation || maxHeight ? 0 : DEFAULT_ANIMATION_DURATION;
153
+
137
154
  // Debounce timer will be used to prevent the tooltip from flickering when the user moves the mouse out and in the children element.
138
155
  const debounceTimer = useRef();
139
156
  const [visibleInDom, setVisibleInDom] = useState(false);
@@ -184,9 +201,9 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
184
201
  timer.current = setTimeout(() => {
185
202
  unmountTooltip();
186
203
  onClose?.();
187
- }, ANIMATION_DURATION);
188
- }, needDebounce ? DEBOUNCE_DURATION : 0);
189
- }, [needDebounce, onClose, unmountTooltip]);
204
+ }, animationDuration);
205
+ }, needDebounce && !disableAnimation ? DEFAULT_DEBOUNCE_DURATION : 0);
206
+ }, [animationDuration, disableAnimation, needDebounce, onClose, unmountTooltip]);
190
207
 
191
208
  /**
192
209
  * When mouse hover or stop hovering children this function display or hide tooltip. A timeout is set to allow animation
@@ -334,6 +351,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
334
351
  ref: innerTooltipRef,
335
352
  positions: positions,
336
353
  maxWidth: maxWidth,
354
+ maxHeight: maxHeight,
337
355
  role: role,
338
356
  id: generatedId,
339
357
  className: className,
@@ -341,6 +359,7 @@ const Popup = /*#__PURE__*/forwardRef((_ref13, ref) => {
341
359
  "data-testid": dataTestId,
342
360
  "data-has-arrow": hasArrow,
343
361
  onClick: stopClickPropagation,
362
+ animationDuration: animationDuration,
344
363
  children: text
345
364
  }), document.body) : null]
346
365
  });
@@ -99,26 +99,31 @@ const TagInputContainer = /*#__PURE__*/_styled('div', {
99
99
  }, ";");
100
100
  const StyledInput = /*#__PURE__*/_styled("input", {
101
101
  target: "ea7vc6o0"
102
- })("font-size:16px;color:", _ref6 => {
102
+ })("display:flex;flex:1;font-size:", _ref6 => {
103
+ let {
104
+ theme
105
+ } = _ref6;
106
+ return theme.typography.body.fontSize;
107
+ }, ";color:", _ref7 => {
103
108
  let {
104
109
  theme: {
105
110
  colors
106
111
  }
107
- } = _ref6;
112
+ } = _ref7;
108
113
  return colors.neutral.text;
109
- }, ";border:none;outline:none;background-color:", _ref7 => {
114
+ }, ";border:none;outline:none;background-color:", _ref8 => {
110
115
  let {
111
116
  theme: {
112
117
  colors
113
118
  }
114
- } = _ref7;
119
+ } = _ref8;
115
120
  return colors.neutral.background;
116
- }, ";&::placeholder{color:", _ref8 => {
121
+ }, ";&::placeholder{color:", _ref9 => {
117
122
  let {
118
123
  theme: {
119
124
  colors
120
125
  }
121
- } = _ref8;
126
+ } = _ref9;
122
127
  return colors.neutral.textWeak;
123
128
  }, ";}");
124
129
  const convertTagArrayToTagStateArray = tags => (tags || [])?.map((tag, index) => typeof tag === 'object' ? {
@@ -132,7 +137,7 @@ const convertTagArrayToTagStateArray = tags => (tags || [])?.map((tag, index) =>
132
137
  * TagInput is a component that allows users to input tags.
133
138
  * @experimental This component is experimental and may be subject to breaking changes in the future.
134
139
  */
135
- const TagInput = _ref9 => {
140
+ const TagInput = _ref10 => {
136
141
  let {
137
142
  disabled = false,
138
143
  id,
@@ -145,7 +150,7 @@ const TagInput = _ref9 => {
145
150
  variant = 'base',
146
151
  className,
147
152
  'data-testid': dataTestId
148
- } = _ref9;
153
+ } = _ref10;
149
154
  const [tagInputState, setTagInput] = useState(convertTagArrayToTagStateArray(tags ?? []));
150
155
  const [input, setInput] = useState('');
151
156
  const [status, setStatus] = useState({});
@@ -189,10 +194,10 @@ const TagInput = _ref9 => {
189
194
  setStatus({
190
195
  [tagIndex]: STATUS.LOADING
191
196
  });
192
- const findIndex = tagInputState.findIndex(_ref10 => {
197
+ const findIndex = tagInputState.findIndex(_ref11 => {
193
198
  let {
194
199
  index
195
- } = _ref10;
200
+ } = _ref11;
196
201
  return index === tagIndex;
197
202
  });
198
203
  const newTagInput = [...tagInputState];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultraviolet/ui",
3
- "version": "1.21.1",
3
+ "version": "1.23.0",
4
4
  "description": "Ultraviolet UI",
5
5
  "homepage": "https://github.com/scaleway/ultraviolet#readme",
6
6
  "repository": {
@@ -43,8 +43,8 @@
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.31",
47
- "@types/react-datepicker": "4.19.0",
46
+ "@types/react": "18.2.33",
47
+ "@types/react-datepicker": "4.19.1",
48
48
  "@types/react-dom": "18.2.14",
49
49
  "react": "18.2.0",
50
50
  "react-dom": "18.2.0"
@@ -60,14 +60,14 @@
60
60
  "@scaleway/random-name": "4.0.2",
61
61
  "@scaleway/use-media": "2.0.1",
62
62
  "deepmerge": "4.3.1",
63
- "react-datepicker": "4.20.0",
63
+ "react-datepicker": "4.21.0",
64
64
  "react-flatten-children": "1.1.2",
65
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.3.0",
70
- "@ultraviolet/icons": "2.4.2"
70
+ "@ultraviolet/icons": "2.5.1"
71
71
  },
72
72
  "scripts": {
73
73
  "build": "rollup -c ../../rollup.config.mjs"