@ultraviolet/ui 1.10.1 → 1.11.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 CHANGED
@@ -24,11 +24,10 @@ type ActionBarProps = {
24
24
  */
25
25
  rank?: number;
26
26
  role?: string;
27
- 'aria-modal'?: 'true' | 'false';
28
27
  className?: string;
29
28
  'data-testid'?: string;
30
29
  };
31
- declare const ActionBar: ({ children, role, rank, "aria-modal": ariaModal, className, "data-testid": dataTestId, }: ActionBarProps) => react.ReactPortal;
30
+ declare const ActionBar: ({ children, role, rank, className, "data-testid": dataTestId, }: ActionBarProps) => react.ReactPortal;
32
31
 
33
32
  type ScreenSize = keyof typeof consoleLightTheme.screens;
34
33
  type SCWUITheme = typeof consoleLightTheme;
@@ -1453,6 +1452,25 @@ type NoticeProps = {
1453
1452
  };
1454
1453
  declare const Notice: ({ children, className, "data-testid": dataTestId, }: NoticeProps) => _emotion_react_jsx_runtime.JSX.Element;
1455
1454
 
1455
+ type CheckboxGroupCheckboxProps = Omit<ComponentProps<typeof Checkbox>, 'onChange' | 'checked' | 'required'> & {
1456
+ value: string;
1457
+ };
1458
+ declare const CheckboxGroupCheckbox: ({ onFocus, onBlur, disabled, error, name, value, children, helper, className, autoFocus, "data-testid": dataTestId, }: CheckboxGroupCheckboxProps) => _emotion_react_jsx_runtime.JSX.Element;
1459
+ type CheckboxGroupProps = {
1460
+ legend: string;
1461
+ value?: string[];
1462
+ className?: string;
1463
+ helper?: ReactNode;
1464
+ error?: ReactNode;
1465
+ direction?: 'row' | 'column';
1466
+ children: ReactNode;
1467
+ required?: boolean;
1468
+ } & Required<Pick<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'name'>> & Pick<InputHTMLAttributes<HTMLInputElement>, 'required'>;
1469
+ declare const CheckboxGroup: {
1470
+ ({ legend, value, className, helper, error, direction, children, onChange, name, required, }: CheckboxGroupProps): _emotion_react_jsx_runtime.JSX.Element;
1471
+ Checkbox: ({ onFocus, onBlur, disabled, error, name, value, children, helper, className, autoFocus, "data-testid": dataTestId, }: CheckboxGroupCheckboxProps) => _emotion_react_jsx_runtime.JSX.Element;
1472
+ };
1473
+
1456
1474
  declare const containerSizes: {
1457
1475
  large: number;
1458
1476
  medium: number;
@@ -2285,25 +2303,42 @@ type ToastContainerProps = {
2285
2303
  };
2286
2304
  declare const ToastContainer: ({ newestOnTop, limit, position, "data-testid": dataTestId, }: ToastContainerProps) => _emotion_react_jsx_runtime.JSX.Element;
2287
2305
 
2288
- type ToggleProps = {
2289
- id?: string;
2290
- checked?: boolean;
2306
+ declare const Toggle: react.ForwardRefExoticComponent<{
2307
+ id?: string | undefined;
2308
+ checked?: boolean | undefined;
2291
2309
  name: string;
2292
- tooltip?: string;
2310
+ tooltip?: string | undefined;
2293
2311
  /**
2294
2312
  * If `onChange` is given component will work as a controlled component if not it will work as an uncontrolled component.
2295
2313
  */
2296
- onChange?: ChangeEventHandler<HTMLInputElement>;
2297
- size?: 'large' | 'small';
2298
- labelPosition?: 'left' | 'right';
2314
+ onChange?: ChangeEventHandler<HTMLInputElement> | undefined;
2315
+ size?: "large" | "small" | undefined;
2316
+ labelPosition?: "left" | "right" | undefined;
2299
2317
  label?: ReactNode;
2300
2318
  helper?: ReactNode;
2301
- disabled?: boolean;
2319
+ disabled?: boolean | undefined;
2320
+ className?: string | undefined;
2321
+ required?: boolean | undefined;
2322
+ 'data-testid'?: string | undefined;
2323
+ } & Pick<InputHTMLAttributes<HTMLInputElement>, "value"> & react.RefAttributes<HTMLInputElement>>;
2324
+
2325
+ type ToggleGroupToggleProps = Omit<ComponentProps<typeof Toggle>, 'onChange' | 'checked' | 'required'> & {
2326
+ value: string;
2327
+ };
2328
+ type ToggleGroupProps = {
2329
+ legend: string;
2330
+ value?: string[];
2302
2331
  className?: string;
2332
+ helper?: ReactNode;
2333
+ error?: ReactNode;
2334
+ direction?: 'row' | 'column';
2335
+ children: ReactNode;
2303
2336
  required?: boolean;
2304
- 'data-testid'?: string;
2337
+ } & Required<Pick<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'name'>> & Pick<InputHTMLAttributes<HTMLInputElement>, 'required'>;
2338
+ declare const ToggleGroup: {
2339
+ ({ legend, value, className, helper, error, direction, children, onChange, name, required, }: ToggleGroupProps): _emotion_react_jsx_runtime.JSX.Element;
2340
+ Toggle: ({ disabled, name, value, label, helper, className, "data-testid": dataTestId, }: ToggleGroupToggleProps) => _emotion_react_jsx_runtime.JSX.Element;
2305
2341
  };
2306
- declare const Toggle: react.ForwardRefExoticComponent<ToggleProps & react.RefAttributes<HTMLInputElement>>;
2307
2342
 
2308
2343
  type TooltipProps = Pick<ComponentProps<typeof Popup>, 'id' | 'children' | 'maxWidth' | 'placement' | 'text' | 'className' | 'visible' | 'innerRef' | 'role' | 'data-testid' | 'containerFullWidth'>;
2309
2344
  declare const Tooltip: react.ForwardRefExoticComponent<TooltipProps & react.RefAttributes<HTMLDivElement>>;
@@ -2396,4 +2431,4 @@ declare const down: (size: ScreenSize, rules: string) => string;
2396
2431
 
2397
2432
  declare const normalize: () => string;
2398
2433
 
2399
- export { ActionBar, Alert, Avatar, Badge, Banner, BarChart, BarStack, Breadcrumbs, Breakpoint, Bullet, Button, Card, Carousel, Checkbox, CopyButton, DateInput, EmptyState, Expandable, LineChart, Link, List, Loader, Menu, Meter, Modal, Notice, NumberInput, Pagination, PasswordCheck, PasswordStrengthMeter, PieChart, Popover, ProgressBar, Radio, RadioGroup, Row, SCWUITheme, SelectInput, SelectableCard, Separator, Skeleton, Snippet, Stack, Status, StepList, Stepper, SwitchButton, Table, Tabs, Tag, TagInput, TagList, Text, TextInput, TimeInput, ToastContainer, Toggle, Tooltip, VerificationCode, bounce, down, extendTheme, fadeIn, fadeOut, flash, getUUID, normalize, ping, pulse, quickScaleDown, scaleBack, scaleDown, scaleForward, scaleUp, sketchIn, sketchOut, slideDownLarge, slideFromBottom, slideFromLeft, slideFromRight, slideFromTop, slideToBottom, slideToLeft, slideToRight, slideToTop, slideUpLarge, toast, unfoldIn, unfoldOut, up, zoomIn, zoomOut };
2434
+ export { ActionBar, Alert, Avatar, Badge, Banner, BarChart, BarStack, Breadcrumbs, Breakpoint, Bullet, Button, Card, Carousel, Checkbox, CheckboxGroup, CheckboxGroupCheckbox, CopyButton, DateInput, EmptyState, Expandable, LineChart, Link, List, Loader, Menu, Meter, Modal, Notice, NumberInput, Pagination, PasswordCheck, PasswordStrengthMeter, PieChart, Popover, ProgressBar, Radio, RadioGroup, Row, type SCWUITheme, SelectInput, SelectableCard, Separator, Skeleton, Snippet, Stack, Status, StepList, Stepper, SwitchButton, Table, Tabs, Tag, TagInput, TagList, Text, TextInput, TimeInput, ToastContainer, Toggle, ToggleGroup, Tooltip, VerificationCode, bounce, down, extendTheme, fadeIn, fadeOut, flash, getUUID, normalize, ping, pulse, quickScaleDown, scaleBack, scaleDown, scaleForward, scaleUp, sketchIn, sketchOut, slideDownLarge, slideFromBottom, slideFromLeft, slideFromRight, slideFromTop, slideToBottom, slideToLeft, slideToRight, slideToTop, slideUpLarge, toast, unfoldIn, unfoldOut, up, zoomIn, zoomOut };
@@ -33,14 +33,12 @@ const ActionBar = _ref5 => {
33
33
  children,
34
34
  role = 'dialog',
35
35
  rank = 0,
36
- 'aria-modal': ariaModal = 'true',
37
36
  className,
38
37
  'data-testid': dataTestId
39
38
  } = _ref5;
40
39
  return /*#__PURE__*/createPortal(jsx(StyledDiv, {
41
40
  rank: rank,
42
41
  role: role,
43
- "aria-modal": ariaModal,
44
42
  className: className,
45
43
  "data-testid": dataTestId,
46
44
  children: children
@@ -0,0 +1,129 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Icon } from '@ultraviolet/icons';
3
+ import { useContext, useMemo, createContext } from 'react';
4
+ import { Checkbox } from '../Checkbox/index.js';
5
+ import { Stack } from '../Stack/index.js';
6
+ import { Text } from '../Text/index.js';
7
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
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 CheckboxGroupContext = /*#__PURE__*/createContext(undefined);
11
+ const CheckboxGroupCheckbox = _ref => {
12
+ let {
13
+ onFocus,
14
+ onBlur,
15
+ disabled,
16
+ error,
17
+ name,
18
+ value,
19
+ children,
20
+ helper,
21
+ className,
22
+ autoFocus,
23
+ 'data-testid': dataTestId
24
+ } = _ref;
25
+ const context = useContext(CheckboxGroupContext);
26
+ if (!context) {
27
+ throw new Error('CheckboxGroup.Checkbox can only be used inside a CheckboxGroup');
28
+ }
29
+ const {
30
+ groupName,
31
+ onChange,
32
+ groupValues
33
+ } = context;
34
+ const checkboxName = `${groupName}.${name ?? ''}`;
35
+ const checkboxValue = `${value}`;
36
+ return jsx(Checkbox, {
37
+ onChange: onChange,
38
+ checked: groupValues?.includes(checkboxValue),
39
+ onFocus: onFocus,
40
+ onBlur: onBlur,
41
+ disabled: disabled,
42
+ error: error,
43
+ name: checkboxName,
44
+ value: checkboxValue,
45
+ helper: helper,
46
+ className: className,
47
+ autoFocus: autoFocus,
48
+ "data-testid": dataTestId,
49
+ children: children
50
+ });
51
+ };
52
+ const FieldSet = /*#__PURE__*/_styled("fieldset", {
53
+ target: "e1k5uyng1"
54
+ })(process.env.NODE_ENV === "production" ? {
55
+ name: "7o2an9",
56
+ styles: "border:none;padding:0;margin:0"
57
+ } : {
58
+ name: "7o2an9",
59
+ styles: "border:none;padding:0;margin:0",
60
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
61
+ });
62
+ const StyledRequiredIcon = /*#__PURE__*/_styled(Icon, {
63
+ target: "e1k5uyng0"
64
+ })(process.env.NODE_ENV === "production" ? {
65
+ name: "1nglpc5",
66
+ styles: "vertical-align:super"
67
+ } : {
68
+ name: "1nglpc5",
69
+ styles: "vertical-align:super",
70
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
71
+ });
72
+ const CheckboxGroup = _ref2 => {
73
+ let {
74
+ legend,
75
+ value,
76
+ className,
77
+ helper,
78
+ error,
79
+ direction = 'column',
80
+ children,
81
+ onChange,
82
+ name,
83
+ required = false
84
+ } = _ref2;
85
+ const contextValue = useMemo(() => ({
86
+ groupName: name,
87
+ groupValues: value ?? [],
88
+ onChange
89
+ }), [name, value, onChange]);
90
+ return jsx(CheckboxGroupContext.Provider, {
91
+ value: contextValue,
92
+ children: jsxs(Stack, {
93
+ gap: 1,
94
+ children: [jsx(FieldSet, {
95
+ className: className,
96
+ children: jsxs(Stack, {
97
+ gap: 1.5,
98
+ children: [jsxs(Text, {
99
+ as: "legend",
100
+ variant: "bodyStrong",
101
+ children: [legend, "\xA0", required ? jsx(StyledRequiredIcon, {
102
+ name: "asterisk",
103
+ color: "danger",
104
+ size: 8
105
+ }) : null]
106
+ }), jsx(Stack, {
107
+ gap: direction === 'column' ? 1 : 2,
108
+ direction: direction,
109
+ children: children
110
+ })]
111
+ })
112
+ }), helper ? jsx(Text, {
113
+ as: "p",
114
+ variant: "bodySmall",
115
+ prominence: "weak",
116
+ children: helper
117
+ }) : null, error ? jsx(Text, {
118
+ as: "p",
119
+ variant: "bodySmall",
120
+ sentiment: "danger",
121
+ prominence: "weak",
122
+ children: error
123
+ }) : null]
124
+ })
125
+ });
126
+ };
127
+ CheckboxGroup.Checkbox = CheckboxGroupCheckbox;
128
+
129
+ export { CheckboxGroup, CheckboxGroupCheckbox };
@@ -73,6 +73,7 @@ const Dialog = _ref9 => {
73
73
  backdropCss
74
74
  } = _ref9;
75
75
  const containerRef = useRef(document.createElement('div'));
76
+ const dialogRef = useRef(null);
76
77
  const onCloseRef = useRef(onClose);
77
78
 
78
79
  // Portal to put the modal in
@@ -80,6 +81,7 @@ const Dialog = _ref9 => {
80
81
  const element = containerRef.current;
81
82
  if (open) {
82
83
  document.body.appendChild(element);
84
+ dialogRef.current?.focus();
83
85
  }
84
86
  return () => {
85
87
  if (document.body.contains(element)) {
@@ -97,14 +99,26 @@ const Dialog = _ref9 => {
97
99
  useEffect(() => {
98
100
  const handleEscPress = event => {
99
101
  if (event.key === 'Escape' && hideOnEsc) {
102
+ event.preventDefault();
103
+ event.stopPropagation();
100
104
  onCloseRef.current();
101
105
  }
102
106
  };
103
107
  if (open) {
104
- document.addEventListener('keyup', handleEscPress);
108
+ document.body.addEventListener('keyup', handleEscPress, {
109
+ capture: true
110
+ });
111
+ document.body.addEventListener('keydown', handleEscPress, {
112
+ capture: true
113
+ });
105
114
  }
106
115
  return () => {
107
- document.removeEventListener('keyup', handleEscPress);
116
+ document.body.removeEventListener('keyup', handleEscPress, {
117
+ capture: true
118
+ });
119
+ document.body.removeEventListener('keydown', handleEscPress, {
120
+ capture: true
121
+ });
108
122
  };
109
123
  }, [open, onCloseRef, hideOnEsc]);
110
124
 
@@ -117,6 +131,11 @@ const Dialog = _ref9 => {
117
131
  }
118
132
  }, [preventBodyScroll, open]);
119
133
 
134
+ // Stop focus to prevent unexpected body loose focus
135
+ const stopFocus = useCallback(event => {
136
+ event.stopPropagation();
137
+ }, []);
138
+
120
139
  // Stop click to prevent unexpected dialog close
121
140
  const stopClick = useCallback(event => {
122
141
  event.stopPropagation();
@@ -126,15 +145,53 @@ const Dialog = _ref9 => {
126
145
  const stopKeyUp = useCallback(event => {
127
146
  event.stopPropagation();
128
147
  }, []);
148
+
149
+ // Enable focus trap inside the modal
150
+ const handleFocusTrap = useCallback(event => {
151
+ event.stopPropagation();
152
+ if (event.key === 'Escape') {
153
+ event.preventDefault();
154
+ return;
155
+ }
156
+ const isTabPressed = event.key === 'Tab';
157
+ if (!isTabPressed) {
158
+ return;
159
+ }
160
+ const focusableEls = dialogRef.current?.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled])') ?? [];
161
+
162
+ // Handle case when no interactive element are within the modal (including close icon)
163
+ if (focusableEls.length === 0) {
164
+ event.preventDefault();
165
+ }
166
+ const firstFocusableEl = focusableEls[0];
167
+ const lastFocusableEl = focusableEls[focusableEls.length - 1];
168
+ if (event.shiftKey) {
169
+ if (document.activeElement === firstFocusableEl) {
170
+ lastFocusableEl.focus();
171
+ event.preventDefault();
172
+ }
173
+ } else if (document.activeElement === lastFocusableEl) {
174
+ firstFocusableEl.focus();
175
+ event.preventDefault();
176
+ }
177
+ }, []);
178
+
179
+ // Prevent default behaviour on Escape
180
+ const stopCancel = event => {
181
+ event.preventDefault();
182
+ event.stopPropagation();
183
+ };
129
184
  return /*#__PURE__*/createPortal(jsx(StyledBackdrop, {
130
185
  "data-open": open,
131
186
  onClick: hideOnClickOutside ? onClose : undefined,
132
187
  className: backdropClassName,
133
188
  css: backdropCss,
134
189
  "data-testid": dataTestId ? `${dataTestId}-backdrop` : undefined,
190
+ onFocus: stopFocus,
135
191
  children: jsx(StyledDialog, {
136
192
  css: dialogCss,
137
193
  onKeyUp: stopKeyUp,
194
+ onKeyDown: handleFocusTrap,
138
195
  className: className,
139
196
  id: id,
140
197
  "data-testid": dataTestId,
@@ -143,6 +200,10 @@ const Dialog = _ref9 => {
143
200
  "data-size": size,
144
201
  open: open,
145
202
  onClick: stopClick,
203
+ onCancel: stopCancel,
204
+ onClose: stopCancel,
205
+ "aria-modal": true,
206
+ ref: dialogRef,
146
207
  children: open ? children : null
147
208
  })
148
209
  }), containerRef.current);
@@ -17,6 +17,11 @@ const Disclosure = _ref => {
17
17
  element?.removeEventListener('click', handleOpen);
18
18
  };
19
19
  }, [handleOpen, disclosureRef]);
20
+ useEffect(() => {
21
+ if (!visible) {
22
+ disclosureRef.current?.focus();
23
+ }
24
+ }, [visible, disclosureRef]);
20
25
  if (typeof disclosure === 'function') {
21
26
  return disclosure({
22
27
  visible,
@@ -30,7 +35,9 @@ const Disclosure = _ref => {
30
35
  if ( /*#__PURE__*/isValidElement(disclosure)) {
31
36
  return /*#__PURE__*/cloneElement(disclosure, {
32
37
  ...disclosure.props,
33
- ref: disclosureRef
38
+ ref: disclosureRef,
39
+ 'aria-controls': id,
40
+ 'aria-haspopup': 'dialog'
34
41
  });
35
42
  }
36
43
  return null;
@@ -1,5 +1,5 @@
1
1
  import _styled from '@emotion/styled/base';
2
- import { useState, useId, useCallback } from 'react';
2
+ import { useState, useId, useCallback, useEffect } from 'react';
3
3
  import { Button } from '../Button/index.js';
4
4
  import { Dialog } from './Dialog.js';
5
5
  import { Disclosure } from './Disclosure.js';
@@ -61,6 +61,9 @@ const Modal = _ref3 => {
61
61
  }, []);
62
62
  const finalId = id ?? controlId;
63
63
  const finalSize = size ?? width;
64
+ useEffect(() => {
65
+ setVisible(opened);
66
+ }, [opened]);
64
67
  return jsxs(Fragment, {
65
68
  children: [jsx(Disclosure, {
66
69
  id: finalId,
@@ -167,7 +167,8 @@ const Toggle = /*#__PURE__*/forwardRef((_ref23, ref) => {
167
167
  helper,
168
168
  required,
169
169
  className,
170
- 'data-testid': dataTestId
170
+ 'data-testid': dataTestId,
171
+ value
171
172
  } = _ref23;
172
173
  const [state, setState] = useState(checked);
173
174
  const uniqueId = useId();
@@ -212,7 +213,8 @@ const Toggle = /*#__PURE__*/forwardRef((_ref23, ref) => {
212
213
  name: name,
213
214
  onChange: onLocalChange,
214
215
  type: "checkbox",
215
- ref: ref
216
+ ref: ref,
217
+ value: value
216
218
  })
217
219
  })]
218
220
  })
@@ -0,0 +1,121 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Icon } from '@ultraviolet/icons';
3
+ import { useMemo, createContext, useContext } from 'react';
4
+ import { Stack } from '../Stack/index.js';
5
+ import { Text } from '../Text/index.js';
6
+ import { Toggle } from '../Toggle/index.js';
7
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
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 ToggleGroupContext = /*#__PURE__*/createContext(undefined);
11
+ const ToggleGroupToggle = _ref => {
12
+ let {
13
+ disabled,
14
+ name,
15
+ value,
16
+ label,
17
+ helper,
18
+ className,
19
+ 'data-testid': dataTestId
20
+ } = _ref;
21
+ const context = useContext(ToggleGroupContext);
22
+ if (!context) {
23
+ throw new Error('ToggleGroup.Toggle can only be used inside a ToggleGroup');
24
+ }
25
+ const {
26
+ groupName,
27
+ onChange,
28
+ groupValues
29
+ } = context;
30
+ const ToggleName = `${groupName}.${name}`;
31
+ const ToggleValue = `${value}`;
32
+ return jsx(Toggle, {
33
+ onChange: onChange,
34
+ checked: groupValues?.includes(ToggleValue),
35
+ disabled: disabled,
36
+ name: ToggleName,
37
+ value: ToggleValue,
38
+ helper: helper,
39
+ className: className,
40
+ "data-testid": dataTestId,
41
+ label: label
42
+ });
43
+ };
44
+ const FieldSet = /*#__PURE__*/_styled("fieldset", {
45
+ target: "e1qvneex1"
46
+ })(process.env.NODE_ENV === "production" ? {
47
+ name: "7o2an9",
48
+ styles: "border:none;padding:0;margin:0"
49
+ } : {
50
+ name: "7o2an9",
51
+ styles: "border:none;padding:0;margin:0",
52
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
53
+ });
54
+ const StyledRequiredIcon = /*#__PURE__*/_styled(Icon, {
55
+ target: "e1qvneex0"
56
+ })(process.env.NODE_ENV === "production" ? {
57
+ name: "1nglpc5",
58
+ styles: "vertical-align:super"
59
+ } : {
60
+ name: "1nglpc5",
61
+ styles: "vertical-align:super",
62
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
63
+ });
64
+ const ToggleGroup = _ref2 => {
65
+ let {
66
+ legend,
67
+ value,
68
+ className,
69
+ helper,
70
+ error,
71
+ direction = 'column',
72
+ children,
73
+ onChange,
74
+ name,
75
+ required = false
76
+ } = _ref2;
77
+ const contextValue = useMemo(() => ({
78
+ groupName: name,
79
+ groupValues: value ?? [],
80
+ onChange
81
+ }), [name, value, onChange]);
82
+ return jsx(ToggleGroupContext.Provider, {
83
+ value: contextValue,
84
+ children: jsxs(Stack, {
85
+ gap: 1,
86
+ children: [jsx(FieldSet, {
87
+ className: className,
88
+ children: jsxs(Stack, {
89
+ gap: 1.5,
90
+ children: [jsxs(Text, {
91
+ as: "legend",
92
+ variant: "bodyStrong",
93
+ children: [legend, "\xA0", required ? jsx(StyledRequiredIcon, {
94
+ name: "asterisk",
95
+ color: "danger",
96
+ size: 8
97
+ }) : null]
98
+ }), jsx(Stack, {
99
+ gap: 2,
100
+ direction: direction,
101
+ children: children
102
+ })]
103
+ })
104
+ }), helper ? jsx(Text, {
105
+ as: "p",
106
+ variant: "bodySmall",
107
+ prominence: "weak",
108
+ children: helper
109
+ }) : null, error ? jsx(Text, {
110
+ as: "p",
111
+ variant: "bodySmall",
112
+ sentiment: "danger",
113
+ prominence: "weak",
114
+ children: error
115
+ }) : null]
116
+ })
117
+ });
118
+ };
119
+ ToggleGroup.Toggle = ToggleGroupToggle;
120
+
121
+ export { ToggleGroup, ToggleGroupToggle };
package/dist/src/index.js CHANGED
@@ -30,6 +30,7 @@ export { Menu } from './components/Menu/index.js';
30
30
  export { Meter } from './components/Meter/Meter.js';
31
31
  export { Modal } from './components/Modal/Modal.js';
32
32
  export { Notice } from './components/Notice/index.js';
33
+ export { CheckboxGroup, CheckboxGroupCheckbox } from './components/CheckboxGroup/index.js';
33
34
  export { NumberInput } from './components/NumberInput/index.js';
34
35
  export { Pagination } from './components/Pagination/index.js';
35
36
  export { PasswordCheck } from './components/PasswordCheck/index.js';
@@ -59,6 +60,7 @@ export { TextInput } from './components/TextInput/index.js';
59
60
  export { TimeInput } from './components/TimeInput/index.js';
60
61
  export { ToastContainer, toast } from './components/Toaster/index.js';
61
62
  export { Toggle } from './components/Toggle/index.js';
63
+ export { ToggleGroup } from './components/ToggleGroup/index.js';
62
64
  export { Tooltip } from './components/Tooltip/index.js';
63
65
  export { VerificationCode } from './components/VerificationCode/index.js';
64
66
  export { RadioGroup } from './components/RadioGroup/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultraviolet/ui",
3
- "version": "1.10.1",
3
+ "version": "1.11.1",
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.11",
42
+ "@babel/core": "7.22.15",
43
43
  "@emotion/babel-plugin": "11.11.0",
44
44
  "@emotion/react": "11.11.1",
45
45
  "@emotion/styled": "11.11.0",
@@ -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.1"
71
+ "@ultraviolet/icons": "2.0.0"
72
72
  }
73
73
  }