@itwin/itwinui-react 1.32.0 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/cjs/core/ButtonGroup/ButtonGroup.d.ts +6 -1
  3. package/cjs/core/ButtonGroup/ButtonGroup.js +6 -3
  4. package/cjs/core/ComboBox/ComboBox.d.ts +6 -1
  5. package/cjs/core/ComboBox/ComboBox.js +4 -2
  6. package/cjs/core/Footer/Footer.d.ts +14 -2
  7. package/cjs/core/Footer/Footer.js +40 -17
  8. package/cjs/core/InputGroup/InputGroup.js +12 -2
  9. package/cjs/core/LabeledSelect/LabeledSelect.js +10 -4
  10. package/cjs/core/Slider/Slider.js +10 -1
  11. package/cjs/core/StatusMessage/StatusMessage.d.ts +24 -0
  12. package/cjs/core/StatusMessage/StatusMessage.js +39 -0
  13. package/cjs/core/StatusMessage/index.d.ts +4 -0
  14. package/cjs/core/StatusMessage/index.js +10 -0
  15. package/cjs/core/Table/Table.d.ts +5 -0
  16. package/cjs/core/Table/Table.js +8 -8
  17. package/cjs/core/Table/TableRowMemoized.js +1 -0
  18. package/cjs/core/Table/actionHandlers/resizeHandler.d.ts +2 -0
  19. package/cjs/core/Table/actionHandlers/selectHandler.d.ts +1 -0
  20. package/cjs/core/Table/filters/BaseFilter.js +1 -1
  21. package/cjs/core/Table/filters/FilterToggle.js +4 -4
  22. package/cjs/core/Table/hooks/index.d.ts +1 -0
  23. package/cjs/core/Table/hooks/index.js +3 -1
  24. package/cjs/core/Table/hooks/useColumnDragAndDrop.d.ts +2 -0
  25. package/cjs/core/Table/hooks/useColumnDragAndDrop.js +120 -0
  26. package/cjs/core/Table/hooks/useExpanderCell.js +1 -0
  27. package/cjs/core/Table/hooks/useResizeColumns.js +8 -4
  28. package/cjs/core/Table/hooks/useSelectionCell.js +2 -2
  29. package/cjs/core/ToggleSwitch/ToggleSwitch.js +13 -10
  30. package/cjs/core/UserIcon/UserIcon.js +1 -10
  31. package/cjs/core/index.d.ts +2 -0
  32. package/cjs/core/index.js +3 -1
  33. package/cjs/core/utils/components/InputContainer.d.ts +1 -0
  34. package/cjs/core/utils/components/InputContainer.js +8 -7
  35. package/cjs/core/utils/hooks/useIntersection.d.ts +4 -3
  36. package/cjs/core/utils/hooks/useIntersection.js +10 -5
  37. package/cjs/core/utils/hooks/useOverflow.d.ts +3 -2
  38. package/cjs/core/utils/hooks/useOverflow.js +24 -21
  39. package/cjs/types/react-table-config.d.ts +7 -0
  40. package/esm/core/ButtonGroup/ButtonGroup.d.ts +6 -1
  41. package/esm/core/ButtonGroup/ButtonGroup.js +6 -3
  42. package/esm/core/ComboBox/ComboBox.d.ts +6 -1
  43. package/esm/core/ComboBox/ComboBox.js +4 -2
  44. package/esm/core/Footer/Footer.d.ts +14 -2
  45. package/esm/core/Footer/Footer.js +40 -17
  46. package/esm/core/InputGroup/InputGroup.js +12 -2
  47. package/esm/core/LabeledSelect/LabeledSelect.js +10 -4
  48. package/esm/core/Slider/Slider.js +10 -1
  49. package/esm/core/StatusMessage/StatusMessage.d.ts +24 -0
  50. package/esm/core/StatusMessage/StatusMessage.js +32 -0
  51. package/esm/core/StatusMessage/index.d.ts +4 -0
  52. package/esm/core/StatusMessage/index.js +6 -0
  53. package/esm/core/Table/Table.d.ts +5 -0
  54. package/esm/core/Table/Table.js +10 -10
  55. package/esm/core/Table/TableRowMemoized.js +1 -0
  56. package/esm/core/Table/actionHandlers/resizeHandler.d.ts +2 -0
  57. package/esm/core/Table/actionHandlers/selectHandler.d.ts +1 -0
  58. package/esm/core/Table/filters/BaseFilter.js +1 -1
  59. package/esm/core/Table/filters/FilterToggle.js +4 -4
  60. package/esm/core/Table/hooks/index.d.ts +1 -0
  61. package/esm/core/Table/hooks/index.js +1 -0
  62. package/esm/core/Table/hooks/useColumnDragAndDrop.d.ts +2 -0
  63. package/esm/core/Table/hooks/useColumnDragAndDrop.js +116 -0
  64. package/esm/core/Table/hooks/useExpanderCell.js +1 -0
  65. package/esm/core/Table/hooks/useResizeColumns.js +8 -4
  66. package/esm/core/Table/hooks/useSelectionCell.js +2 -2
  67. package/esm/core/ToggleSwitch/ToggleSwitch.js +13 -10
  68. package/esm/core/UserIcon/UserIcon.js +1 -10
  69. package/esm/core/index.d.ts +2 -0
  70. package/esm/core/index.js +1 -0
  71. package/esm/core/utils/components/InputContainer.d.ts +1 -0
  72. package/esm/core/utils/components/InputContainer.js +8 -7
  73. package/esm/core/utils/hooks/useIntersection.d.ts +4 -3
  74. package/esm/core/utils/hooks/useIntersection.js +10 -5
  75. package/esm/core/utils/hooks/useOverflow.d.ts +3 -2
  76. package/esm/core/utils/hooks/useOverflow.js +24 -21
  77. package/esm/types/react-table-config.d.ts +7 -0
  78. package/package.json +15 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.34.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.33.1...v1.34.0) (2022-03-22)
