@itwin/itwinui-react 3.0.0-dev.12 → 3.0.0-dev.13

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 (37) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/cjs/core/ColorPicker/ColorBuilder.js +2 -0
  3. package/cjs/core/ColorPicker/ColorInputPanel.js +24 -4
  4. package/cjs/core/ColorPicker/ColorPalette.js +2 -80
  5. package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
  6. package/cjs/core/ColorPicker/ColorSwatch.js +25 -15
  7. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +1 -1
  8. package/cjs/core/LabeledSelect/LabeledSelect.js +3 -3
  9. package/cjs/core/Select/Select.d.ts +1 -1
  10. package/cjs/core/Select/Select.js +6 -4
  11. package/cjs/core/Tabs/Tabs.d.ts +222 -52
  12. package/cjs/core/Tabs/Tabs.js +436 -376
  13. package/cjs/core/ThemeProvider/ThemeProvider.js +3 -1
  14. package/cjs/index.d.ts +1 -2
  15. package/cjs/index.js +1 -2
  16. package/cjs/styles.js +4 -2
  17. package/esm/core/ColorPicker/ColorBuilder.js +2 -0
  18. package/esm/core/ColorPicker/ColorInputPanel.js +25 -5
  19. package/esm/core/ColorPicker/ColorPalette.js +3 -83
  20. package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
  21. package/esm/core/ColorPicker/ColorSwatch.js +18 -12
  22. package/esm/core/LabeledSelect/LabeledSelect.d.ts +1 -1
  23. package/esm/core/LabeledSelect/LabeledSelect.js +3 -2
  24. package/esm/core/Select/Select.d.ts +1 -1
  25. package/esm/core/Select/Select.js +3 -3
  26. package/esm/core/Tabs/Tabs.d.ts +222 -52
  27. package/esm/core/Tabs/Tabs.js +429 -369
  28. package/esm/core/ThemeProvider/ThemeProvider.js +3 -1
  29. package/esm/index.d.ts +1 -2
  30. package/esm/index.js +1 -2
  31. package/esm/styles.js +4 -2
  32. package/package.json +2 -2
  33. package/styles.css +8 -8
  34. package/cjs/core/Tabs/Tab.d.ts +0 -40
  35. package/cjs/core/Tabs/Tab.js +0 -65
  36. package/esm/core/Tabs/Tab.d.ts +0 -40
  37. package/esm/core/Tabs/Tab.js +0 -57
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.0-dev.13
4
+
5
+ ### Major Changes
6
+
7
+ - [#1548](https://github.com/iTwin/iTwinUI/pull/1548): Tabs are now always scrollable. Deprecated `overflowOptions` prop.
8
+
9
+ ### Minor Changes
10
+
11
+ - [#1548](https://github.com/iTwin/iTwinUI/pull/1548): Added composition API to Tab. Subcomponents: Wrapper, TabList, Tab, TabLabel, TabIcon, TabDescription, Actions, Panel.
12
+
13
+ ### Patch Changes
14
+
15
+ - [#1618](https://github.com/iTwin/iTwinUI/pull/1618): Improved accessibility of ColorPicker/ColorPalette/ColorSwatch.
16
+
3
17
  ## 3.0.0-dev.12
4
18
 
5
19
  ### Minor Changes
@@ -223,6 +237,12 @@
223
237
  - Updated dependencies:
224
238
  - @itwin/itwinui-css@2.0.0-dev.0
225
239
 
240
+ ## 2.12.12
241
+
242
+ ### Patch Changes
243
+
244
+ - [#1625](https://github.com/iTwin/iTwinUI/pull/1625): Fixed an issue where components rendered in a popout window were throwing a stylesheet-related error.
245
+
226
246
  ## 2.12.11
227
247
 
228
248
  ### Patch Changes
@@ -282,6 +282,7 @@ exports.ColorBuilder = React.forwardRef((props, ref) => {
282
282
  },
283
283
  min: 0,
284
284
  max: 359,
285
+ thumbProps: () => ({ 'aria-label': 'Hue' }),
285
286
  }),
286
287
  showAlpha &&
287
288
  React.createElement(Slider_js_1.Slider, {
@@ -303,6 +304,7 @@ exports.ColorBuilder = React.forwardRef((props, ref) => {
303
304
  style: {
304
305
  '--iui-color-picker-selected-color': hueColorString,
305
306
  },
307
+ thumbProps: () => ({ 'aria-label': 'Opacity' }),
306
308
  }),
307
309
  );
308
310
  });
@@ -144,6 +144,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
144
144
  maxLength: showAlpha ? 9 : 7,
145
145
  minLength: 1,
146
146
  placeholder: 'HEX',
147
+ 'aria-label': 'Hex',
147
148
  value: input[0],
148
149
  onChange: (event) => {
149
150
  const value = event.target.value.startsWith('#')
@@ -173,6 +174,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
173
174
  max: '359',
174
175
  step: '.1',
175
176
  placeholder: 'H',
177
+ 'aria-label': 'Hue',
176
178
  value: input[0] ?? '',
177
179
  onChange: (event) => {
178
180
  setInput([event.target.value, input[1], input[2], input[3]]);
@@ -199,6 +201,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
199
201
  max: '100',
200
202
  step: '.1',
201
203
  placeholder: 'S',
204
+ 'aria-label': 'Saturation',
202
205
  value: input[1] ?? '',
203
206
  onChange: (event) => {
204
207
  setInput([input[0], event.target.value, input[2], input[3]]);
@@ -225,6 +228,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
225
228
  max: '100',
226
229
  step: '.1',
227
230
  placeholder: 'L',
231
+ 'aria-label': 'Lightness',
228
232
  value: input[2] ?? '',
229
233
  onChange: (event) => {
230
234
  setInput([input[0], input[1], event.target.value, input[3]]);
@@ -252,6 +256,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
252
256
  max: '1',
253
257
  step: '.01',
254
258
  placeholder: 'A',
259
+ 'aria-label': 'Alpha',
255
260
  value: input[3] ?? '',
256
261
  onChange: (event) => {
257
262
  setInput([input[0], input[1], input[2], event.target.value]);
@@ -281,6 +286,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
281
286
  min: '0',
282
287
  max: '255',
283
288
  placeholder: 'R',
289
+ 'aria-label': 'Red',
284
290
  value: input[0] ?? '',
285
291
  onChange: (event) => {
286
292
  setInput([event.target.value, input[1], input[2], input[3]]);
@@ -306,6 +312,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
306
312
  min: '0',
307
313
  max: '255',
308
314
  placeholder: 'G',
315
+ 'aria-label': 'Green',
309
316
  value: input[1] ?? '',
310
317
  onChange: (event) => {
311
318
  setInput([input[0], event.target.value, input[2], input[3]]);
@@ -331,6 +338,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
331
338
  min: '0',
332
339
  max: '255',
333
340
  placeholder: 'B',
341
+ 'aria-label': 'Blue',
334
342
  value: input[2] ?? '',
335
343
  onChange: (event) => {
336
344
  setInput([input[0], input[1], event.target.value, input[3]]);
@@ -358,6 +366,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
358
366
  max: '1',
359
367
  step: '.01',
360
368
  placeholder: 'A',
369
+ 'aria-label': 'Alpha',
361
370
  value: input[3] ?? '',
362
371
  onChange: (event) => {
363
372
  setInput([input[0], input[1], input[2], event.target.value]);
@@ -378,6 +387,7 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
378
387
  Number(input[3]) < 0 || Number(input[3]) > 1 ? 'negative' : undefined,
379
388
  }),
380
389
  );
390
+ const labelId = (0, index_js_1.useId)();
381
391
  return React.createElement(
382
392
  index_js_1.Box,
383
393
  {
@@ -390,8 +400,8 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
390
400
  },
391
401
  React.createElement(
392
402
  index_js_1.Box,
393
- { className: 'iui-color-picker-section-label' },
394
- showAlpha && currentFormat != 'hex'
403
+ { className: 'iui-color-picker-section-label', id: labelId },
404
+ showAlpha && currentFormat !== 'hex'
395
405
  ? currentFormat.toUpperCase() + 'A'
396
406
  : currentFormat.toUpperCase(),
397
407
  ),
@@ -401,12 +411,22 @@ exports.ColorInputPanel = React.forwardRef((props, ref) => {
401
411
  allowedColorFormats.length > 1 &&
402
412
  React.createElement(
403
413
  IconButton_js_1.IconButton,
404
- { styleType: 'borderless', onClick: swapColorFormat, size: 'small' },
414
+ {
415
+ styleType: 'borderless',
416
+ onClick: swapColorFormat,
417
+ size: 'small',
418
+ label: 'Switch format',
419
+ },
405
420
  React.createElement(index_js_1.SvgSwap, null),
406
421
  ),
407
422
  React.createElement(
408
423
  index_js_1.Box,
409
- { ref: inputsContainerRef, className: 'iui-color-input-fields' },
424
+ {
425
+ ref: inputsContainerRef,
426
+ className: 'iui-color-input-fields',
427
+ role: currentFormat !== 'hex' ? 'group' : undefined,
428
+ 'aria-labelledby': currentFormat !== 'hex' ? labelId : undefined,
429
+ },
410
430
  currentFormat === 'hex' && hexInputField,
411
431
  currentFormat === 'rgb' && rgbInputs,
412
432
  currentFormat === 'hsl' && hslInputs,
@@ -27,79 +27,6 @@ exports.ColorPalette = React.forwardRef((props, ref) => {
27
27
  const { colors, label, className, children, ...rest } = props;
28
28
  const { activeColor, setActiveColor, onChangeComplete } = (0,
29
29
  ColorPickerContext_js_1.useColorPickerContext)();
30
- const [focusedIndex, setFocusedIndex] = React.useState();
31
- // callback ref to set tabindex=0 on first child if none of the swatches are tabbable
32
- const setDefaultTabIndex = (el) => {
33
- if (el && !el.querySelector('[tabindex="0"]')) {
34
- el.firstElementChild?.setAttribute('tabindex', '0');
35
- }
36
- };
37
- const paletteRef = React.useRef(null);
38
- const paletteRefs = (0, index_js_1.useMergedRefs)(
39
- paletteRef,
40
- setDefaultTabIndex,
41
- );
42
- // Color palette arrow key navigation
43
- const handleKeyDown = (event) => {
44
- if (event.altKey) {
45
- return;
46
- }
47
- const swatches = (0, index_js_1.getFocusableElements)(paletteRef.current);
48
- if (!swatches.length) {
49
- return;
50
- }
51
- const currentIndex = swatches.findIndex(
52
- (swatch) => swatch === paletteRef.current?.ownerDocument.activeElement,
53
- );
54
- if (currentIndex < 0) {
55
- return;
56
- }
57
- let newIndex = -1;
58
- switch (event.key) {
59
- case 'ArrowDown': {
60
- // Look for next ColorSwatch with same offsetLeft value
61
- newIndex = swatches.findIndex(
62
- (swatch, index) =>
63
- index > currentIndex &&
64
- swatch.offsetLeft === swatches[currentIndex].offsetLeft,
65
- );
66
- break;
67
- }
68
- case 'ArrowUp': {
69
- // Look backwards for next ColorSwatch with same offsetLeft value
70
- for (let i = currentIndex - 1; i >= 0; i--) {
71
- if (swatches[i].offsetLeft === swatches[currentIndex].offsetLeft) {
72
- newIndex = i;
73
- break;
74
- }
75
- }
76
- break;
77
- }
78
- case 'ArrowLeft':
79
- newIndex = Math.max(currentIndex - 1, 0);
80
- break;
81
- case 'ArrowRight':
82
- newIndex = Math.min(currentIndex + 1, swatches.length - 1);
83
- break;
84
- case 'Enter':
85
- case ' ':
86
- case 'Spacebar':
87
- swatches[currentIndex].click();
88
- event.preventDefault();
89
- return;
90
- }
91
- if (newIndex >= 0 && newIndex < swatches.length) {
92
- setFocusedIndex(newIndex);
93
- event.preventDefault();
94
- }
95
- };
96
- // call focus() when focusedIndex changes
97
- React.useEffect(() => {
98
- if (focusedIndex != null) {
99
- const swatches = (0, index_js_1.getFocusableElements)(paletteRef.current);
100
- swatches[focusedIndex]?.focus();
101
- }
102
- }, [focusedIndex]);
103
30
  return React.createElement(
104
31
  index_js_1.Box,
105
32
  {
@@ -118,11 +45,7 @@ exports.ColorPalette = React.forwardRef((props, ref) => {
118
45
  ),
119
46
  React.createElement(
120
47
  index_js_1.Box,
121
- {
122
- className: 'iui-color-palette',
123
- onKeyDown: handleKeyDown,
124
- ref: paletteRefs,
125
- },
48
+ { className: 'iui-color-palette' },
126
49
  children,
127
50
  colors &&
128
51
  colors.map((_color, index) => {
@@ -130,8 +53,7 @@ exports.ColorPalette = React.forwardRef((props, ref) => {
130
53
  return React.createElement(ColorSwatch_js_1.ColorSwatch, {
131
54
  key: index,
132
55
  color: color,
133
- onClick: (event) => {
134
- event.preventDefault();
56
+ onClick: () => {
135
57
  onChangeComplete?.(color);
136
58
  setActiveColor(color);
137
59
  },
@@ -16,5 +16,5 @@ type ColorSwatchProps = {
16
16
  * <ColorSwatch color='#23450b' onClick={onClick}/>
17
17
  * <ColorSwatch color={{ r: 255, g: 255, b: 0 }} onClick={onClick}/>
18
18
  */
19
- export declare const ColorSwatch: PolymorphicForwardRefComponent<"div", ColorSwatchProps>;
19
+ export declare const ColorSwatch: PolymorphicForwardRefComponent<"button", ColorSwatchProps>;
20
20
  export default ColorSwatch;
@@ -10,6 +10,7 @@ const React = tslib_1.__importStar(require('react'));
10
10
  const classnames_1 = tslib_1.__importDefault(require('classnames'));
11
11
  const index_js_1 = require('../utils/index.js');
12
12
  const ColorPicker_js_1 = require('./ColorPicker.js');
13
+ const VisuallyHidden_js_1 = require('../VisuallyHidden/VisuallyHidden.js');
13
14
  /**
14
15
  * ColorSwatch component to display within a color palette.
15
16
  * @example
@@ -25,21 +26,30 @@ exports.ColorSwatch = React.forwardRef((props, ref) => {
25
26
  : (0, ColorPicker_js_1.getColorValue)(color).toHslString(true),
26
27
  [color],
27
28
  );
28
- return React.createElement(index_js_1.Box, {
29
- className: (0, classnames_1.default)(
30
- 'iui-color-swatch',
31
- { 'iui-active': isActive },
32
- className,
33
- ),
34
- style: {
35
- '--iui-color-swatch-background': colorString,
36
- ...style,
29
+ return React.createElement(
30
+ index_js_1.Box,
31
+ {
32
+ as: !!onClick ? index_js_1.ButtonBase : 'span',
33
+ className: (0, classnames_1.default)(
34
+ 'iui-color-swatch',
35
+ { 'iui-active': isActive },
36
+ className,
37
+ ),
38
+ style: {
39
+ '--iui-color-swatch-background': colorString,
40
+ ...style,
41
+ },
42
+ onClick: onClick,
43
+ 'aria-pressed': !!onClick && isActive ? 'true' : undefined,
44
+ ref: ref,
45
+ ...rest,
37
46
  },
38
- onClick: onClick,
39
- tabIndex: isActive ? 0 : -1,
40
- 'aria-selected': isActive,
41
- ref: ref,
42
- ...rest,
43
- });
47
+ props.children ??
48
+ React.createElement(
49
+ VisuallyHidden_js_1.VisuallyHidden,
50
+ null,
51
+ colorString.toUpperCase(),
52
+ ),
53
+ );
44
54
  });
45
55
  exports.default = exports.ColorSwatch;
@@ -76,5 +76,5 @@ export type LabeledSelectProps<T> = {
76
76
  * svgIcon={<SvgCamera />}
77
77
  * />
78
78
  */
79
- export declare const LabeledSelect: <T>(props: LabeledSelectProps<T>) => JSX.Element;
79
+ export declare const LabeledSelect: React.ForwardRefExoticComponent<LabeledSelectProps<unknown> & React.RefAttributes<HTMLElement>>;
80
80
  export default LabeledSelect;
@@ -46,7 +46,7 @@ const Icon_js_1 = require('../Icon/Icon.js');
46
46
  * svgIcon={<SvgCamera />}
47
47
  * />
48
48
  */
49
- const LabeledSelect = (props) => {
49
+ exports.LabeledSelect = React.forwardRef((props, forwardedRef) => {
50
50
  const {
51
51
  className,
52
52
  disabled = false,
@@ -95,6 +95,7 @@ const LabeledSelect = (props) => {
95
95
  style: style,
96
96
  status: status,
97
97
  ...rest,
98
+ ref: forwardedRef,
98
99
  triggerProps: {
99
100
  'aria-labelledby': labelId,
100
101
  ...triggerProps,
@@ -113,6 +114,5 @@ const LabeledSelect = (props) => {
113
114
  )
114
115
  : message,
115
116
  );
116
- };
117
- exports.LabeledSelect = LabeledSelect;
117
+ });
118
118
  exports.default = exports.LabeledSelect;
@@ -168,5 +168,5 @@ export type SelectProps<T> = {
168
168
  * )}
169
169
  * />
170
170
  */
171
- export declare const Select: <T>(props: SelectProps<T>) => JSX.Element;
171
+ export declare const Select: React.ForwardRefExoticComponent<SelectProps<unknown> & React.RefAttributes<HTMLElement>>;
172
172
  export default Select;
@@ -71,7 +71,7 @@ const isSingleOnChange = (onChange, multiple) => {
71
71
  * )}
72
72
  * />
73
73
  */
74
- const Select = (props) => {
74
+ exports.Select = React.forwardRef((props, forwardedRef) => {
75
75
  const uid = (0, index_js_1.useId)();
76
76
  const {
77
77
  options,
@@ -192,7 +192,10 @@ const Select = (props) => {
192
192
  className: (0, classnames_1.default)('iui-input-with-icon', className),
193
193
  style: style,
194
194
  ...rest,
195
- ref: popover.refs.setPositionReference,
195
+ ref: (0, index_js_1.useMergedRefs)(
196
+ popover.refs.setPositionReference,
197
+ forwardedRef,
198
+ ),
196
199
  },
197
200
  React.createElement(
198
201
  index_js_1.Box,
@@ -282,8 +285,7 @@ const Select = (props) => {
282
285
  ),
283
286
  ),
284
287
  );
285
- };
286
- exports.Select = Select;
288
+ });
287
289
  const SingleSelectButton = ({ selectedItem, selectedItemRenderer }) => {
288
290
  const startIcon = selectedItem?.startIcon ?? selectedItem?.icon;
289
291
  return React.createElement(