@itwin/itwinui-react 3.15.2 → 3.15.4

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 (89) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/DEV-cjs/core/Breadcrumbs/Breadcrumbs.js +85 -65
  3. package/DEV-cjs/core/ButtonGroup/ButtonGroup.js +32 -27
  4. package/DEV-cjs/core/ComboBox/ComboBox.js +9 -6
  5. package/DEV-cjs/core/DatePicker/DatePicker.js +14 -4
  6. package/DEV-cjs/core/Popover/Popover.js +44 -16
  7. package/DEV-cjs/core/ProgressIndicators/ProgressLinear.js +2 -1
  8. package/DEV-cjs/core/Select/SelectTagContainer.js +27 -13
  9. package/DEV-cjs/core/Table/ColumnHeader.js +21 -28
  10. package/DEV-cjs/core/Table/Table.js +17 -10
  11. package/DEV-cjs/core/Table/TablePaginator.js +111 -88
  12. package/DEV-cjs/core/Table/cells/DefaultCell.js +3 -3
  13. package/DEV-cjs/core/Table/utils.js +3 -3
  14. package/DEV-cjs/core/TransferList/TransferList.js +18 -6
  15. package/DEV-cjs/styles.js +1 -1
  16. package/DEV-cjs/utils/components/MiddleTextTruncation.js +19 -14
  17. package/DEV-cjs/utils/components/OverflowContainer.js +63 -0
  18. package/DEV-cjs/utils/components/index.js +1 -0
  19. package/DEV-cjs/utils/hooks/useOverflow.js +12 -8
  20. package/DEV-esm/core/Breadcrumbs/Breadcrumbs.js +86 -67
  21. package/DEV-esm/core/ButtonGroup/ButtonGroup.js +33 -28
  22. package/DEV-esm/core/ComboBox/ComboBox.js +9 -6
  23. package/DEV-esm/core/DatePicker/DatePicker.js +12 -4
  24. package/DEV-esm/core/Popover/Popover.js +45 -17
  25. package/DEV-esm/core/ProgressIndicators/ProgressLinear.js +2 -1
  26. package/DEV-esm/core/Select/SelectTagContainer.js +24 -13
  27. package/DEV-esm/core/Table/ColumnHeader.js +28 -29
  28. package/DEV-esm/core/Table/Table.js +18 -11
  29. package/DEV-esm/core/Table/TablePaginator.js +112 -89
  30. package/DEV-esm/core/Table/cells/DefaultCell.js +4 -4
  31. package/DEV-esm/core/Table/utils.js +1 -1
  32. package/DEV-esm/core/TransferList/TransferList.js +14 -2
  33. package/DEV-esm/styles.js +1 -1
  34. package/DEV-esm/utils/components/MiddleTextTruncation.js +19 -14
  35. package/DEV-esm/utils/components/OverflowContainer.js +50 -0
  36. package/DEV-esm/utils/components/index.js +1 -0
  37. package/DEV-esm/utils/hooks/useOverflow.js +8 -8
  38. package/cjs/core/Breadcrumbs/Breadcrumbs.js +84 -64
  39. package/cjs/core/ButtonGroup/ButtonGroup.js +32 -27
  40. package/cjs/core/ComboBox/ComboBox.js +9 -6
  41. package/cjs/core/DatePicker/DatePicker.js +14 -4
  42. package/cjs/core/Popover/Popover.d.ts +10 -0
  43. package/cjs/core/Popover/Popover.js +44 -16
  44. package/cjs/core/ProgressIndicators/ProgressLinear.js +2 -1
  45. package/cjs/core/Select/SelectTagContainer.js +27 -13
  46. package/cjs/core/Table/ColumnHeader.d.ts +8 -12
  47. package/cjs/core/Table/ColumnHeader.js +21 -28
  48. package/cjs/core/Table/Table.js +13 -10
  49. package/cjs/core/Table/TablePaginator.js +111 -88
  50. package/cjs/core/Table/cells/DefaultCell.js +3 -3
  51. package/cjs/core/Table/utils.d.ts +2 -2
  52. package/cjs/core/Table/utils.js +3 -3
  53. package/cjs/core/TransferList/TransferList.d.ts +1 -1
  54. package/cjs/core/TransferList/TransferList.js +18 -6
  55. package/cjs/styles.js +1 -1
  56. package/cjs/utils/components/MiddleTextTruncation.js +19 -14
  57. package/cjs/utils/components/OverflowContainer.d.ts +37 -0
  58. package/cjs/utils/components/OverflowContainer.js +62 -0
  59. package/cjs/utils/components/index.d.ts +1 -0
  60. package/cjs/utils/components/index.js +1 -0
  61. package/cjs/utils/hooks/useOverflow.d.ts +2 -3
  62. package/cjs/utils/hooks/useOverflow.js +12 -8
  63. package/esm/core/Breadcrumbs/Breadcrumbs.js +85 -66
  64. package/esm/core/ButtonGroup/ButtonGroup.js +33 -28
  65. package/esm/core/ComboBox/ComboBox.js +9 -6
  66. package/esm/core/DatePicker/DatePicker.js +12 -4
  67. package/esm/core/Popover/Popover.d.ts +10 -0
  68. package/esm/core/Popover/Popover.js +45 -17
  69. package/esm/core/ProgressIndicators/ProgressLinear.js +2 -1
  70. package/esm/core/Select/SelectTagContainer.js +24 -13
  71. package/esm/core/Table/ColumnHeader.d.ts +8 -12
  72. package/esm/core/Table/ColumnHeader.js +28 -29
  73. package/esm/core/Table/Table.js +14 -11
  74. package/esm/core/Table/TablePaginator.js +112 -89
  75. package/esm/core/Table/cells/DefaultCell.js +4 -4
  76. package/esm/core/Table/utils.d.ts +2 -2
  77. package/esm/core/Table/utils.js +1 -1
  78. package/esm/core/TransferList/TransferList.d.ts +1 -1
  79. package/esm/core/TransferList/TransferList.js +14 -2
  80. package/esm/styles.js +1 -1
  81. package/esm/utils/components/MiddleTextTruncation.js +19 -14
  82. package/esm/utils/components/OverflowContainer.d.ts +37 -0
  83. package/esm/utils/components/OverflowContainer.js +49 -0
  84. package/esm/utils/components/index.d.ts +1 -0
  85. package/esm/utils/components/index.js +1 -0
  86. package/esm/utils/hooks/useOverflow.d.ts +2 -3
  87. package/esm/utils/hooks/useOverflow.js +8 -8
  88. package/package.json +1 -1
  89. package/styles.css +8 -8