4
+
5
+ ### What's new
6
+
7
+ * **Table:** support for draggable columns ([#561](https://www.github.com/iTwin/iTwinUI-react/issues/561)) ([0e741f5](https://www.github.com/iTwin/iTwinUI-react/commit/0e741f5c0838996a5f45c57abedf41daeef652d4))
8
+
9
+ ### Fixes
10
+
11
+ * **ToggleSwitch:** updated toggle switch styles through css package ([#592](https://www.github.com/iTwin/iTwinUI-react/issues/592)) ([3a0be35](https://www.github.com/iTwin/iTwinUI-react/commit/3a0be355d4363fe7d704c3fd6f975c509c65da2b))
12
+ * **UserIcon:** busy status now also shows an icon
13
+
14
+ ### [1.33.1](https://www.github.com/iTwin/iTwinUI-react/compare/v1.33.0...v1.33.1) (2022-03-18)
15
+
16
+ ### Fixes
17
+
18
+ * **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))
19
+ * **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))
20
+ * **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))
21
+
22
+ ## [1.33.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.32.0...v1.33.0) (2022-03-07)
23
+
24
+ ### What's new
25
+
26
+ * **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))
27
+ * **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))
28
+ * This new prop can accept a string or the new `StatusMessage` component for customizing icon.
29
+ * **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))
30
+
3
31
  ## [1.32.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.31.0...v1.32.0) (2022-02-25)
4
32
 
5
33
  ### 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)));
@@ -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
  */
@@ -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, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer"]);
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;
@@ -274,7 +275,8 @@ var ComboBox = function (props) {
274
275
  itemRenderer,
275
276
  memoizedItems,
276
277
  ]);
