@itwin/itwinui-react 1.32.0-dev.0 → 1.33.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/cjs/core/ButtonGroup/ButtonGroup.d.ts +6 -1
  3. package/cjs/core/ButtonGroup/ButtonGroup.js +6 -3
  4. package/cjs/core/Checkbox/Checkbox.d.ts +13 -0
  5. package/cjs/core/Checkbox/Checkbox.js +15 -22
  6. package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
  7. package/cjs/core/ComboBox/ComboBox.d.ts +17 -1
  8. package/cjs/core/ComboBox/ComboBox.js +55 -20
  9. package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +6 -0
  10. package/cjs/core/ExpandableBlock/ExpandableBlock.js +3 -2
  11. package/cjs/core/Footer/Footer.d.ts +14 -2
  12. package/cjs/core/Footer/Footer.js +40 -17
  13. package/cjs/core/InputGroup/InputGroup.js +12 -2
  14. package/cjs/core/LabeledSelect/LabeledSelect.js +10 -4
  15. package/cjs/core/Menu/Menu.js +3 -3
  16. package/cjs/core/Radio/Radio.d.ts +13 -0
  17. package/cjs/core/Radio/Radio.js +7 -8
  18. package/cjs/core/Slider/Slider.js +10 -1
  19. package/cjs/core/StatusMessage/StatusMessage.d.ts +24 -0
  20. package/cjs/core/StatusMessage/StatusMessage.js +39 -0
  21. package/cjs/core/StatusMessage/index.d.ts +4 -0
  22. package/cjs/core/StatusMessage/index.js +10 -0
  23. package/cjs/core/Table/hooks/useSelectionCell.js +1 -2
  24. package/cjs/core/Tree/Tree.d.ts +123 -0
  25. package/cjs/core/Tree/Tree.js +177 -0
  26. package/cjs/core/Tree/TreeContext.d.ts +25 -0
  27. package/cjs/core/Tree/TreeContext.js +20 -0
  28. package/cjs/core/Tree/TreeNode.d.ts +87 -0
  29. package/cjs/core/Tree/TreeNode.js +169 -0
  30. package/cjs/core/Tree/TreeNodeExpander.d.ts +8 -0
  31. package/cjs/core/Tree/TreeNodeExpander.js +46 -0
  32. package/cjs/core/Tree/index.d.ts +6 -0
  33. package/cjs/core/Tree/index.js +13 -0
  34. package/cjs/core/index.d.ts +4 -0
  35. package/cjs/core/index.js +7 -1
  36. package/cjs/core/utils/components/InputContainer.d.ts +1 -0
  37. package/cjs/core/utils/components/InputContainer.js +8 -7
  38. package/cjs/core/utils/functions/focusable.js +6 -2
  39. package/cjs/core/utils/hooks/useIntersection.d.ts +4 -3
  40. package/cjs/core/utils/hooks/useIntersection.js +10 -5
  41. package/cjs/core/utils/hooks/useOverflow.d.ts +3 -2
  42. package/cjs/core/utils/hooks/useOverflow.js +24 -21
  43. package/esm/core/ButtonGroup/ButtonGroup.d.ts +6 -1
  44. package/esm/core/ButtonGroup/ButtonGroup.js +6 -3
  45. package/esm/core/Checkbox/Checkbox.d.ts +13 -0
  46. package/esm/core/Checkbox/Checkbox.js +15 -22
  47. package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
  48. package/esm/core/ComboBox/ComboBox.d.ts +17 -1
  49. package/esm/core/ComboBox/ComboBox.js +56 -21
  50. package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +6 -0
  51. package/esm/core/ExpandableBlock/ExpandableBlock.js +3 -2
  52. package/esm/core/Footer/Footer.d.ts +14 -2
  53. package/esm/core/Footer/Footer.js +40 -17
  54. package/esm/core/InputGroup/InputGroup.js +12 -2
  55. package/esm/core/LabeledSelect/LabeledSelect.js +10 -4
  56. package/esm/core/Menu/Menu.js +3 -3
  57. package/esm/core/Radio/Radio.d.ts +13 -0
  58. package/esm/core/Radio/Radio.js +7 -8
  59. package/esm/core/Slider/Slider.js +10 -1
  60. package/esm/core/StatusMessage/StatusMessage.d.ts +24 -0
  61. package/esm/core/StatusMessage/StatusMessage.js +32 -0
  62. package/esm/core/StatusMessage/index.d.ts +4 -0
  63. package/esm/core/StatusMessage/index.js +6 -0
  64. package/esm/core/Table/hooks/useSelectionCell.js +1 -2
  65. package/esm/core/Tree/Tree.d.ts +123 -0
  66. package/esm/core/Tree/Tree.js +170 -0
  67. package/esm/core/Tree/TreeContext.d.ts +25 -0
  68. package/esm/core/Tree/TreeContext.js +13 -0
  69. package/esm/core/Tree/TreeNode.d.ts +87 -0
  70. package/esm/core/Tree/TreeNode.js +162 -0
  71. package/esm/core/Tree/TreeNodeExpander.d.ts +8 -0
  72. package/esm/core/Tree/TreeNodeExpander.js +39 -0
  73. package/esm/core/Tree/index.d.ts +6 -0
  74. package/esm/core/Tree/index.js +7 -0
  75. package/esm/core/index.d.ts +4 -0
  76. package/esm/core/index.js +2 -0
  77. package/esm/core/utils/components/InputContainer.d.ts +1 -0
  78. package/esm/core/utils/components/InputContainer.js +8 -7
  79. package/esm/core/utils/functions/focusable.js +6 -2
  80. package/esm/core/utils/hooks/useIntersection.d.ts +4 -3
  81. package/esm/core/utils/hooks/useIntersection.js +10 -5
  82. package/esm/core/utils/hooks/useOverflow.d.ts +3 -2
  83. package/esm/core/utils/hooks/useOverflow.js +24 -21
  84. package/package.json +15 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ### [1.33.1](https://www.github.com/iTwin/iTwinUI-react/compare/v1.33.0...v1.33.1) (2022-03-18)