@@ -1,104 +1,123 @@
1
1
  import * as React from 'react';
2
2
  import cx from 'classnames';
3
3
  import {
4
- useMergedRefs,
5
- useOverflow,
6
4
  SvgChevronRight,
7
5
  Box,
6
+ OverflowContainer,
8
7
  useWarningLogger,
9
8
  } from '../../utils/index.js';
10
9
  import { Button } from '../Buttons/Button.js';
11
10
  import { Anchor } from '../Typography/Anchor.js';
12
11
  let BreadcrumbsComponent = React.forwardRef((props, ref) => {
13
12
  let {
14
- children: items,
15
- currentIndex = items.length - 1,
13
+ children: childrenProp,
14
+ currentIndex = React.Children.count(childrenProp) - 1,
16
15
  separator,
17
16
  overflowButton,
18
17
  className,
19
18
  ...rest
20
19
  } = props;
21
- let [overflowRef, visibleCount] = useOverflow(items);
22
- let refs = useMergedRefs(overflowRef, ref);
20
+ let items = React.useMemo(
21
+ () => React.Children.toArray(childrenProp),
22
+ [childrenProp],
23
+ );
23
24
  return React.createElement(
24
25
  Box,
25
26
  {
26
27
  as: 'nav',
27
28
  className: cx('iui-breadcrumbs', className),
28
- ref: refs,
29
+ ref: ref,
29
30
  'aria-label': 'Breadcrumb',
30
31
  ...rest,
31
32
  },
32
33
  React.createElement(
33
- Box,
34
+ OverflowContainer,
34
35
  {
35
36
  as: 'ol',
37
+ itemsCount: items.length,
36
38
  className: 'iui-breadcrumbs-list',
37
39
  },
38
- visibleCount > 1 &&
40
+ React.createElement(
41
+ BreadcrumbContent,
42
+ {
43
+ currentIndex: currentIndex,
44
+ overflowButton: overflowButton,
45
+ separator: separator,
46
+ },
47
+ items,
48
+ ),
49
+ ),
50
+ );
51
+ });
52
+ let BreadcrumbContent = (props) => {
53
+ let { children: items, currentIndex, overflowButton, separator } = props;
54
+ let { visibleCount } = OverflowContainer.useContext();
55
+ return React.createElement(
56
+ React.Fragment,
57
+ null,
58
+ visibleCount > 1 &&
59
+ React.createElement(
60
+ React.Fragment,
61
+ null,
62
+ React.createElement(ListItem, {
63
+ item: items[0],
64
+ isActive: 0 === currentIndex,
65
+ }),
66
+ React.createElement(Separator, {
67
+ separator: separator,
68
+ }),
69
+ ),
70
+ items.length - visibleCount > 0 &&
71
+ React.createElement(
72
+ React.Fragment,
73
+ null,
39
74
  React.createElement(
40
- React.Fragment,
41
- null,
42
- React.createElement(ListItem, {
43
- item: items[0],
44
- isActive: 0 === currentIndex,
45
- }),
46
- React.createElement(Separator, {
47
- separator: separator,
48
- }),
75
+ Box,
76
+ {
77
+ as: 'li',
78
+ className: 'iui-breadcrumbs-item',
79
+ },
80
+ overflowButton
81
+ ? overflowButton(visibleCount)
82
+ : React.createElement(
83
+ Box,
84
+ {
85
+ as: 'span',
86
+ className: 'iui-breadcrumbs-content',
87
+ },
88
+ '…',
89
+ ),
49
90
  ),
50
- items.length - visibleCount > 0 &&
51
- React.createElement(
91
+ React.createElement(Separator, {
92
+ separator: separator,
93
+ }),
94
+ ),
95
+ items
96
+ .slice(
97
+ visibleCount > 1 ? items.length - visibleCount + 1 : items.length - 1,
98
+ )
99
+ .map((_, _index) => {
100
+ let index =
101
+ visibleCount > 1
102
+ ? 1 + (items.length - visibleCount) + _index
103
+ : items.length - 1;
104
+ return React.createElement(
52
105
  React.Fragment,
53
- null,
54
- React.createElement(
55
- Box,
56
- {
57
- as: 'li',
58
- className: 'iui-breadcrumbs-item',
59
- },
60
- overflowButton
61
- ? overflowButton(visibleCount)
62
- : React.createElement(
63
- Box,
64
- {
65
- as: 'span',
66
- className: 'iui-breadcrumbs-content',
67
- },
68
- '…',
69
- ),
70
- ),
71
- React.createElement(Separator, {
72
- separator: separator,
106
+ {
107
+ key: index,
108
+ },
109
+ React.createElement(ListItem, {
110
+ item: items[index],
111
+ isActive: currentIndex === index,
73
112
  }),
74
- ),
75
- items
76
- .slice(
77
- visibleCount > 1 ? items.length - visibleCount + 1 : items.length - 1,
78
- )
79
- .map((_, _index) => {
80
- let index =
81
- visibleCount > 1
82
- ? 1 + (items.length - visibleCount) + _index
83
- : items.length - 1;
84
- return React.createElement(
85
- React.Fragment,
86
- {
87
- key: index,
88
- },
89
- React.createElement(ListItem, {
90
- item: items[index],
91
- isActive: currentIndex === index,
113
+ index < items.length - 1 &&
114
+ React.createElement(Separator, {
115
+ separator: separator,
92
116
  }),
93
- index < items.length - 1 &&
94
- React.createElement(Separator, {
95
- separator: separator,
96
- }),
97
- );
98
- }),
99
- ),
117
+ );
118
+ }),
100
119
  );
101
- });
120
+ };
102
121
  let ListItem = ({ item, isActive }) => {
103
122
  let children = item;
104
123
  let logWarning = useWarningLogger();
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import cx from 'classnames';
3
- import { useOverflow, useMergedRefs, Box } from '../../utils/index.js';
3
+ import { Box, OverflowContainer } from '../../utils/index.js';
4
4
  import {
5
5
  Composite,
6
6
  CompositeItem,
@@ -91,14 +91,12 @@ let OverflowGroup = React.forwardRef((props, forwardedRef) => {
91
91
  () => React.Children.toArray(childrenProp).filter(Boolean),
92
92
  [childrenProp],
93
93
  );
94
- let [overflowRef, visibleCount] = useOverflow(
95
- items,
96
- !overflowButton,
97
- orientation,
98
- );
99
94
  return React.createElement(
100
- BaseGroup,
95
+ OverflowContainer,
101
96
  {
97
+ as: BaseGroup,
98
+ itemsCount: items.length,
99
+ overflowOrientation: orientation,
102
100
  orientation: orientation,
103
101
  ...rest,
104
102
  className: cx(
@@ -108,27 +106,34 @@ let OverflowGroup = React.forwardRef((props, forwardedRef) => {
108
106
  },
109
107
  props.className,
110
108
  ),
111
- ref: useMergedRefs(forwardedRef, overflowRef),
109
+ ref: forwardedRef,
112
110
  },
113
- (() => {
114
- if (!(visibleCount < items.length)) return items;
115
- let overflowStart =
116
- 'start' === overflowPlacement
117
- ? items.length - visibleCount
118
- : visibleCount - 1;
119
- return React.createElement(
120
- React.Fragment,
121
- null,
122
- overflowButton &&
123
- 'start' === overflowPlacement &&
124
- overflowButton(overflowStart),
125
- 'start' === overflowPlacement
126
- ? items.slice(overflowStart + 1)
127
- : items.slice(0, Math.max(0, overflowStart)),
128
- overflowButton &&
129
- 'end' === overflowPlacement &&
130
- overflowButton(overflowStart),
131
- );
132
- })(),
111
+ React.createElement(OverflowGroupContent, {
112
+ overflowButton: overflowButton,
113
+ overflowPlacement: overflowPlacement,
114
+ items: items,
115
+ }),
133
116
  );
134
117
  });
118
+ let OverflowGroupContent = (props) => {
119
+ let { overflowButton, overflowPlacement, items } = props;
120
+ let { visibleCount } = OverflowContainer.useContext();
121
+ let overflowStart =
122
+ 'start' === overflowPlacement
123
+ ? items.length - visibleCount
124
+ : visibleCount - 1;
125
+ if (!(visibleCount < items.length)) return items;
126
+ return React.createElement(
127
+ React.Fragment,
128
+ null,
129
+ overflowButton &&
130
+ 'start' === overflowPlacement &&
131
+ overflowButton(overflowStart),
132
+ 'start' === overflowPlacement
133
+ ? items.slice(overflowStart + 1)
134
+ : items.slice(0, Math.max(0, overflowStart)),
135
+ overflowButton &&
136
+ 'end' === overflowPlacement &&
137
+ overflowButton(overflowStart),
138
+ );
139
+ };
@@ -113,12 +113,14 @@ export const ComboBox = React.forwardRef((props, forwardedRef) => {
113
113
  setFocusedIndex(selectedIndexes ?? -1);
114
114
  } else {
115
115
  setFocusedIndex(-1);
116
- if (!isMultipleEnabled(selectedIndexes, multiple))
117
- setInputValue(
118
- selectedIndexes >= 0
119
- ? optionsRef.current[selectedIndexes]?.label ?? ''
120
- : '',
121
- );
116
+ isMultipleEnabled(selectedIndexes, multiple)
117
+ ? setInputValue('')
118
+ : setInputValue(
119
+ selectedIndexes >= 0
120
+ ? optionsRef.current[selectedIndexes]?.label ?? ''
121
+ : '',
122
+ );
123
+ setIsInputDirty(false);
122
124
  }
123
125
  }, [isOpen, multiple, optionsRef, selectedIndexes]);
124
126
  let previousOptions = React.useRef(options);
@@ -216,6 +218,7 @@ export const ComboBox = React.forwardRef((props, forwardedRef) => {
216
218
  .filter(Boolean)
217
219
  .join(', '),
218
220
  );
221
+ setInputValue('');
219
222
  } else {
220
223
  setSelectedIndexes(__originalIndex);
221
224
  hide();
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../utils/index.js';
12
12
  import { IconButton } from '../Buttons/IconButton.js';
13
13
  import { TimePicker } from '../TimePicker/TimePicker.js';
14
+ import { PopoverInitialFocusContext } from '../Popover/Popover.js';
14
15
  let isSameDay = (a, b) =>
15
16
  a &&
16
17
  b &&
@@ -175,6 +176,11 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
175
176
  currentDate.getFullYear(),
176
177
  );
177
178
  }, [date, setMonthAndYear, startDate, endDate, enableRangeSelect]);