277
- 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 }),
278
280
  react_1.default.createElement("div", { className: 'iui-input-with-icon' },
279
281
  react_1.default.createElement(utils_1.Popover, __assign({ placement: 'bottom-start', visible: isOpen, onClickOutside: function (_, _a) {
280
282
  var _b;
@@ -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;
@@ -208,11 +208,20 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
208
208
  newValues[closestValueIndex] = pointerValue;
209
209
  setCurrentValues(newValues);
210
210
  onChange === null || onChange === void 0 ? void 0 : onChange(newValues);
211
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(newValues);
211
212
  focusThumb(containerRef.current, closestValueIndex);
212
213
  event.preventDefault();
213
214
  event.stopPropagation();
214
215
  }
215
- }, [min, max, step, currentValues, getAllowableThumbRange, onChange]);
216
+ }, [
217
+ min,
218
+ max,
219
+ step,
220
+ currentValues,
221
+ getAllowableThumbRange,
222
+ onChange,
223
+ onUpdate,
224
+ ]);
216
225
  (0, utils_1.useEventListener)('pointermove', handlePointerMove, (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument);
217
226
  (0, utils_1.useEventListener)('pointerup', handlePointerUp, (_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
218
227
  var tickMarkArea = react_1.default.useMemo(function () {
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ export declare type StatusMessageProps = {
3
+ /**
4
+ * Custom icon to be displayed at the beginning.
5
+ * It will default to the `status` icon, if it's set.
6
+ */
7
+ startIcon?: JSX.Element;
8
+ /**
9
+ * Message content.
10
+ */
11
+ children: React.ReactNode;
12
+ /**
13
+ * Status of the message.
14
+ */
15
+ status?: 'positive' | 'warning' | 'negative';
16
+ };
17
+ /**
18
+ * Component to display icon and text below the `Combobox` component.
19
+ * @example
20
+ * <StatusMessage>This is the text</StatusMessage>
21
+ * <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
22
+ */
23
+ export declare const StatusMessage: ({ startIcon: userStartIcon, children, status, }: StatusMessageProps) => JSX.Element;
24
+ export default StatusMessage;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StatusMessage = void 0;
7
+ /*---------------------------------------------------------------------------------------------
8
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
9
+ * See LICENSE.md in the project root for license terms and full copyright notice.
10
+ *--------------------------------------------------------------------------------------------*/
11
+ var react_1 = __importDefault(require("react"));
12
+ var utils_1 = require("../utils");
13
+ var classnames_1 = __importDefault(require("classnames"));
14
+ /**
15
+ * Component to display icon and text below the `Combobox` component.
16
+ * @example
17
+ * <StatusMessage>This is the text</StatusMessage>
18
+ * <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
19
+ */
20
+ var StatusMessage = function (_a) {
21
+ var userStartIcon = _a.startIcon, children = _a.children, status = _a.status;
22
+ (0, utils_1.useTheme)();
23
+ var StartIcon = function () {
24
+ var _a;
25
+ var icon = userStartIcon !== null && userStartIcon !== void 0 ? userStartIcon : (status && utils_1.StatusIconMap[status]());
26
+ if (!icon) {
27
+ return null;
28
+ }
29
+ return react_1.default.cloneElement(icon, {
30
+ className: (0, classnames_1.default)('iui-input-icon', (_a = icon.props) === null || _a === void 0 ? void 0 : _a.className),
31
+ 'aria-hidden': true,
32
+ });
33
+ };
34
+ return (react_1.default.createElement(react_1.default.Fragment, null,
35
+ react_1.default.createElement(StartIcon, null),
36
+ react_1.default.createElement("div", { className: 'iui-message' }, children)));
37
+ };
38
+ exports.StatusMessage = StatusMessage;
39
+ exports.default = exports.StatusMessage;
@@ -0,0 +1,4 @@
1
+ export { StatusMessage } from './StatusMessage';
2
+ export type { StatusMessageProps } from './StatusMessage';
3
+ declare const _default: "./StatusMessage";
4
+ export default _default;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatusMessage = void 0;
4
+ /*---------------------------------------------------------------------------------------------
5
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
+ * See LICENSE.md in the project root for license terms and full copyright notice.
7
+ *--------------------------------------------------------------------------------------------*/
8
+ var StatusMessage_1 = require("./StatusMessage");
9
+ Object.defineProperty(exports, "StatusMessage", { enumerable: true, get: function () { return StatusMessage_1.StatusMessage; } });
10
+ exports.default = './StatusMessage';
@@ -170,6 +170,11 @@ export declare type TableProps<T extends Record<string, unknown> = Record<string
170
170
  * @beta
171
171
  */
172
172
  enableVirtualization?: boolean;
173
+ /**
174
+ * Flag whether columns can be reordered.
175
+ * @default false
176
+ */
177
+ enableColumnReordering?: boolean;
173
178
  } & Omit<CommonProps, 'title'>;
174
179
  /**
175
180
  * Table based on [react-table](https://react-table.tanstack.com/docs/api/overview).
@@ -94,9 +94,9 @@ var tableResizeEndAction = 'tableResizeEnd';
94
94
  */
95
95
  var Table = function (props) {
96
96
  var _a;
97
- var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.isSortable, isSortable = _d === void 0 ? false : _d, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _e = props.intersectionMargin, intersectionMargin = _e === void 0 ? 300 : _e, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _f = props.density, density = _f === void 0 ? 'default' : _f, _g = props.selectSubRows, selectSubRows = _g === void 0 ? true : _g, getSubRows = props.getSubRows, _h = props.selectRowOnClick, selectRowOnClick = _h === void 0 ? true : _h, paginatorRenderer = props.paginatorRenderer, _j = props.pageSize, pageSize = _j === void 0 ? 25 : _j, _k = props.isResizable, isResizable = _k === void 0 ? false : _k, _l = props.styleType, styleType = _l === void 0 ? 'default' : _l, _m = props.enableVirtualization, enableVirtualization = _m === void 0 ? false : _m, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization"]);
97
+ var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.isSortable, isSortable = _d === void 0 ? false : _d, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _e = props.intersectionMargin, intersectionMargin = _e === void 0 ? 300 : _e, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _f = props.density, density = _f === void 0 ? 'default' : _f, _g = props.selectSubRows, selectSubRows = _g === void 0 ? true : _g, getSubRows = props.getSubRows, _h = props.selectRowOnClick, selectRowOnClick = _h === void 0 ? true : _h, paginatorRenderer = props.paginatorRenderer, _j = props.pageSize, pageSize = _j === void 0 ? 25 : _j, _k = props.isResizable, isResizable = _k === void 0 ? false : _k, _l = props.styleType, styleType = _l === void 0 ? 'default' : _l, _m = props.enableVirtualization, enableVirtualization = _m === void 0 ? false : _m, _o = props.enableColumnReordering, enableColumnReordering = _o === void 0 ? false : _o, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
98
98
  (0, utils_1.useTheme)();
99
- var _o = react_1.default.useState(), ownerDocument = _o[0], setOwnerDocument = _o[1];
99
+ var _p = react_1.default.useState(), ownerDocument = _p[0], setOwnerDocument = _p[1];
100
100
  var defaultColumn = react_1.default.useMemo(function () { return ({
101
101
  maxWidth: 0,
102
102
  minWidth: 0,
@@ -152,7 +152,7 @@ var Table = function (props) {
152
152
  return getSubRows ? getSubRows(item, index) : item.subRows;
153
153
  });
154
154
  }, [data, getSubRows]);
155
- var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState) }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, isRowDisabled));
155
+ var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState) }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, isRowDisabled), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering));
156
156
  var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, filteredFlatRows = instance.filteredFlatRows, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders;