4
+
5
+ ### Fixes
6
+
7
+ * **ButtonGroup:** Add vertical support to `overflowButton` ([#579](https://www.github.com/iTwin/iTwinUI-react/issues/579)) ([aad619b](https://www.github.com/iTwin/iTwinUI-react/commit/aad619b6dc7d65ffd79c8d33111489b1b8d27680))
8
+ * **Slider:** Fixed to call onUpdate on rail click ([#587](https://www.github.com/iTwin/iTwinUI-react/issues/587)) ([e7cc679](https://www.github.com/iTwin/iTwinUI-react/commit/e7cc6796308928230f2d2c7c79b6ee35286595a7))
9
+ * **Table:** Removed wrapper span from checkbox ([#583](https://www.github.com/iTwin/iTwinUI-react/issues/583)) ([996377b](https://www.github.com/iTwin/iTwinUI-react/commit/996377bf44cdacd9f42361f2199c2a83420ca15b))
10
+
11
+ ## [1.33.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.32.0...v1.33.0) (2022-03-07)
12
+
13
+ ### What's new
14
+
15
+ * **ButtonGroup:** Add new `orientation` prop to allow showing vertical group ([#577](https://www.github.com/iTwin/iTwinUI-react/issues/577)) ([f6cd52f](https://www.github.com/iTwin/iTwinUI-react/commit/f6cd52f39dd139439281114d3ade99e486ab6bfb))
16
+ * **ComboBox:** Add new `message` prop ([#554](https://www.github.com/iTwin/iTwinUI-react/issues/554)) ([8113860](https://www.github.com/iTwin/iTwinUI-react/commit/8113860499e6156d97992919204b3b8c7e46197b))
17
+ * This new prop can accept a string or the new `StatusMessage` component for customizing icon.
18
+ * **Footer:** Allow overriding and removing default footer elements ([#544](https://www.github.com/iTwin/iTwinUI-react/issues/544)) ([76396a4](https://www.github.com/iTwin/iTwinUI-react/commit/76396a4cc0a88bb7680316cf4642b732729abd7a))
19
+
20
+ ## [1.32.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.31.0...v1.32.0) (2022-02-25)
21
+
22
+ ### What's new
23
+
24
+ * **Popover:** Append to `body` by default and increase z-index ([#562](https://www.github.com/iTwin/iTwinUI-react/issues/562)) ([66df49f](https://www.github.com/iTwin/iTwinUI-react/commit/66df49fec85ec13707cc73bb3fdf84ca3a4c7655))
25
+ - This will fix many clipping and positioning issues in tooltips and dropdowns, without the need for any workarounds.
26
+ - If a popover is nested within another popover which is already appended to document.body, then it should use `appendTo='parent'`.
27
+ * **Tree:** Add new Tree Component ([#468](https://www.github.com/iTwin/iTwinUI-react/issues/468)) ([1d5083c](https://www.github.com/iTwin/iTwinUI-react/commit/1d5083c612cd1f1b1cbec0e5ea82b8b573d72b86))
28
+ * **ComboBox:** Add new `itemRenderer` prop for customizing the look of menu items ([#547](https://www.github.com/iTwin/iTwinUI-react/issues/547)) ([d866d32](https://www.github.com/iTwin/iTwinUI-react/commit/d866d32a719dea6e359519ae40bc66dc7df209e1))
29
+ * **ExpandableBlock:** Add borderless variant via new `styleType` prop ([#557](https://www.github.com/iTwin/iTwinUI-react/issues/557)) ([9e8c8ab](https://www.github.com/iTwin/iTwinUI-react/commit/9e8c8ab76a7c6d24c51d5eea9e4424417c0e2fad))
30
+ * **Checkbox** and **Radio**: Render without `<label>` wrapper if `label` prop is not passed ([#556](https://www.github.com/iTwin/iTwinUI-react/issues/556)) ([a436cbf](https://www.github.com/iTwin/iTwinUI-react/commit/a436cbf333629b2603bf160f9a8ffe2592093805))
31
+
32
+ ### Fixes
33
+
34
+ * **Menu:** Fix lost item focus in edge cases ([#563](https://www.github.com/iTwin/iTwinUI-react/issues/563)) ([3ccb5ed](https://www.github.com/iTwin/iTwinUI-react/commit/3ccb5ed98ac4f60479e0450abb31cbb659d902b9))
35
+
3
36
  ## [1.31.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.30.0...v1.31.0) (2022-02-15)
4
37
 
5
38
  ### What's new
@@ -20,6 +20,11 @@ export declare type ButtonGroupProps = {
20
20
  * @default 'end'
21
21
  */
22
22
  overflowPlacement?: 'start' | 'end';
23
+ /**
24
+ * Should the buttons be placed in a horizontal or vertical layout?
25
+ * @default 'horizontal'
26
+ */
27
+ orientation?: 'horizontal' | 'vertical';
23
28
  } & React.ComponentPropsWithRef<'div'>;
24
29
  /**
25
30
  * Group buttons together for common actions.
@@ -49,5 +54,5 @@ export declare type ButtonGroupProps = {
49
54
  * {buttons}
50
55
  * </ButtonGroup>
51
56
  */
52
- export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
57
+ export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "orientation" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
53
58
  export default ButtonGroup;
@@ -63,12 +63,15 @@ require("@itwin/itwinui-css/css/button.css");
63
63
  * </ButtonGroup>
64
64
  */
65
65
  exports.ButtonGroup = react_1.default.forwardRef(function (props, ref) {
66
- var children = props.children, className = props.className, style = props.style, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, rest = __rest(props, ["children", "className", "style", "overflowButton", "overflowPlacement"]);
66
+ var children = props.children, className = props.className, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, _b = props.orientation, orientation = _b === void 0 ? 'horizontal' : _b, rest = __rest(props, ["children", "className", "overflowButton", "overflowPlacement", "orientation"]);
67
67
  var items = react_1.default.useMemo(function () { var _a; return (_a = react_1.default.Children.map(children, function (child) { return react_1.default.createElement("div", null, child); })) !== null && _a !== void 0 ? _a : []; }, [children]);
68
68
  (0, utils_1.useTheme)();
69
- var _b = (0, utils_1.useOverflow)(items, !overflowButton), overflowRef = _b[0], visibleCount = _b[1];
69
+ var _c = (0, utils_1.useOverflow)(items, !overflowButton, orientation), overflowRef = _c[0], visibleCount = _c[1];
70
70
  var refs = (0, utils_1.useMergedRefs)(overflowRef, ref);
71
- return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-button-group', className), style: __assign(__assign({}, (!!overflowButton && { width: '100%' })), style), ref: refs }, rest), !!overflowButton && visibleCount < items.length ? (react_1.default.createElement(react_1.default.Fragment, null,
71
+ return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)({
72
+ 'iui-button-group': orientation === 'horizontal',
73
+ 'iui-button-group-vertical': orientation === 'vertical',
74
+ }, className), "aria-orientation": orientation, ref: refs }, rest), !!overflowButton && visibleCount < items.length ? (react_1.default.createElement(react_1.default.Fragment, null,
72
75
  overflowButton && overflowPlacement === 'start' && (react_1.default.createElement("div", null, overflowButton(visibleCount))),
73
76
  items.slice(0, visibleCount - 1),
74
77
  overflowButton && overflowPlacement === 'end' && (react_1.default.createElement("div", null, overflowButton(visibleCount))))) : (items)));
@@ -30,16 +30,23 @@ export declare type CheckboxProps = {
30
30
  isLoading?: boolean;
31
31
  /**
32
32
  * Custom CSS class name for the checkmark element.
33
+ *
34
+ * @deprecated As of 1.32.0, this is applied on the actual checkbox `<input>` element.
35
+ * The checkmark has been moved into a pseudo-element.
33
36
  */
34
37
  checkmarkClassName?: string;
35
38
  /**
36
39
  * Custom CSS Style for the checkmark element.
40
+ *
41
+ * @deprecated As of 1.32.0, this is applied on the actual checkbox `<input>` element.
42
+ * The checkmark has been moved into a pseudo-element.
37
43
  */
38
44
  checkmarkStyle?: React.CSSProperties;
39
45
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'>;
40
46
  /**
41
47
  * Simple input checkbox
42
48
  * @example
49
+ * <Checkbox />
43
50
  * <Checkbox label='Basic Checkbox' />
44
51
  * <Checkbox label='Disabled Checkbox' disabled />
45
52
  * <Checkbox label='Checked' checked />
@@ -78,10 +85,16 @@ export declare const Checkbox: React.ForwardRefExoticComponent<{
78
85
  isLoading?: boolean | undefined;
79
86
  /**
80
87
  * Custom CSS class name for the checkmark element.
88
+ *
89
+ * @deprecated As of 1.32.0, this is applied on the actual checkbox `<input>` element.
90
+ * The checkmark has been moved into a pseudo-element.
81
91
  */
82
92
  checkmarkClassName?: string | undefined;
83
93
  /**
84
94
  * Custom CSS Style for the checkmark element.
95
+ *
96
+ * @deprecated As of 1.32.0, this is applied on the actual checkbox `<input>` element.
97
+ * The checkmark has been moved into a pseudo-element.
85
98
  */
86
99
  checkmarkStyle?: React.CSSProperties | undefined;
87
100
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "type"> & React.RefAttributes<HTMLInputElement>>;
@@ -38,6 +38,7 @@ require("@itwin/itwinui-css/css/inputs.css");
38
38
  /**
39
39
  * Simple input checkbox
40
40
  * @example
41
+ * <Checkbox />
41
42
  * <Checkbox label='Basic Checkbox' />
42
43
  * <Checkbox label='Disabled Checkbox' disabled />
43
44
  * <Checkbox label='Checked' checked />
@@ -47,8 +48,8 @@ require("@itwin/itwinui-css/css/inputs.css");
47
48
  * <Checkbox label='Visibility Checkbox' variant='eyeball' />
48
49
  */
49
50
  exports.Checkbox = react_1.default.forwardRef(function (props, ref) {
50
- var _a;
51
- var className = props.className, _b = props.disabled, disabled = _b === void 0 ? false : _b, _c = props.indeterminate, indeterminate = _c === void 0 ? false : _c, label = props.label, status = props.status, _d = props.variant, variant = _d === void 0 ? 'default' : _d, setFocus = props.setFocus, _e = props.isLoading, isLoading = _e === void 0 ? false : _e, style = props.style, checkmarkClassName = props.checkmarkClassName, checkmarkStyle = props.checkmarkStyle, rest = __rest(props, ["className", "disabled", "indeterminate", "label", "status", "variant", "setFocus", "isLoading", "style", "checkmarkClassName", "checkmarkStyle"]);
51
+ var _a, _b;
52
+ var className = props.className, _c = props.disabled, disabled = _c === void 0 ? false : _c, _d = props.indeterminate, indeterminate = _d === void 0 ? false : _d, label = props.label, status = props.status, _e = props.variant, variant = _e === void 0 ? 'default' : _e, setFocus = props.setFocus, _f = props.isLoading, isLoading = _f === void 0 ? false : _f, style = props.style, checkmarkClassName = props.checkmarkClassName, checkmarkStyle = props.checkmarkStyle, rest = __rest(props, ["className", "disabled", "indeterminate", "label", "status", "variant", "setFocus", "isLoading", "style", "checkmarkClassName", "checkmarkStyle"]);
52
53
  (0, utils_1.useTheme)();
53
54
  var inputElementRef = react_1.default.useRef(null);
54
55
  var refs = (0, utils_1.useMergedRefs)(inputElementRef, ref);
@@ -65,27 +66,19 @@ exports.Checkbox = react_1.default.forwardRef(function (props, ref) {
65
66
  : inputElementRef.current.checked;
66
67
  }
67
68
  });
68
- var defaultCheckbox = (react_1.default.createElement("svg", { viewBox: '0 0 16 16', "aria-hidden": 'true', focusable: 'false' },
69
- react_1.default.createElement("path", { className: 'iui-check', d: 'm6.5 12.5-4.5-4.5 1.5-1.5 3 3 6-6 1.5 1.5z' }),
70
- react_1.default.createElement("path", { className: 'iui-check-partial', d: 'm2.75 6.875h10.5v2.25h-10.5z' })));
71
- var visibilityCheckbox = (react_1.default.createElement("svg", { viewBox: '0 0 16 16', "aria-hidden": 'true', focusable: 'false' },
72
- react_1.default.createElement("path", { className: 'iui-check', d: 'm8 2.99051a8.81883 8.81883 0 0 0 -8 4.95062 8.74664 8.74664 0 0 0 8 5.06836 8.63266 8.63266 0 0 0 8-5.06836 8.83631 8.83631 0 0 0 -8-4.95062zm-1.31445 1.86981a1.47663 1.47663 0 1 1 -1.47663 1.47668 1.47665 1.47665 0 0 1 1.47663-1.47668zm1.31445 6.64917a7.17486 7.17486 0 0 1 -6.30475-3.55237 7.4952 7.4952 0 0 1 2.81475-2.6336 3.83956 3.83956 0 1 0 6.98126.00244 7.522 7.522 0 0 1 2.81774 2.63916 7.09785 7.09785 0 0 1 -6.309 3.54437z' }),
73
- react_1.default.createElement("g", { className: 'iui-check-partial' },
74
- react_1.default.createElement("path", { d: 'm8 3v7.9a4.01179 4.01179 0 0 0 4-4 6.7509 6.7509 0 0 0 -.2-1.4l.1.1a6.89429 6.89429 0 0 1 2.4 2.4 8.39088 8.39088 0 0 1 -2.3 2.3 6.89412 6.89412 0 0 1 -3.9 1.2c-.03345 0-.06653-.00677-.1-.0072v1.5072a8.90686 8.90686 0 0 0 8-5 8.90686 8.90686 0 0 0 -8-5z', opacity: '.33' }),
75
- react_1.default.createElement("path", { d: 'm8 0a1 1 0 0 0 -1 1v2.07135a8.91637 8.91637 0 0 0 -7 4.92865 8.91637 8.91637 0 0 0 7 4.92865v2.07135a1 1 0 0 0 2 0v-14a1 1 0 0 0 -1-1zm-1.5 4.9a1.55426 1.55426 0 0 1 .5.087v2.81451a1.40746 1.40746 0 0 1 -.5.09849 1.538 1.538 0 0 1 -1.5-1.5 1.53794 1.53794 0 0 1 1.5-1.5zm-2.3 5.4a6.97279 6.97279 0 0 1 -2.5-2.3 6.89429 6.89429 0 0 1 2.4-2.4c.1 0 .1-.1.2-.1a3.194 3.194 0 0 0 -.3 1.4 4.0047 4.0047 0 0 0 3 3.857v.65289a6.37491 6.37491 0 0 1 -2.8-1.10989z' })),
76
- react_1.default.createElement("path", { className: 'iui-uncheck', d: 'm1.70671 12.879 11.17218-11.17219 1.4142 1.4142-11.17218 11.17218zm.99329-1.679 1.1-1.1a5.06317 5.06317 0 0 1 -2-2.1 7.48268 7.48268 0 0 1 6.2-3.5 4.86877 4.86877 0 0 1 1.2.1l1.3-1.3a10.07431 10.07431 0 0 0 -2.5-.3 8.84129 8.84129 0 0 0 -8 5 8.42455 8.42455 0 0 0 2.7 3.2zm10.7-6.4-1.1 1.1a7.08625 7.08625 0 0 1 2 2.1 7.50323 7.50323 0 0 1 -6.2 3.5 8.31665 8.31665 0 0 1 -1.3-.2l-1.3 1.3a8.909 8.909 0 0 0 6.4-.5 9.04344 9.04344 0 0 0 4.1-4.1 9.168 9.168 0 0 0 -2.6-3.2z' })));
77
- return (react_1.default.createElement("label", { className: (0, classnames_1.default)('iui-checkbox', (_a = {
69
+ var checkbox = (react_1.default.createElement(react_1.default.Fragment, null,
70
+ react_1.default.createElement("input", __assign({ className: (0, classnames_1.default)('iui-checkbox', {
71
+ 'iui-checkbox-visibility': variant === 'eyeball',
72
+ 'iui-loading': isLoading,
73
+ }, className && (_a = {}, _a[className] = !label, _a), checkmarkClassName), style: __assign(__assign({}, (!label && style)), checkmarkStyle), disabled: disabled || isLoading, type: 'checkbox', ref: refs }, rest)),
74
+ isLoading && react_1.default.createElement(ProgressIndicators_1.ProgressRadial, { size: 'x-small', indeterminate: true })));
75
+ return !label ? (checkbox) : (react_1.default.createElement("label", { className: (0, classnames_1.default)('iui-checkbox-wrapper', (_b = {
78
76
  'iui-disabled': disabled
79
77
  },
80
- _a["iui-" + status] = !!status,
81
- _a['iui-loading'] = isLoading,
82
- _a['iui-checkbox-visibility'] = variant === 'eyeball',
83
- _a), className), style: style },
84
- react_1.default.createElement("input", __assign({ disabled: disabled || isLoading, type: 'checkbox', ref: refs }, rest)),
85
- react_1.default.createElement("span", { className: (0, classnames_1.default)('iui-checkbox-checkmark', checkmarkClassName), style: checkmarkStyle },
86
- isLoading && react_1.default.createElement(ProgressIndicators_1.ProgressRadial, { indeterminate: true }),
87
- !isLoading &&
88
- (variant === 'default' ? defaultCheckbox : visibilityCheckbox)),
89
- label && react_1.default.createElement("span", { className: 'iui-label' }, label)));
78
+ _b["iui-" + status] = !!status,
79
+ _b['iui-loading'] = isLoading,
80
+ _b), className), style: style },
81
+ checkbox,
82
+ label && react_1.default.createElement("span", { className: 'iui-checkbox-label' }, label)));
90
83
  });
91
84
  exports.default = exports.Checkbox;
@@ -17,5 +17,5 @@ export declare type ColorSwatchProps = {
17
17
  * <ColorSwatch color='#23450b' onClick={onClick}/>
18
18
  * <ColorSwatch color={{ r: 255, g: 255, b: 0 }} onClick={onClick}/>
19
19
  */
20
- export declare const ColorSwatch: React.ForwardRefExoticComponent<Pick<ColorSwatchProps, "dir" | "slot" | "style" | "title" | "id" | "role" | "children" | "className" | "accessKey" | "draggable" | "hidden" | "lang" | "translate" | "prefix" | "contentEditable" | "inputMode" | "tabIndex" | "onFocus" | "color" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "contextMenu" | "placeholder" | "spellCheck" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "is" | "isActive"> & React.RefAttributes<HTMLDivElement>>;
20
+ export declare const ColorSwatch: React.ForwardRefExoticComponent<Pick<ColorSwatchProps, "dir" | "slot" | "style" | "title" | "id" | "aria-disabled" | "role" | "children" | "className" | "accessKey" | "draggable" | "hidden" | "lang" | "translate" | "prefix" | "contentEditable" | "inputMode" | "tabIndex" | "onFocus" | "color" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "contextMenu" | "placeholder" | "spellCheck" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "is" | "isActive"> & React.RefAttributes<HTMLDivElement>>;
21
21
  export default ColorSwatch;
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { InputProps } from '../Input';
3
3
  import { SelectOption } from '../Select';
4
4
  import { PopoverProps, CommonProps, InputContainerProps } from '../utils';
@@ -12,6 +12,11 @@ export declare type ComboBoxProps<T> = {
12
12
  * Controlled value of ComboBox.
13
13
  */
14
14
  value?: T;
15
+ /**
16
+ * Message shown below the combobox.
17
+ * Use `StatusMessage` component.
18
+ */
19
+ message?: React.ReactNode;
15
20
  /**
16
21
  * Callback fired when selected value changes.
17
22
  */
@@ -33,6 +38,17 @@ export declare type ComboBoxProps<T> = {
33
38
  * @default 'No options found'
34
39
  */
35
40
  emptyStateMessage?: string;
41
+ /**
42
+ * A custom item renderer can be specified to control the rendering.
43
+ * This function should ideally return a customized version of `MenuItem`,
44
+ * otherwise you will need to make sure to provide styling for the `isFocused` state.
45
+ */
46
+ itemRenderer?: (option: SelectOption<T>, states: {
47
+ isSelected: boolean;
48
+ isFocused: boolean;
49
+ id: string;
50
+ index: number;
51
+ }) => JSX.Element;
36
52
  } & Pick<InputContainerProps, 'status'> & Omit<CommonProps, 'title'>;
37
53
  /**
38
54
  * ComboBox component that allows typing a value to filter the options in dropdown list.
@@ -38,6 +38,7 @@ var Typography_1 = require("../Typography");
38
38
  var utils_1 = require("../utils");
39
39
  var CaretDownSmall_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/icons/CaretDownSmall"));
40
40
  require("tippy.js/animations/shift-away.css");
41
+ var StatusMessage_1 = require("../StatusMessage");
41
42
  /**
42
43
  * ComboBox component that allows typing a value to filter the options in dropdown list.
43
44
  * Values can be selected either using mouse clicks or using the Enter key.
@@ -52,7 +53,7 @@ require("tippy.js/animations/shift-away.css");
52
53
  * />
53
54
  */
54
55
  var ComboBox = function (props) {
55
- var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage"]);
56
+ var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, message = props.message, status = props.status, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "message", "status", "emptyStateMessage", "itemRenderer"]);
56
57
  // Generate a stateful random id if not specified
57
58
  var id = react_1.default.useState(function () {
58
59
  var _a, _b;
@@ -67,16 +68,31 @@ var ComboBox = function (props) {
67
68
  return value === options[index].value;
68
69
  });
69
70
  }, [options, id]);
71
+ var userOnChange = react_1.default.useRef(onChange);
70
72
  var memoizedItems = react_1.default.useMemo(function () {
71
- return options.map(function (_a, index) {
72
- var label = _a.label, value = _a.value, rest = __rest(_a, ["label", "value"]);
73
- return (react_1.default.createElement(Menu_1.MenuItem, __assign({ id: getOptionId(index), key: getOptionId(index), value: value, role: 'option', onClick: function (value) {
73
+ return options.map(function (option, index) {
74
+ var label = option.label, value = option.value, rest = __rest(option, ["label", "value"]);
75
+ var additionalProps = {
76
+ value: value,
77
+ role: 'option',
78
+ onClick: function () {
79
+ var _a;
74
80
  setSelectedValue(value);
75
- onChange === null || onChange === void 0 ? void 0 : onChange(value);
81
+ (_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, value);
76
82
  setIsOpen(false);
77
- } }, rest), label));
83
+ },
84
+ };
85
+ if (itemRenderer) {
86
+ return react_1.default.cloneElement(itemRenderer(option, {
87
+ id: getOptionId(index),
88
+ index: index,
89
+ isSelected: false,
90
+ isFocused: false,
91
+ }), additionalProps);
92
+ }
93
+ return (react_1.default.createElement(Menu_1.MenuItem, __assign({ id: getOptionId(index), key: getOptionId(index) }, additionalProps, rest), label));
78
94
  });
79
- }, [options, getOptionId, onChange]);
95
+ }, [options, getOptionId, itemRenderer]);
80
96
  var inputRef = react_1.default.useRef(null);
81
97
  var menuRef = react_1.default.useRef(null);
82
98
  var toggleButtonRef = react_1.default.useRef(null);
@@ -155,6 +171,7 @@ var ComboBox = function (props) {
155
171
  });
156
172
  }, [inputValue, options, selectedValue, isOpen, filterFunction]);
157
173
  var onKeyDown = react_1.default.useCallback(function (event) {
174
+ var _a;
158
175
  var focusableOptions = (0, utils_1.getFocusableElements)(menuRef.current);
159
176
  var focusedIndexInFilteredList = focusableOptions.findIndex(function (_a) {
160
177
  var _b;
@@ -188,7 +205,7 @@ var ComboBox = function (props) {
188
205
  case 'Enter':
189
206
  if (isOpen) {
190
207
  setSelectedValue(options[focusedIndex].value);
191
- onChange === null || onChange === void 0 ? void 0 : onChange(options[focusedIndex].value);
208
+ (_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, options[focusedIndex].value);
192
209
  }
193
210
  setIsOpen(function (open) { return !open; });
194
211
  event.preventDefault();
@@ -208,26 +225,41 @@ var ComboBox = function (props) {
208
225
  }
209
226
  break;
210
227
  }
211
- }, [focusedIndex, isOpen, options, getOptionId, onChange]);
228
+ }, [focusedIndex, isOpen, options, getOptionId]);
212
229
  var menuItems = react_1.default.useMemo(function () {
213
230
  if (filteredOptions.length === 0) {
214
- return (react_1.default.createElement(Menu_1.MenuExtraContent, null,
215
- react_1.default.createElement(Typography_1.Text, { isMuted: true }, emptyStateMessage)));
231
+ return [
232
+ react_1.default.createElement(Menu_1.MenuExtraContent, { key: 0 },
233
+ react_1.default.createElement(Typography_1.Text, { isMuted: true }, emptyStateMessage)),
234
+ ];
216
235
  }
217
236
  return filteredOptions.map(function (option) {
237
+ var _a;
218
238
  var index = options.findIndex(function (_a) {
219
239
  var value = _a.value;
220
240
  return option.value === value;
221
241
  });
222
242
  if (index < 0) {
223
- return;
243
+ return react_1.default.createElement(react_1.default.Fragment, null);
224
244
  }
225
- if (selectedValue === option.value || focusedIndex === index) {
226
- return react_1.default.cloneElement(memoizedItems[index], {
227
- isSelected: selectedValue === option.value,
228
- className: (0, classnames_1.default)({ 'iui-focused': focusedIndex === index }),
229
- ref: function (el) {
230
- return focusedIndex === index && (el === null || el === void 0 ? void 0 : el.scrollIntoView(false));
245
+ var id = getOptionId(index);
246
+ var isSelected = selectedValue === option.value;
247
+ var isFocused = focusedIndex === index;
248
+ var focusScrollRef = function (el) {
249
+ return isFocused && (el === null || el === void 0 ? void 0 : el.scrollIntoView({ block: 'nearest' }));
250
+ };
251
+ if (isSelected || isFocused) {
252
+ var item = (_a = itemRenderer === null || itemRenderer === void 0 ? void 0 : itemRenderer(option, { index: index, id: id, isSelected: isSelected, isFocused: isFocused })) !== null && _a !== void 0 ? _a : react_1.default.cloneElement(memoizedItems[index], { isSelected: isSelected });
253
+ return react_1.default.cloneElement(item, {
254
+ className: (0, classnames_1.default)({ 'iui-focused': isFocused }, item.props.className),
255
+ ref: (0, utils_1.mergeRefs)(focusScrollRef, item.props.ref),
256
+ value: option.value,
257
+ role: 'option',
258
+ onClick: function () {
259
+ var _a;
260
+ setSelectedValue(option.value);
261
+ (_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, option.value);
262
+ setIsOpen(false);
231
263
  },
232
264
  });
233
265
  }
@@ -237,11 +269,14 @@ var ComboBox = function (props) {
237
269
  filteredOptions,
238
270
  emptyStateMessage,
239
271
  options,
240
- focusedIndex,
272
+ getOptionId,
241
273
  selectedValue,
274
+ focusedIndex,
275
+ itemRenderer,
242
276
  memoizedItems,
243
277
  ]);
244
- return (react_1.default.createElement(utils_1.InputContainer, __assign({ className: className, isIconInline: true }, rest, { id: id }),
278
+ return (react_1.default.createElement(utils_1.InputContainer, __assign({ className: className, status: status, statusMessage: typeof message === 'string' ? (react_1.default.createElement(StatusMessage_1.StatusMessage, { status: status }, message)) : (react_1.default.isValidElement(message) &&
279
+ react_1.default.cloneElement(message, { status: status })) }, rest, { id: id }),
245
280
  react_1.default.createElement("div", { className: 'iui-input-with-icon' },
246
281
  react_1.default.createElement(utils_1.Popover, __assign({ placement: 'bottom-start', visible: isOpen, onClickOutside: function (_, _a) {
247
282
  var _b;
@@ -38,6 +38,12 @@ export declare type ExpandableBlockProps = {
38
38
  * @default 'default'
39
39
  */
40
40
  size?: 'default' | 'small';
41
+ /**
42
+ * Style of the ExpandableBlock.
43
+ * Use 'borderless' to hide outline.
44
+ * @default 'default'
45
+ */
46
+ styleType?: 'default' | 'borderless';
41
47
  } & Omit<CommonProps, 'title'>;
42
48
  /**
43
49
  * Container that allows content to be hidden behind a brief title and a caption.
@@ -46,10 +46,10 @@ require("@itwin/itwinui-css/css/expandable-block.css");
46
46
  */
47
47
  var ExpandableBlock = function (props) {
48
48
  var _a;
49
- var caption = props.caption, children = props.children, className = props.className, title = props.title, onToggle = props.onToggle, style = props.style, _b = props.isExpanded, isExpanded = _b === void 0 ? false : _b, endIcon = props.endIcon, status = props.status, _c = props.size, size = _c === void 0 ? 'default' : _c, rest = __rest(props, ["caption", "children", "className", "title", "onToggle", "style", "isExpanded", "endIcon", "status", "size"]);
49
+ var caption = props.caption, children = props.children, className = props.className, title = props.title, onToggle = props.onToggle, style = props.style, _b = props.isExpanded, isExpanded = _b === void 0 ? false : _b, endIcon = props.endIcon, status = props.status, _c = props.size, size = _c === void 0 ? 'default' : _c, _d = props.styleType, styleType = _d === void 0 ? 'default' : _d, rest = __rest(props, ["caption", "children", "className", "title", "onToggle", "style", "isExpanded", "endIcon", "status", "size", "styleType"]);
50
50
  (0, utils_1.useTheme)();
51
51
  var icon = endIcon !== null && endIcon !== void 0 ? endIcon : (status && utils_1.StatusIconMap[status]());
52
- var _d = react_1.default.useState(isExpanded), expanded = _d[0], setExpanded = _d[1];
52
+ var _e = react_1.default.useState(isExpanded), expanded = _e[0], setExpanded = _e[1];
53
53
  react_1.default.useEffect(function () {
54
54
  setExpanded(isExpanded);
55
55
  }, [isExpanded]);
@@ -68,6 +68,7 @@ var ExpandableBlock = function (props) {
68
68
  'iui-with-caption': !!caption,
69
69
  'iui-expanded': expanded,
70
70
  'iui-small': size === 'small',
71
+ 'iui-borderless': styleType === 'borderless',
71
72
  }, className), style: style }, rest),
72
73
  react_1.default.createElement("div", { "aria-expanded": expanded, className: 'iui-header', tabIndex: 0, onClick: handleToggle, onKeyDown: onKeyDown },
73
74
  react_1.default.createElement(ChevronRight_1.default, { className: 'iui-icon', "aria-hidden": true }),
@@ -11,8 +11,10 @@ export declare type TitleTranslations = {
11
11
  export declare type FooterProps = {
12
12
  /**
13
13
  * Customize footer elements.
14
+ * Providing a `FooterElement[]` will append the custom elements to the end of the default elements.
15
+ * Providing a function that returns a `FooterElement[]` allows further customization - whatever is returned from the function is displayed in the footer with no amendments.
14
16
  */
15
- customElements?: FooterElement[];
17
+ customElements?: FooterElement[] | ((defaultElements: FooterElement[]) => FooterElement[]);
16
18
  /**
17
19
  * Provide localized strings.
18
20
  */
@@ -27,13 +29,23 @@ export declare type FooterElement = {
27
29
  * URL of the footer element.
28
30
  */
29
31
  url?: string;
32
+ /**
33
+ * Key of the footer element.
34
+ */
35
+ key?: keyof TitleTranslations | 'copyright' | (string & Record<never, never>);
30
36
  };
31
37
  /**
32
38
  * Footer element with all needed legal and info links.
33
39
  * Be sure to place it manually at the bottom of your page.
34
40
  * You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
35
- * @example
41
+ * @example <caption>Appending custom element after default elements</caption>
36
42
  * <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
43
+ * @example <caption>Returning only custom elements</caption>
44
+ * <Footer customElements={() => newFooterElements)} />
45
+ * @example <caption>Filtering out a specific element</caption>
46
+ * <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
47
+ * @example <caption>Changing a url</caption>
48
+ * <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
37
49
  */
38
50
  export declare const Footer: (props: FooterProps) => JSX.Element;
39
51
  export default Footer;
@@ -54,40 +54,63 @@ var footerTranslations = {
54
54
  * Footer element with all needed legal and info links.
55
55
  * Be sure to place it manually at the bottom of your page.
56
56
  * You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
57
- * @example
57
+ * @example <caption>Appending custom element after default elements</caption>
58
58
  * <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
59
+ * @example <caption>Returning only custom elements</caption>
60
+ * <Footer customElements={() => newFooterElements)} />
61
+ * @example <caption>Filtering out a specific element</caption>
62
+ * <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
63
+ * @example <caption>Changing a url</caption>
64
+ * <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
59
65
  */
60
66
  var Footer = function (props) {
61
67
  var customElements = props.customElements, translatedTitles = props.translatedTitles, className = props.className, rest = __rest(props, ["customElements", "translatedTitles", "className"]);
62
68
  (0, utils_1.useTheme)();
63
- var today = new Date();
64
69
  var titles = __assign(__assign({}, footerTranslations), translatedTitles);
65
70
  var defaultElements = [
66
71
  {
72
+ key: 'copyright',
73
+ title: "\u00A9 " + new Date().getFullYear() + " Bentley Systems, Incorporated",
74
+ },
75
+ {
76
+ key: 'termsOfService',
67
77
  title: titles.termsOfService,
68
78
  url: 'https://connect-agreementportal.bentley.com/AgreementApp/Home/Eula/view/readonly/BentleyConnect',
69
79
  },
70
- { title: titles.privacy, url: 'https://www.bentley.com/en/privacy-policy' },
71
80
  {
81
+ key: 'privacy',
82
+ title: titles.privacy,
83
+ url: 'https://www.bentley.com/en/privacy-policy',
84
+ },
85
+ {
86
+ key: 'termsOfUse',
72
87
  title: titles.termsOfUse,
73
88
  url: 'https://www.bentley.com/en/terms-of-use-and-select-online-agreement',
74
89
  },
75
- { title: titles.cookies, url: 'https://www.bentley.com/en/cookie-policy' },
76
- { title: titles.legalNotices, url: 'https://connect.bentley.com/Legal' },
90
+ {
91
+ key: 'cookies',
92
+ title: titles.cookies,
93
+ url: 'https://www.bentley.com/en/cookie-policy',
94
+ },
95
+ {
96
+ key: 'legalNotices',
97
+ title: titles.legalNotices,
98
+ url: 'https://connect.bentley.com/Legal',
99
+ },
77
100
  ];
78
- var elements = customElements
79
- ? __spreadArray(__spreadArray([], defaultElements, true), customElements, true) : defaultElements;
101
+ var elements = defaultElements;
102
+ if (customElements) {
103
+ elements =
104
+ typeof customElements === 'function'
105
+ ? customElements(defaultElements)
106
+ : __spreadArray(__spreadArray([], defaultElements, true), customElements, true);
107
+ }
80
108
  return (react_1.default.createElement("footer", __assign({ className: (0, classnames_1.default)('iui-legal-footer', className) }, rest),
81
- react_1.default.createElement("ul", null,
82
- react_1.default.createElement("li", null,
83
- "\u00A9 ",
84
- today.getFullYear(),
85
- " Bentley Systems, Incorporated"),
86
- elements.map(function (element, index) {
87
- return (react_1.default.createElement("li", { key: element.title + "-" + index },
88
- react_1.default.createElement("span", { className: 'iui-separator' }),
89
- element.url ? (react_1.default.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
90
- }))));
109
+ react_1.default.createElement("ul", null, elements.map(function (element, index) {
110
+ return (react_1.default.createElement("li", { key: element.key || element.title + "-" + index },
111
+ index > 0 && react_1.default.createElement("span", { className: 'iui-separator' }),
112
+ element.url ? (react_1.default.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
113
+ }))));
91
114
  };
92
115
  exports.Footer = Footer;
93
116
  exports.default = exports.Footer;
@@ -51,8 +51,18 @@ require("@itwin/itwinui-css/css/inputs.css");
51
51
  var InputGroup = function (props) {
52
52
  var children = props.children, _a = props.disabled, disabled = _a === void 0 ? false : _a, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, className = props.className, style = props.style, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["children", "disabled", "displayStyle", "label", "message", "status", "svgIcon", "className", "style", "required"]);
53
53
  (0, utils_1.useTheme)();
54
- var icon = svgIcon !== null && svgIcon !== void 0 ? svgIcon : (status && utils_1.StatusIconMap[status]());
55
- return (react_1.default.createElement(utils_1.InputContainer, __assign({ label: label, disabled: disabled, required: required, status: status, message: message, icon: icon ? react_1.default.cloneElement(icon, { 'aria-hidden': true }) : undefined, isLabelInline: displayStyle === 'inline', className: className, style: style }, rest),
54
+ var icon = function () {
55
+ if (svgIcon) {
56
+ return react_1.default.cloneElement(svgIcon, { 'aria-hidden': true });
57
+ }
58
+ if (status && message) {
59
+ return react_1.default.cloneElement(utils_1.StatusIconMap[status](), {
60
+ 'aria-hidden': true,
61
+ });
62
+ }
63
+ return undefined;
64
+ };
65
+ return (react_1.default.createElement(utils_1.InputContainer, __assign({ label: label, disabled: disabled, required: required, status: status, message: message, icon: icon(), isLabelInline: displayStyle === 'inline', className: className, style: style }, rest),
56
66
  react_1.default.createElement("div", { className: 'iui-input-group' }, children)));
57
67
  };
58
68
  exports.InputGroup = InputGroup;
@@ -70,10 +70,16 @@ require("@itwin/itwinui-css/css/inputs.css");
70
70
  var LabeledSelect = function (props) {
71
71
  var className = props.className, _a = props.disabled, disabled = _a === void 0 ? false : _a, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, style = props.style, selectClassName = props.selectClassName, selectStyle = props.selectStyle, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["className", "disabled", "label", "message", "status", "svgIcon", "displayStyle", "style", "selectClassName", "selectStyle", "required"]);
72
72
  (0, utils_1.useTheme)();
73
- var icon = svgIcon !== null && svgIcon !== void 0 ? svgIcon : (status && utils_1.StatusIconMap[status]());
74
- return (react_1.default.createElement(utils_1.InputContainer, { label: label, disabled: disabled, required: required, status: status, message: message, icon: displayStyle === 'default' && icon
75
- ? react_1.default.cloneElement(icon, { 'aria-hidden': true })
76
- : undefined, isLabelInline: displayStyle === 'inline', className: className, style: style },
73
+ var icon = function () {
74
+ if (svgIcon) {
75
+ return react_1.default.cloneElement(svgIcon, { 'aria-hidden': true });
76
+ }
77
+ if (status && message) {
78
+ return utils_1.StatusIconMap[status]();
79
+ }
80
+ return undefined;
81
+ };
82
+ return (react_1.default.createElement(utils_1.InputContainer, { label: label, disabled: disabled, required: required, status: status, message: message, icon: displayStyle === 'default' ? icon() : undefined, isLabelInline: displayStyle === 'inline', className: className, style: style },
77
83
  react_1.default.createElement(Select_1.Select, __assign({ disabled: disabled, className: selectClassName, style: selectStyle }, rest))));
78
84
  };
79
85
  exports.LabeledSelect = LabeledSelect;