179
+ let popoverInitialFocusContext = React.useContext(PopoverInitialFocusContext);
180
+ React.useLayoutEffect(() => {
181
+ if (setFocus && popoverInitialFocusContext)
182
+ popoverInitialFocusContext.setInitialFocus(-1);
183
+ }, [popoverInitialFocusContext, setFocus]);
178
184
  let days = React.useMemo(() => {
179
185
  let offsetToFirst = new Date(
180
186
  displayedYear,
@@ -499,10 +505,12 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
499
505
  role: 'option',
500
506
  tabIndex: isSameDay(weekDay, focusedDay) ? 0 : -1,
501
507
  'aria-disabled': isDisabled ? 'true' : void 0,
502
- ref: (element) =>
503
- isSameDay(weekDay, focusedDay) &&
504
- needFocus.current &&
505
- element?.focus(),
508
+ ref: (element) => {
509
+ if (isSameDay(weekDay, focusedDay) && needFocus.current)
510
+ setTimeout(() => {
511
+ element?.focus();
512
+ });
513
+ },
506
514
  ...dayProps,
507
515
  className: cx(getDayClass(weekDay), dayProps?.className),
508
516
  },
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { FloatingFocusManager } from '@floating-ui/react';
2
3
  import type { Placement, UseFloatingOptions, UseHoverProps, UseClickProps, UseFocusProps, UseDismissProps } from '@floating-ui/react';
3
4
  import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
4
5
  import type { PortalProps } from '../../utils/components/Portal.js';
@@ -97,8 +98,17 @@ type PopoverInternalProps = {
97
98
  */
98
99
  matchWidth?: boolean;
99
100
  } & Omit<UseFloatingOptions, 'middleware' | 'placement'>;
101
+ type InitialFocus = React.ComponentPropsWithoutRef<typeof FloatingFocusManager>['initialFocus'];
100
102
  /** Stores the current open/closed state of the popover. */
101
103
  export declare const PopoverOpenContext: React.Context<boolean | undefined>;
104
+ /**
105
+ * Stores the initialFocus of the popover.
106
+ *
107
+ * E.g. Popover's descendants can disable the popover's initialFocus to prevent conflicts with its own focus management.
108
+ */
109
+ export declare const PopoverInitialFocusContext: React.Context<{
110
+ setInitialFocus: React.Dispatch<React.SetStateAction<InitialFocus>>;
111
+ } | undefined>;
102
112
  export declare const usePopover: (options: PopoverOptions & PopoverInternalProps) => {
103
113
  placement: Placement;
104
114
  strategy: import("@floating-ui/utils").Strategy;
@@ -33,7 +33,9 @@ import {
33
33
  useMergedRefs,
34
34
  } from '../../utils/index.js';
35
35
  import { usePortalTo } from '../../utils/components/Portal.js';
36
+ import { ThemeProvider } from '../ThemeProvider/ThemeProvider.js';
36
37
  export const PopoverOpenContext = React.createContext(void 0);
38
+ export const PopoverInitialFocusContext = React.createContext(void 0);
37
39
  export const usePopover = (options) => {
38
40
  let {
39
41
  placement = 'bottom-start',
@@ -231,7 +233,12 @@ export const Popover = React.forwardRef((props, forwardedRef) => {
231
233
  role: 'dialog',
232
234
  middleware,
233
235
  });
234
- let popoverRef = useMergedRefs(popover.refs.setFloating, forwardedRef);
236
+ let [popoverElement, setPopoverElement] = React.useState();
237
+ let popoverRef = useMergedRefs(
238
+ popover.refs.setFloating,
239
+ forwardedRef,
240
+ setPopoverElement,
241
+ );
235
242
  let triggerId = `${useId()}-trigger`;
236
243
  let hasAriaLabel = !!props['aria-labelledby'] || !!props['aria-label'];
237
244
  useLayoutEffect(() => {
@@ -239,6 +246,13 @@ export const Popover = React.forwardRef((props, forwardedRef) => {
239
246
  popover.refs.setPositionReference(positionReference);
240
247
  return () => void popover.refs.setPositionReference(null);
241
248
  }, [popover.refs, positionReference]);
249
+ let [initialFocus, setInitialFocus] = React.useState();
250
+ let initialFocusContextValue = React.useMemo(
251
+ () => ({
252
+ setInitialFocus,
253
+ }),
254
+ [],
255
+ );
242
256
  return React.createElement(
243
257
  React.Fragment,
244
258
  null,
@@ -255,32 +269,46 @@ export const Popover = React.forwardRef((props, forwardedRef) => {
255
269
  ),
256
270
  popover.open
257
271
  ? React.createElement(
258
- PopoverPortal,
272
+ PopoverInitialFocusContext.Provider,
259
273
  {
260
- portal: portal,
274
+ value: initialFocusContextValue,
261
275
  },
262
276
  React.createElement(
263
- FloatingFocusManager,
277
+ PopoverPortal,
264
278
  {
265
- context: popover.context,
266
- modal: false,
279
+ portal: portal,
267
280
  },
268
281
  React.createElement(
269
- Box,
282
+ ThemeProvider,
270
283
  {
271
- className: cx(
284
+ portalContainer: popoverElement,
285
+ },
286
+ React.createElement(DisplayContents, null),
287
+ React.createElement(
288
+ FloatingFocusManager,
289
+ {
290
+ context: popover.context,
291
+ modal: false,
292
+ initialFocus: initialFocus,
293
+ },
294
+ React.createElement(
295
+ Box,
272
296
  {
273
- 'iui-popover-surface': applyBackground,
297
+ className: cx(
298
+ {
299
+ 'iui-popover-surface': applyBackground,
300
+ },
301
+ className,
302
+ ),
303
+ 'aria-labelledby': hasAriaLabel
304
+ ? void 0
305
+ : popover.refs.domReference.current?.id,
306
+ ...popover.getFloatingProps(rest),
307
+ ref: popoverRef,
274
308
  },
275
- className,
309
+ content,
276
310
  ),
277
- 'aria-labelledby': hasAriaLabel
278
- ? void 0
279
- : popover.refs.domReference.current?.id,
280
- ...popover.getFloatingProps(rest),
281
- ref: popoverRef,
282
- },
283
- content,
311
+ ),
284
312
  ),
285
313
  ),
286
314
  )
@@ -22,10 +22,11 @@ export const ProgressLinear = React.forwardRef((props, forwardedRef) => {
22
22
  'data-iui-status': status,
23
23
  'data-iui-indeterminate': indeterminate ? 'true' : void 0,
24
24
  'data-iui-animated': isAnimated ? 'true' : void 0,
25
+ ...rest,
25
26
  style: {
26
27
  '--iui-progress-percentage': `${boundedValue}%`,
28
+ ...props.style,
27
29
  },
28
- ...rest,
29
30
  },
30
31
  React.createElement(
31
32
  ShadowRoot,
@@ -1,26 +1,37 @@
1
1
  import * as React from 'react';
2
2
  import cx from 'classnames';
3
- import { useOverflow, useMergedRefs, Box } from '../../utils/index.js';
4
3
  import { SelectTag } from './SelectTag.js';
4
+ import { OverflowContainer } from '../../utils/index.js';
5
5
  export const SelectTagContainer = React.forwardRef((props, ref) => {
6
- let { tags, className, ...rest } = props;
7
- let [containerRef, visibleCount] = useOverflow(tags);
8
- let refs = useMergedRefs(ref, containerRef);
6
+ let { tags: tagsProp, className, ...rest } = props;
7
+ let tags = React.useMemo(() => React.Children.toArray(tagsProp), [tagsProp]);
9
8
  return React.createElement(
10
- Box,
9
+ OverflowContainer,
11
10
  {
11
+ itemsCount: tags.length,
12
12
  className: cx('iui-select-tag-container', className),
13
- ref: refs,
13
+ ref: ref,
14
14
  ...rest,
15
15
  },
16
+ React.createElement(SelectTagContainerContent, {
17
+ ...props,
18
+ tags: tags,
19
+ }),
20
+ );
21
+ });
22
+ let SelectTagContainerContent = (props) => {
23
+ let { tags } = props;
24
+ let { visibleCount } = OverflowContainer.useContext();
25
+ return React.createElement(
26
+ React.Fragment,
27
+ null,
28
+ visibleCount < tags.length ? tags.slice(0, visibleCount - 1) : tags,
16
29
  React.createElement(
17
- React.Fragment,
30
+ OverflowContainer.OverflowNode,
18
31
  null,
19
- visibleCount < tags.length ? tags.slice(0, visibleCount - 1) : tags,
20
- visibleCount < tags.length &&
21
- React.createElement(SelectTag, {
22
- label: `+${tags.length - visibleCount + 1} item(s)`,
23
- }),
32
+ React.createElement(SelectTag, {
33
+ label: `+${tags.length - visibleCount + 1} item(s)`,
34
+ }),
24
35
  ),
25
36
  );
26
- });
37
+ };
@@ -1,19 +1,15 @@
1
- import * as React from 'react';
2
- import type { ColumnInstance, HeaderGroup, TableKeyedProps, TableState } from '../../react-table/react-table.js';
3
- type ColumnHeaderProps<T extends Record<string, unknown> = Record<string, unknown>> = TableKeyedProps & {
4
- columnRefs: React.MutableRefObject<Record<string, HTMLDivElement>>;
5
- column: HeaderGroup<T>;
6
- index: number;
1
+ import { type PolymorphicForwardRefComponent } from '../../utils/index.js';
2
+ import type { HeaderGroup, TableKeyedProps } from '../../react-table/react-table.js';
3
+ type ColumnHeaderProps = TableKeyedProps & {
4
+ column: HeaderGroup<Record<string, unknown>>;
7
5
  areFiltersSet: boolean;
8
- hasAnySubRows: boolean;
9
- headers: HeaderGroup<T>[];
10
- state: TableState<T>;
11
- data: T[];
12
6
  isResizable: boolean;
13
7
  columnResizeMode: 'fit' | 'expand';
14
8
  enableColumnReordering: boolean;
15
9
  density: string | undefined;
16
- visibleColumns: ColumnInstance<T>[];
10
+ columnHasExpanders: boolean;
11
+ isLast: boolean;
12
+ isTableEmpty: boolean;
17
13
  };
18
- export declare const ColumnHeader: <T extends Record<string, unknown> = Record<string, unknown>>(props: ColumnHeaderProps<T>) => JSX.Element;
14
+ export declare const ColumnHeader: PolymorphicForwardRefComponent<"div", ColumnHeaderProps>;
19
15
  export {};
@@ -5,40 +5,39 @@ import {
5
5
  LineClamp,
6
6
  SvgSortDown,
7
7
  SvgSortUp,
8
+ useMergedRefs,
8
9
  } from '../../utils/index.js';
9
- import { SELECTION_CELL_ID } from './columns/index.js';
10
10
  import { FilterToggle } from './filters/FilterToggle.js';
11
- import { getCellStyle, getSubRowStyle, getStickyStyle } from './utils.js';
11
+ import {
12
+ getCellStyle,
13
+ getSubRowStyle,
14
+ getStickyStyle,
15
+ TableInstanceContext,
16
+ } from './utils.js';
12
17
  import cx from 'classnames';
13
- export const ColumnHeader = (props) => {
18
+ export const ColumnHeader = React.forwardRef((props, forwardedRef) => {
14
19
  let {
15
- columnRefs,
16
20
  column,
17
- index,
18
21
  areFiltersSet,
19
- hasAnySubRows,
20
- headers,
21
- state,
22
- data,
23
22
  isResizable,
24
23
  columnResizeMode,
25
24
  enableColumnReordering,
26
25
  density,
27
- visibleColumns,
26
+ columnHasExpanders,
27
+ isLast,
28
+ isTableEmpty,
28
29
  ...rest
29
30
  } = props;
30
31
  let isHeaderDirectClick = React.useRef(false);
32
+ let instance = React.useContext(TableInstanceContext);
31
33
  let COLUMN_MIN_WIDTHS = {
32
34
  default: 72,
33
35
  withExpander: 108,
34
36
  };
35
37
  let showFilterButton = (column) =>
36
- (0 !== data.length || areFiltersSet) && column.canFilter && !!column.Filter;
37
- let showSortButton = (column) => 0 !== data.length && column.canSort;
38
+ (!isTableEmpty || areFiltersSet) && column.canFilter && !!column.Filter;
39
+ let showSortButton = (column) => !isTableEmpty && column.canSort;
38
40
  let { onClick, ...restSortProps } = column.getSortByToggleProps();
39
- let columnHasExpanders =
40
- hasAnySubRows &&
41
- index === headers.findIndex((c) => c.id !== SELECTION_CELL_ID);
42
41
  if ([void 0, 0].includes(column.minWidth)) {
43
42
  column.minWidth = columnHasExpanders
44
43
  ? COLUMN_MIN_WIDTHS.withExpander
@@ -58,12 +57,12 @@ export const ColumnHeader = (props) => {
58
57
  column.columnClassName,
59
58
  ),
60
59
  style: {
61
- ...getCellStyle(column, !!state.isTableResizing),
60
+ ...getCellStyle(column, !!instance?.state.isTableResizing),
62
61
  ...(columnHasExpanders &&
63
62
  getSubRowStyle({
64
63
  density,
65
64
  })),
66
- ...getStickyStyle(column, visibleColumns),
65
+ ...getStickyStyle(column, instance?.visibleColumns ?? []),
67
66
  flexWrap: 'wrap',
68
67
  columnGap: 'var(--iui-size-xs)',
69
68
  },
@@ -75,14 +74,14 @@ export const ColumnHeader = (props) => {
75
74
  ...rest,
76
75
  key: columnProps.key,
77
76
  title: void 0,
78
- ref: React.useCallback(
79
- (el) => {
80
- if (el) {
81
- columnRefs.current[column.id] = el;
82
- column.resizeWidth = el.getBoundingClientRect().width;
83
- }
84
- },
85
- [column, columnRefs],
77
+ ref: useMergedRefs(
78
+ React.useCallback(
79
+ (el) => {
80
+ if (el) column.resizeWidth = el.getBoundingClientRect().width;
81
+ },
82
+ [column],
83
+ ),
84
+ forwardedRef,
86
85
  ),
87
86
  onMouseDown: () => {
88
87
  isHeaderDirectClick.current = true;
@@ -153,7 +152,7 @@ export const ColumnHeader = (props) => {
153
152
  ),
154
153
  isResizable &&
155
154
  column.isResizerVisible &&
156
- (index !== headers.length - 1 || 'expand' === columnResizeMode) &&
155
+ (!isLast || 'expand' === columnResizeMode) &&
157
156
  React.createElement(
158
157
  Box,
159
158
  {
@@ -172,17 +171,17 @@ export const ColumnHeader = (props) => {
172
171
  slot: 'resizers',
173
172
  }),
174
173
  'left' === column.sticky &&
175
- state.sticky.isScrolledToRight &&
174
+ instance?.state.sticky.isScrolledToRight &&
176
175
  React.createElement(Box, {
177
176
  className: 'iui-table-cell-shadow-right',
178
177
  slot: 'shadows',
179
178
  }),
180
179
  'right' === column.sticky &&
181
- state.sticky.isScrolledToLeft &&
180
+ instance?.state.sticky.isScrolledToLeft &&
182
181
  React.createElement(Box, {
183
182
  className: 'iui-table-cell-shadow-left',
184
183
  slot: 'shadows',
185
184
  }),
186
185
  ),
187
186
  );
188
- };
187
+ });