157
157
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
158
158
  var key = _a[0], value = _a[1];
@@ -266,21 +266,21 @@ var Table = function (props) {
266
266
  className: 'iui-row',
267
267
  });
268
268
  return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
269
- var _a = column.getSortByToggleProps(), onSortClick = _a.onClick, sortByProps = __rest(_a, ["onClick"]);
270
- var columnProps = column.getHeaderProps(__assign(__assign({}, sortByProps), { className: (0, classnames_1.default)('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: __assign({}, (0, utils_2.getCellStyle)(column, !!state.isTableResizing)) }));
271
- return (react_1.default.createElement("div", __assign({}, columnProps, { key: columnProps.key, title: undefined, ref: function (el) {
269
+ var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: __assign({}, (0, utils_2.getCellStyle)(column, !!state.isTableResizing)) }));
270
+ return (react_1.default.createElement("div", __assign({}, columnProps, column.getDragAndDropProps(), { key: columnProps.key, title: undefined, ref: function (el) {
272
271
  if (el && isResizable) {
273
272
  columnRefs.current[column.id] = el;
274
273
  column.resizeWidth = el.getBoundingClientRect().width;
275
274
  }
276
- }, onMouseDown: onSortClick }),
275
+ } }),
277
276
  column.render('Header'),
278
277
  !isLoading && (data.length != 0 || areFiltersSet) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
279
278
  !isLoading && data.length != 0 && column.canSort && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
280
279
  isResizable &&
281
280
  column.isResizerVisible &&
282
281
  index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
283
- react_1.default.createElement("div", { className: 'iui-resizer-bar' })))));
282
+ react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
283
+ enableColumnReordering && !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' }))));
284
284
  })));
285
285
  })),
286
286
  react_1.default.createElement("div", __assign({}, getTableBodyProps({
@@ -92,6 +92,7 @@ exports.TableRowMemoized = react_1.default.memo(exports.TableRow, function (prev
92
92
  prevProp.rowProps === nextProp.rowProps &&
93
93
  prevProp.expanderCell === nextProp.expanderCell &&
94
94
  prevProp.tableHasSubRows === nextProp.tableHasSubRows &&
95
+ prevProp.state.columnOrder === nextProp.state.columnOrder &&
95
96
  !nextProp.state.columnResizing.isResizingColumn &&
96
97
  !nextProp.state.isTableResizing;
97
98
  });
@@ -11,6 +11,7 @@ export declare const onTableResizeStart: <T extends Record<string, unknown>>(sta
11
11
  columnWidths: Record<string, number>;
12
12
  isResizingColumn?: string | undefined;
13
13
  };
14
+ columnReorderStartIndex: number;
14
15
  columnOrder: import("react-table").IdType<T>[];
15
16
  expanded: Record<import("react-table").IdType<T>, boolean>;
16
17
  filters: import("react-table").Filters<T>;
@@ -36,6 +37,7 @@ export declare const onTableResizeEnd: <T extends Record<string, unknown>>(state
36
37
  isResizingColumn?: string | undefined;
37
38
  };
38
39
  hiddenColumns?: import("react-table").IdType<T>[] | undefined;
40
+ columnReorderStartIndex: number;
39
41
  columnOrder: import("react-table").IdType<T>[];
40
42
  expanded: Record<import("react-table").IdType<T>, boolean>;
41
43
  filters: import("react-table").Filters<T>;
@@ -19,6 +19,7 @@ export declare const onSingleSelectHandler: <T extends Record<string, unknown>>(
19
19
  isResizingColumn?: string | undefined;
20
20
  };
21
21
  isTableResizing?: boolean | undefined;
22
+ columnReorderStartIndex: number;
22
23
  columnOrder: import("react-table").IdType<T>[];
23
24
  expanded: Record<import("react-table").IdType<T>, boolean>;
24
25
  filters: import("react-table").Filters<T>;
@@ -31,7 +31,7 @@ var BaseFilter = function (props) {
31
31
  (0, utils_1.useTheme)();
32
32
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)('iui-column-filter', className), style: style,
33
33
  // Prevents from triggering sort
34
- onMouseDown: function (e) {
34
+ onClick: function (e) {
35
35
  e.stopPropagation();
36
36
  }, id: id }, children));
37
37
  };
@@ -54,10 +54,10 @@ var FilterToggle = function (props) {
54
54
  close();
55
55
  }, [close, column]);
56
56
  return (react_1.default.createElement(react_1.default.Fragment, null, column.canFilter && column.Filter && (react_1.default.createElement(utils_1.Popover, { content: column.render('Filter', { close: close, setFilter: setFilter, clearFilter: clearFilter }), placement: 'bottom-start', visible: isVisible, onClickOutside: close, appendTo: ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.body },
57
- react_1.default.createElement(Buttons_1.IconButton, __assign({ styleType: 'borderless', isActive: isVisible || column.filterValue, className: (0, classnames_1.default)('iui-filter-button', className), onClick: function () {
57
+ react_1.default.createElement(Buttons_1.IconButton, __assign({ styleType: 'borderless', isActive: isVisible || column.filterValue, className: (0, classnames_1.default)('iui-filter-button', className), onClick: function (e) {
58
58
  setIsVisible(function (v) { return !v; });
59
- },
60
- // Prevents from triggering sort
61
- onMouseDown: function (e) { return e.stopPropagation(); } }, rest), column.filterValue ? react_1.default.createElement(Filter_1.default, null) : react_1.default.createElement(FilterHollow_1.default, null))))));
59
+ // Prevents from triggering sort
60
+ e.stopPropagation();
61
+ } }, rest), column.filterValue ? react_1.default.createElement(Filter_1.default, null) : react_1.default.createElement(FilterHollow_1.default, null))))));
62
62
  };
63
63
  exports.FilterToggle = FilterToggle;
@@ -3,3 +3,4 @@ export { SELECTION_CELL_ID, useSelectionCell } from './useSelectionCell';
3
3
  export { useSubRowFiltering } from './useSubRowFiltering';
4
4
  export { useSubRowSelection } from './useSubRowSelection';
5
5
  export { useResizeColumns } from './useResizeColumns';
6
+ export { useColumnDragAndDrop } from './useColumnDragAndDrop';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.SELECTION_CELL_ID = exports.useExpanderCell = exports.EXPANDER_CELL_ID = void 0;
3
+ exports.useColumnDragAndDrop = exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.SELECTION_CELL_ID = exports.useExpanderCell = exports.EXPANDER_CELL_ID = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -17,3 +17,5 @@ var useSubRowSelection_1 = require("./useSubRowSelection");
17
17
  Object.defineProperty(exports, "useSubRowSelection", { enumerable: true, get: function () { return useSubRowSelection_1.useSubRowSelection; } });
18
18
  var useResizeColumns_1 = require("./useResizeColumns");
19
19
  Object.defineProperty(exports, "useResizeColumns", { enumerable: true, get: function () { return useResizeColumns_1.useResizeColumns; } });
20
+ var useColumnDragAndDrop_1 = require("./useColumnDragAndDrop");
21
+ Object.defineProperty(exports, "useColumnDragAndDrop", { enumerable: true, get: function () { return useColumnDragAndDrop_1.useColumnDragAndDrop; } });
@@ -0,0 +1,2 @@
1
+ import { Hooks } from 'react-table';
2
+ export declare const useColumnDragAndDrop: <T extends Record<string, unknown>>(isEnabled: boolean) => (hooks: Hooks<T>) => void;