@itwin/itwinui-react 1.43.0 → 1.45.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 (39) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +2 -2
  3. package/cjs/core/Dialog/DialogTitleBar.js +2 -2
  4. package/cjs/core/Dialog/DialogTitleBarTitle.js +2 -2
  5. package/cjs/core/Menu/Menu.js +0 -3
  6. package/cjs/core/Select/Select.d.ts +23 -8
  7. package/cjs/core/Select/Select.js +82 -25
  8. package/cjs/core/Select/SelectTag.d.ts +15 -0
  9. package/cjs/core/Select/SelectTag.js +48 -0
  10. package/cjs/core/Select/index.d.ts +1 -1
  11. package/cjs/core/Table/Table.d.ts +3 -1
  12. package/cjs/core/Table/Table.js +2 -1
  13. package/cjs/core/Table/TableRowMemoized.d.ts +10 -2
  14. package/cjs/core/Table/TableRowMemoized.js +23 -7
  15. package/cjs/core/Table/cells/DefaultCell.d.ts +14 -1
  16. package/cjs/core/Table/cells/DefaultCell.js +10 -4
  17. package/cjs/core/index.d.ts +1 -1
  18. package/cjs/core/utils/components/MiddleTextTruncation.d.ts +15 -1
  19. package/cjs/core/utils/components/MiddleTextTruncation.js +14 -3
  20. package/cjs/core/utils/hooks/useOverflow.js +4 -1
  21. package/esm/core/Dialog/DialogTitleBar.js +1 -1
  22. package/esm/core/Dialog/DialogTitleBarTitle.js +1 -1
  23. package/esm/core/Menu/Menu.js +0 -3
  24. package/esm/core/Select/Select.d.ts +23 -8
  25. package/esm/core/Select/Select.js +83 -26
  26. package/esm/core/Select/SelectTag.d.ts +15 -0
  27. package/esm/core/Select/SelectTag.js +41 -0
  28. package/esm/core/Select/index.d.ts +1 -1
  29. package/esm/core/Table/Table.d.ts +3 -1
  30. package/esm/core/Table/Table.js +2 -1
  31. package/esm/core/Table/TableRowMemoized.d.ts +10 -2
  32. package/esm/core/Table/TableRowMemoized.js +23 -7
  33. package/esm/core/Table/cells/DefaultCell.d.ts +14 -1
  34. package/esm/core/Table/cells/DefaultCell.js +10 -4
  35. package/esm/core/index.d.ts +1 -1
  36. package/esm/core/utils/components/MiddleTextTruncation.d.ts +15 -1
  37. package/esm/core/utils/components/MiddleTextTruncation.js +14 -3
  38. package/esm/core/utils/hooks/useOverflow.js +4 -1
  39. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.45.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.44.0...v1.45.0) (2022-08-25)
4
+
5
+ ### What's new
6
+
7
+ * **MiddleTextTruncation:** Add text renderer for customizing rendered content ([#787](https://www.github.com/iTwin/iTwinUI-react/issues/787)) ([293ebea](https://www.github.com/iTwin/iTwinUI-react/commit/293ebeac844eb540c1d5c7f999e176f3be377d8e))
8
+ * **Table:** Add `Cell` and `Row` status. Icons support in `DefaultCell` ([#788](https://www.github.com/iTwin/iTwinUI-react/issues/788)) ([9b0282e](https://www.github.com/iTwin/iTwinUI-react/commit/9b0282e610434301ff69e296086304afc5648034))
9
+
10
+ ## [1.44.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.43.1...v1.44.0) (2022-08-23)
11
+
12
+ ### What's new
13
+
14
+ * **Select:** Multiple selection support ([#700](https://www.github.com/iTwin/iTwinUI-react/issues/700)) ([b7d34c1](https://www.github.com/iTwin/iTwinUI-react/commit/b7d34c1702ae416d969bed21098270f7aa7731a9))
15
+
16
+ ### Fixes
17
+
18
+ * **Table:** Show correct icon on hover for columns with `sortDescFirst` ([#779](https://www.github.com/iTwin/iTwinUI-react/issues/779)) ([acf19a2](https://www.github.com/iTwin/iTwinUI-react/commit/acf19a23d4680e6e1c1789e45b8e76e0848d8166))
19
+
20
+ ### [1.43.1](https://www.github.com/iTwin/iTwinUI-react/compare/v1.43.0...v1.43.1) (2022-08-18)
21
+
22
+ ### Fixes
23
+
24
+ * **Dialog:** Fixed import path for `useTheme` ([#780](https://www.github.com/iTwin/iTwinUI-react/issues/780)) ([dc5f65a](https://www.github.com/iTwin/iTwinUI-react/commit/dc5f65af8a4a7e8d50f05952084a2ffe98bc0800))
25
+
3
26
  ## [1.43.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.42.0...v1.43.0) (2022-08-17)
4
27
 
5
28
  ### What's new
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  ## What is iTwinUI-react?
15
15
 
16
16
  iTwinUI-react is a library built on top of the [iTwinUI](https://github.com/iTwin/iTwinUI) library.
17
- The goal of this project is to provide React components for using the styles and components from the core `iTwinUI` project. Check out the [demo website](https://itwin.github.io/iTwinUI-react/?path=/story/overview--overview) to see the components in action.
17
+ The goal of this project is to provide React components for using the styles and components from the core `iTwinUI` project. Check out the [demo website](https://itwin.github.io/iTwinUI-react) to see the components in action.
18
18
 
19
19
  ---
20
20
 
@@ -102,4 +102,4 @@ Please read our [CONTRIBUTING.md](https://github.com/iTwin/iTwinUI-react/blob/ma
102
102
 
103
103
  ## Changelog
104
104
 
105
- Read our [CHANGELOG.md](https://github.com/iTwin/iTwinUI-react/blob/main/CHANGELOG.md) to find recent changes.
105
+ Read our [CHANGELOG.md](https://github.com/iTwin/iTwinUI-react/blob/main/packages/iTwinUI-react/CHANGELOG.md) to find recent changes.
@@ -33,7 +33,7 @@ exports.DialogTitleBar = void 0;
33
33
  var react_1 = __importDefault(require("react"));
34
34
  var classnames_1 = __importDefault(require("classnames"));
35
35
  var Close_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/icons/Close"));
36
- var theming_1 = require("@storybook/theming");
36
+ var utils_1 = require("../utils");
37
37
  var Buttons_1 = require("../Buttons");
38
38
  require("@itwin/itwinui-css/css/dialog.css");
39
39
  var DialogContext_1 = require("./DialogContext");
@@ -58,7 +58,7 @@ var DialogTitleBarTitle_1 = require("./DialogTitleBarTitle");
58
58
  exports.DialogTitleBar = Object.assign(react_1.default.forwardRef(function (props, ref) {
59
59
  var dialogContext = (0, DialogContext_1.useDialogContext)();
60
60
  var children = props.children, titleText = props.titleText, _a = props.isDismissible, isDismissible = _a === void 0 ? dialogContext.isDismissible : _a, _b = props.onClose, onClose = _b === void 0 ? dialogContext.onClose : _b, className = props.className, rest = __rest(props, ["children", "titleText", "isDismissible", "onClose", "className"]);
61
- (0, theming_1.useTheme)();
61
+ (0, utils_1.useTheme)();
62
62
  return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog-title-bar', className), ref: ref }, rest), children ? (children) : (react_1.default.createElement(react_1.default.Fragment, null,
63
63
  react_1.default.createElement(DialogTitleBarTitle_1.DialogTitleBarTitle, null, titleText),
64
64
  isDismissible && (react_1.default.createElement(Buttons_1.IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
@@ -32,7 +32,7 @@ exports.DialogTitleBarTitle = void 0;
32
32
  *--------------------------------------------------------------------------------------------*/
33
33
  var react_1 = __importDefault(require("react"));
34
34
  var classnames_1 = __importDefault(require("classnames"));
35
- var theming_1 = require("@storybook/theming");
35
+ var utils_1 = require("../utils");
36
36
  require("@itwin/itwinui-css/css/dialog.css");
37
37
  /**
38
38
  * Dialog title bar. Recommended to be used as a child of `Dialog`.
@@ -41,7 +41,7 @@ require("@itwin/itwinui-css/css/dialog.css");
41
41
  */
42
42
  exports.DialogTitleBarTitle = react_1.default.forwardRef(function (props, ref) {
43
43
  var children = props.children, className = props.className, rest = __rest(props, ["children", "className"]);
44
- (0, theming_1.useTheme)();
44
+ (0, utils_1.useTheme)();
45
45
  return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog-title', className), ref: ref }, rest), children));
46
46
  });
47
47
  exports.default = exports.DialogTitleBarTitle;
@@ -43,9 +43,6 @@ exports.Menu = react_1.default.forwardRef(function (props, ref) {
43
43
  var _c = react_1.default.useState(), focusedIndex = _c[0], setFocusedIndex = _c[1];
44
44
  var menuRef = react_1.default.useRef(null);
45
45
  var refs = (0, utils_1.useMergedRefs)(menuRef, ref);
46
- react_1.default.useEffect(function () {
47
- setFocusedIndex(null);
48
- }, [children]);
49
46
  var getFocusableNodes = react_1.default.useCallback(function () {
50
47
  var focusableItems = (0, utils_1.getFocusableElements)(menuRef.current);
51
48
  // Filter out focusable elements that are inside each menu item, e.g. checkbox, anchor
@@ -44,19 +44,38 @@ export declare type SelectOption<T> = {
44
44
  */
45
45
  [key: string]: unknown;
46
46
  } & CommonProps;
47
- export declare type SelectProps<T> = {
47
+ export declare type SelectValueChangeEvent = 'added' | 'removed';
48
+ export declare type SelectMultipleTypeProps<T> = {
48
49
  /**
49
- * Array of options that populates the select menu.
50
+ * Enable multiple selection.
51
+ * @default false
50
52
  */
51
- options: SelectOption<T>[];
53
+ multiple?: false;
54
+ /**
55
+ * Custom renderer for the selected item in select.
56
+ * If `multiple` is enabled, it will give array of options to render.
57
+ */
58
+ selectedItemRenderer?: (option: SelectOption<T>) => JSX.Element;
52
59
  /**
53
60
  * Selected option value.
61
+ * If `multiple` is enabled, it is an array of values.
54
62
  */
55
63
  value?: T;
56
64
  /**
57
65
  * Callback function handling change event on select.
58
66
  */
59
67
  onChange?: (value: T) => void;
68
+ } | {
69
+ multiple: true;
70
+ selectedItemRenderer?: (options: SelectOption<T>[]) => JSX.Element;
71
+ value?: T[];
72
+ onChange?: (value: T, event: SelectValueChangeEvent) => void;
73
+ };
74
+ export declare type SelectProps<T> = {
75
+ /**
76
+ * Array of options that populates the select menu.
77
+ */
78
+ options: SelectOption<T>[];
60
79
  /**
61
80
  * Placeholder when no item is selected.
62
81
  */
@@ -79,10 +98,6 @@ export declare type SelectProps<T> = {
79
98
  * Custom renderer for an item in the dropdown list. `MenuItem` item props are going to be populated if not provided.
80
99
  */
81
100
  itemRenderer?: (option: SelectOption<T>, itemProps: ItemRendererProps) => JSX.Element;
82
- /**
83
- * Custom renderer for the selected item in select.
84
- */
85
- selectedItemRenderer?: (option: SelectOption<T>) => JSX.Element;
86
101
  /**
87
102
  * Custom class for menu.
88
103
  */
@@ -96,7 +111,7 @@ export declare type SelectProps<T> = {
96
111
  * @see [tippy.js props](https://atomiks.github.io/tippyjs/v6/all-props/)
97
112
  */
98
113
  popoverProps?: Omit<PopoverProps, 'onShow' | 'onHide' | 'disabled'>;
99
- } & Pick<PopoverProps, 'onShow' | 'onHide'> & Omit<React.ComponentPropsWithoutRef<'div'>, 'size' | 'disabled' | 'placeholder' | 'onChange'>;
114
+ } & SelectMultipleTypeProps<T> & Pick<PopoverProps, 'onShow' | 'onHide'> & Omit<React.ComponentPropsWithoutRef<'div'>, 'size' | 'disabled' | 'placeholder' | 'onChange'>;
100
115
  /**
101
116
  * Select component to select value from options.
102
117
  * Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
@@ -37,6 +37,14 @@ var MenuItem_1 = require("../Menu/MenuItem");
37
37
  var utils_1 = require("../utils");
38
38
  require("@itwin/itwinui-css/css/inputs.css");
39
39
  var CaretDownSmall_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/icons/CaretDownSmall"));
40
+ var SelectTag_1 = __importDefault(require("./SelectTag"));
41
+ var isMultipleEnabled = function (variable, multiple) {
42
+ return multiple;
43
+ };
44
+ // Type guard for multiple did not work
45
+ var isSingleOnChange = function (onChange, multiple) {
46
+ return !multiple;
47
+ };
40
48
  /**
41
49
  * Select component to select value from options.
42
50
  * Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
@@ -89,13 +97,13 @@ var CaretDownSmall_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/i
89
97
  var Select = function (props) {
90
98
  var _a;
91
99
  var _b;
92
- var options = props.options, value = props.value, onChange = props.onChange, placeholder = props.placeholder, _c = props.disabled, disabled = _c === void 0 ? false : _c, size = props.size, _d = props.setFocus, setFocus = _d === void 0 ? false : _d, itemRenderer = props.itemRenderer, selectedItemRenderer = props.selectedItemRenderer, className = props.className, style = props.style, menuClassName = props.menuClassName, menuStyle = props.menuStyle, onShow = props.onShow, onHide = props.onHide, popoverProps = props.popoverProps, rest = __rest(props, ["options", "value", "onChange", "placeholder", "disabled", "size", "setFocus", "itemRenderer", "selectedItemRenderer", "className", "style", "menuClassName", "menuStyle", "onShow", "onHide", "popoverProps"]);
100
+ var options = props.options, value = props.value, onChange = props.onChange, placeholder = props.placeholder, _c = props.disabled, disabled = _c === void 0 ? false : _c, size = props.size, _d = props.setFocus, setFocus = _d === void 0 ? false : _d, itemRenderer = props.itemRenderer, selectedItemRenderer = props.selectedItemRenderer, className = props.className, style = props.style, menuClassName = props.menuClassName, menuStyle = props.menuStyle, onShow = props.onShow, onHide = props.onHide, popoverProps = props.popoverProps, _e = props.multiple, multiple = _e === void 0 ? false : _e, rest = __rest(props, ["options", "value", "onChange", "placeholder", "disabled", "size", "setFocus", "itemRenderer", "selectedItemRenderer", "className", "style", "menuClassName", "menuStyle", "onShow", "onHide", "popoverProps", "multiple"]);
93
101
  (0, utils_1.useTheme)();
94
- var _e = react_1.default.useState((_b = popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.visible) !== null && _b !== void 0 ? _b : false), isOpen = _e[0], setIsOpen = _e[1];
102
+ var _f = react_1.default.useState((_b = popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.visible) !== null && _b !== void 0 ? _b : false), isOpen = _f[0], setIsOpen = _f[1];
95
103
  react_1.default.useEffect(function () {
96
104
  setIsOpen(function (open) { var _a; return (_a = popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.visible) !== null && _a !== void 0 ? _a : open; });
97
105
  }, [popoverProps]);
98
- var _f = react_1.default.useState(0), minWidth = _f[0], setMinWidth = _f[1];
106
+ var _g = react_1.default.useState(0), minWidth = _g[0], setMinWidth = _g[1];
99
107
  var toggle = function () { return setIsOpen(function (open) { return !open; }); };
100
108
  var selectRef = react_1.default.useRef(null);
101
109
  var toggleButtonRef = react_1.default.useRef(null);
@@ -122,8 +130,10 @@ var Select = function (props) {
122
130
  case 'Enter':
123
131
  case ' ':
124
132
  case 'Spacebar':
125
- toggle();
126
- event.preventDefault();
133
+ if (event.target === selectRef.current) {
134
+ toggle();
135
+ event.preventDefault();
136
+ }
127
137
  break;
128
138
  default:
129
139
  break;
@@ -131,20 +141,41 @@ var Select = function (props) {
131
141
  };
132
142
  var menuItems = react_1.default.useCallback(function (close) {
133
143
  return options.map(function (option, index) {
134
- var isSelected = value === option.value;
144
+ var _a;
145
+ var isSelected = isMultipleEnabled(value, multiple)
146
+ ? (_a = value === null || value === void 0 ? void 0 : value.includes(option.value)) !== null && _a !== void 0 ? _a : false
147
+ : value === option.value;
135
148
  var menuItem = itemRenderer ? (itemRenderer(option, { close: close, isSelected: isSelected })) : (react_1.default.createElement(MenuItem_1.MenuItem, null, option.label));
136
- return react_1.default.cloneElement(menuItem, __assign(__assign({ key: "".concat(option.label, "-").concat(index), isSelected: isSelected, onClick: function () {
137
- !option.disabled && (onChange === null || onChange === void 0 ? void 0 : onChange(option.value));
138
- close();
139
- }, ref: function (el) { return isSelected && (el === null || el === void 0 ? void 0 : el.scrollIntoView()); }, role: 'option' }, option), menuItem.props));
149
+ var label = option.label, restOption = __rest(option, ["label"]);
150
+ return react_1.default.cloneElement(menuItem, __assign(__assign({ key: "".concat(label, "-").concat(index), isSelected: isSelected, onClick: function () {
151
+ if (option.disabled) {
152
+ return;
153
+ }
154
+ if (isSingleOnChange(onChange, multiple)) {
155
+ onChange === null || onChange === void 0 ? void 0 : onChange(option.value);
156
+ close();
157
+ }
158
+ else {
159
+ onChange === null || onChange === void 0 ? void 0 : onChange(option.value, isSelected ? 'removed' : 'added');
160
+ }
161
+ }, ref: function (el) {
162
+ if (isSelected && !multiple) {
163
+ el === null || el === void 0 ? void 0 : el.scrollIntoView();
164
+ }
165
+ }, role: 'option' }, restOption), menuItem.props));
140
166
  });
141
- }, [itemRenderer, onChange, options, value]);
142
- var selectedItem = react_1.default.useMemo(function () {
167
+ }, [itemRenderer, multiple, onChange, options, value]);
168
+ var selectedItems = react_1.default.useMemo(function () {
143
169
  if (value == null) {
144
170
  return undefined;
145
171
  }
146
- return options.find(function (option) { return option.value === value; });
147
- }, [options, value]);
172
+ return isMultipleEnabled(value, multiple)
173
+ ? options.filter(function (option) { return value.some(function (val) { return val === option.value; }); })
174
+ : options.find(function (option) { return option.value === value; });
175
+ }, [multiple, options, value]);
176
+ var tagRenderer = react_1.default.useCallback(function (item) {
177
+ return react_1.default.createElement(SelectTag_1.default, { key: item.label, label: item.label });
178
+ }, []);
148
179
  return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-input-with-icon', className), "aria-expanded": isOpen, "aria-haspopup": 'listbox', style: style }, rest),
149
180
  react_1.default.createElement(DropdownMenu_1.DropdownMenu, __assign({ menuItems: menuItems, placement: 'bottom-start', className: (0, classnames_1.default)('iui-scroll', menuClassName), style: __assign({ minWidth: minWidth, maxWidth: "min(".concat(minWidth * 2, "px, 90vw)"), maxHeight: 315 }, menuStyle), role: 'listbox', onShow: onShowHandler, onHide: onHideHandler, disabled: disabled }, popoverProps, { visible: isOpen, onClickOutside: function (_, _a) {
150
181
  var _b;
@@ -154,21 +185,13 @@ var Select = function (props) {
154
185
  }
155
186
  } }),
156
187
  react_1.default.createElement("div", { ref: selectRef, className: (0, classnames_1.default)('iui-select-button', (_a = {
157
- 'iui-placeholder': !selectedItem && !!placeholder,
188
+ 'iui-placeholder': (!selectedItems || selectedItems.length === 0) && !!placeholder,
158
189
  'iui-disabled': disabled
159
190
  },
160
191
  _a["iui-".concat(size)] = !!size,
161
192
  _a)), onClick: function () { return !disabled && toggle(); }, onKeyDown: function (e) { return !disabled && onKeyDown(e, toggle); }, tabIndex: !disabled ? 0 : undefined },
162
- !selectedItem && react_1.default.createElement("span", { className: 'iui-content' }, placeholder),
163
- selectedItem &&
164
- selectedItemRenderer &&
165
- selectedItemRenderer(selectedItem),
166
- selectedItem && !selectedItemRenderer && (react_1.default.createElement(react_1.default.Fragment, null,
167
- (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon) &&
168
- react_1.default.cloneElement(selectedItem.icon, {
169
- className: (0, classnames_1.default)(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon.props.className, 'iui-icon'),
170
- }),
171
- react_1.default.createElement("span", { className: 'iui-content' }, selectedItem.label))))),
193
+ (!selectedItems || selectedItems.length === 0) && (react_1.default.createElement("span", { className: 'iui-content' }, placeholder)),
194
+ isMultipleEnabled(selectedItems, multiple) ? (react_1.default.createElement(MultipleSelectButton, { selectedItems: selectedItems, selectedItemsRenderer: selectedItemRenderer, tagRenderer: tagRenderer })) : (react_1.default.createElement(SingleSelectButton, { selectedItem: selectedItems, selectedItemRenderer: selectedItemRenderer })))),
172
195
  react_1.default.createElement("span", { ref: toggleButtonRef, className: (0, classnames_1.default)('iui-end-icon', {
173
196
  'iui-actionable': !disabled,
174
197
  'iui-disabled': disabled,
@@ -177,4 +200,38 @@ var Select = function (props) {
177
200
  react_1.default.createElement(CaretDownSmall_1.default, { "aria-hidden": true }))));
178
201
  };
179
202
  exports.Select = Select;
203
+ var SingleSelectButton = function (_a) {
204
+ var selectedItem = _a.selectedItem, selectedItemRenderer = _a.selectedItemRenderer;
205
+ return (react_1.default.createElement(react_1.default.Fragment, null,
206
+ selectedItem &&
207
+ selectedItemRenderer &&
208
+ selectedItemRenderer(selectedItem),
209
+ selectedItem && !selectedItemRenderer && (react_1.default.createElement(react_1.default.Fragment, null,
210
+ selectedItem.icon &&
211
+ react_1.default.cloneElement(selectedItem.icon, {
212
+ className: (0, classnames_1.default)(selectedItem.icon.props.className, 'iui-icon'),
213
+ }),
214
+ react_1.default.createElement("span", { className: 'iui-content' }, selectedItem.label)))));
215
+ };
216
+ var MultipleSelectButton = function (_a) {
217
+ var selectedItems = _a.selectedItems, selectedItemsRenderer = _a.selectedItemsRenderer, tagRenderer = _a.tagRenderer;
218
+ var selectedItemsElements = react_1.default.useMemo(function () {
219
+ if (!selectedItems) {
220
+ return [];
221
+ }
222
+ return selectedItems.map(function (item) { return tagRenderer(item); });
223
+ }, [selectedItems, tagRenderer]);
224
+ var _b = (0, utils_1.useOverflow)(selectedItemsElements), containerRef = _b[0], visibleCount = _b[1];
225
+ return (react_1.default.createElement(react_1.default.Fragment, null,
226
+ selectedItems &&
227
+ selectedItemsRenderer &&
228
+ selectedItemsRenderer(selectedItems),
229
+ selectedItems && !selectedItemsRenderer && (react_1.default.createElement("span", { className: 'iui-content' },
230
+ react_1.default.createElement("div", { className: 'iui-select-tag-container', ref: containerRef },
231
+ react_1.default.createElement(react_1.default.Fragment, null,
232
+ visibleCount < selectedItemsElements.length
233
+ ? selectedItemsElements.slice(0, visibleCount - 1)
234
+ : selectedItemsElements,
235
+ visibleCount < selectedItemsElements.length && (react_1.default.createElement(SelectTag_1.default, { label: "+".concat(selectedItemsElements.length - visibleCount + 1, " item(s)") }))))))));
236
+ };
180
237
  exports.default = exports.Select;
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from '../utils';
3
+ import '@itwin/itwinui-css/css/inputs.css';
4
+ export declare type SelectTagProps = {
5
+ /**
6
+ * Text inside the tag.
7
+ */
8
+ label: string;
9
+ } & CommonProps;
10
+ /**
11
+ * Tag for showing selected value in `Select`.
12
+ * @private
13
+ */
14
+ export declare const SelectTag: (props: SelectTagProps) => JSX.Element;
15
+ export default SelectTag;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.SelectTag = void 0;
29
+ /*---------------------------------------------------------------------------------------------
30
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
31
+ * See LICENSE.md in the project root for license terms and full copyright notice.
32
+ *--------------------------------------------------------------------------------------------*/
33
+ var classnames_1 = __importDefault(require("classnames"));
34
+ var react_1 = __importDefault(require("react"));
35
+ var utils_1 = require("../utils");
36
+ require("@itwin/itwinui-css/css/inputs.css");
37
+ /**
38
+ * Tag for showing selected value in `Select`.
39
+ * @private
40
+ */
41
+ var SelectTag = function (props) {
42
+ var className = props.className, label = props.label, rest = __rest(props, ["className", "label"]);
43
+ (0, utils_1.useTheme)();
44
+ return (react_1.default.createElement("span", __assign({ className: (0, classnames_1.default)('iui-select-tag', className) }, rest),
45
+ react_1.default.createElement("span", { className: 'iui-select-tag-label' }, label)));
46
+ };
47
+ exports.SelectTag = SelectTag;
48
+ exports.default = exports.SelectTag;
@@ -1,4 +1,4 @@
1
1
  export { Select } from './Select';
2
- export type { SelectProps, SelectOption, ItemRendererProps } from './Select';
2
+ export type { SelectProps, SelectOption, ItemRendererProps, SelectValueChangeEvent, } from './Select';
3
3
  declare const _default: "./Select";
4
4
  export default _default;
@@ -129,7 +129,9 @@ export declare type TableProps<T extends Record<string, unknown> = Record<string
129
129
  * Function that should return custom props passed to the each row.
130
130
  * Must be memoized.
131
131
  */
132
- rowProps?: (row: Row<T>) => React.ComponentPropsWithRef<'div'>;
132
+ rowProps?: (row: Row<T>) => React.ComponentPropsWithRef<'div'> & {
133
+ status?: 'positive' | 'warning' | 'negative';
134
+ };
133
135
  /**
134
136
  * Modify the density of the table (adjusts the row height).
135
137
  * @default 'default'
@@ -359,7 +359,8 @@ var Table = function (props) {
359
359
  (showFilterButton(column) ||
360
360
  showSortButton(column)) && (react_1.default.createElement("div", { className: 'iui-table-header-actions-container' },
361
361
  showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
362
- showSortButton(column) && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))))),
362
+ showSortButton(column) && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSortedDesc ||
363
+ (!column.isSorted && column.sortDescFirst) ? (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))))),
363
364
  isResizable &&
364
365
  column.isResizerVisible &&
365
366
  index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
@@ -8,7 +8,11 @@ import { CellProps, Row, TableInstance, TableState } from 'react-table';
8
8
  */
9
9
  export declare const TableRow: <T extends Record<string, unknown>>(props: {
10
10
  row: Row<T>;
11
- rowProps?: ((row: Row<T>) => React.ComponentPropsWithRef<'div'>) | undefined;
11
+ rowProps?: ((row: Row<T>) => Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
12
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
13
+ } & {
14
+ status?: "positive" | "warning" | "negative" | undefined;
15
+ }) | undefined;
12
16
  isLast: boolean;
13
17
  onRowInViewport: React.MutableRefObject<((rowData: T) => void) | undefined>;
14
18
  onBottomReached: React.MutableRefObject<(() => void) | undefined>;
@@ -25,7 +29,11 @@ export declare const TableRow: <T extends Record<string, unknown>>(props: {
25
29
  }) => JSX.Element;
26
30
  export declare const TableRowMemoized: <T extends Record<string, unknown>>(props: {
27
31
  row: Row<T>;
28
- rowProps?: ((row: Row<T>) => React.ComponentPropsWithRef<'div'>) | undefined;
32
+ rowProps?: ((row: Row<T>) => Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
33
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
34
+ } & {
35
+ status?: "positive" | "warning" | "negative" | undefined;
36
+ }) | undefined;
29
37
  isLast: boolean;
30
38
  onRowInViewport: React.MutableRefObject<((rowData: T) => void) | undefined>;
31
39
  onBottomReached: React.MutableRefObject<(() => void) | undefined>;
@@ -10,6 +10,17 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
13
24
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
25
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
26
  };
@@ -30,6 +41,8 @@ var TableCell_1 = require("./TableCell");
30
41
  * When adding new features check whether it changes state that affects row. If it does then add equality check to `React.memo`.
31
42
  */
32
43
  var TableRow = function (props) {
44
+ var _a;
45
+ var _b;
33
46
  var row = props.row, rowProps = props.rowProps, isLast = props.isLast, onRowInViewport = props.onRowInViewport, onBottomReached = props.onBottomReached, intersectionMargin = props.intersectionMargin, onClick = props.onClick, subComponent = props.subComponent, isDisabled = props.isDisabled, tableHasSubRows = props.tableHasSubRows, tableInstance = props.tableInstance, expanderCell = props.expanderCell, bodyRef = props.bodyRef, tableRowRef = props.tableRowRef;
34
47
  var onIntersect = react_1.default.useCallback(function () {
35
48
  var _a, _b;
@@ -50,13 +63,16 @@ var TableRow = function (props) {
50
63
  rootMargin: "".concat(intersectionMargin, "px"),
51
64
  root: intersectionRoot,
52
65
  });
53
- var userRowProps = rowProps === null || rowProps === void 0 ? void 0 : rowProps(row);
54
- var mergedProps = __assign(__assign(__assign({}, row.getRowProps({ style: { flex: "0 0 auto", minWidth: '100%' } })), userRowProps), {
55
- className: (0, classnames_1.default)('iui-row', {
56
- 'iui-selected': row.isSelected,
57
- 'iui-row-expanded': row.isExpanded && subComponent,
58
- 'iui-disabled': isDisabled,
59
- }, userRowProps === null || userRowProps === void 0 ? void 0 : userRowProps.className),
66
+ var userRowProps = (_b = rowProps === null || rowProps === void 0 ? void 0 : rowProps(row)) !== null && _b !== void 0 ? _b : {};
67
+ var status = userRowProps.status, restUserRowProps = __rest(userRowProps, ["status"]);
68
+ var mergedProps = __assign(__assign(__assign({}, row.getRowProps({ style: { flex: "0 0 auto", minWidth: '100%' } })), restUserRowProps), {
69
+ className: (0, classnames_1.default)('iui-row', (_a = {
70
+ 'iui-selected': row.isSelected,
71
+ 'iui-row-expanded': row.isExpanded && subComponent,
72
+ 'iui-disabled': isDisabled
73
+ },
74
+ _a["iui-".concat(status)] = !!status,
75
+ _a), userRowProps === null || userRowProps === void 0 ? void 0 : userRowProps.className),
60
76
  });
61
77
  var refs = (0, utils_1.useMergedRefs)(intersectionRef, mergedProps.ref, tableRowRef);
62
78
  return (react_1.default.createElement(react_1.default.Fragment, null,
@@ -1,6 +1,19 @@
1
1
  import React from 'react';
2
2
  import { CellRendererProps } from 'react-table';
3
- export declare type DefaultCellProps<T extends Record<string, unknown>> = CellRendererProps<T> & React.ComponentPropsWithoutRef<'div'>;
3
+ export declare type DefaultCellProps<T extends Record<string, unknown>> = {
4
+ /**
5
+ * Custom icon to be displayed at the beginning of the cell.
6
+ */
7
+ startIcon?: JSX.Element;
8
+ /**
9
+ * Custom icon to be displayed at the end of the cell.
10
+ */
11
+ endIcon?: JSX.Element;
12
+ /**
13
+ * Status of the cell.
14
+ */
15
+ status?: 'positive' | 'negative' | 'warning';
16
+ } & CellRendererProps<T> & React.ComponentPropsWithoutRef<'div'>;
4
17
  /**
5
18
  * Default cell.
6
19
  * It should be passed to `cellRenderer`.
@@ -44,12 +44,18 @@ var classnames_1 = __importDefault(require("classnames"));
44
44
  * }
45
45
  */
46
46
  var DefaultCell = function (props) {
47
+ var _a;
47
48
  // Omitting `cellProps`
48
49
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
- var _a = props.cellElementProps, cellElementClassName = _a.className, cellElementStyle = _a.style, cellElementProps = __rest(_a, ["className", "style"]), children = props.children, cellProps = props.cellProps, isDisabled = props.isDisabled, className = props.className, style = props.style, rest = __rest(props, ["cellElementProps", "children", "cellProps", "isDisabled", "className", "style"]);
50
- return (react_1.default.createElement("div", __assign({}, cellElementProps, rest, { className: (0, classnames_1.default)(cellElementClassName, className, {
51
- 'iui-disabled': isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(cellProps.row.original),
52
- }), style: __assign(__assign({}, cellElementStyle), style) }), children));
50
+ var _b = props.cellElementProps, cellElementClassName = _b.className, cellElementStyle = _b.style, cellElementProps = __rest(_b, ["className", "style"]), children = props.children, startIcon = props.startIcon, endIcon = props.endIcon, cellProps = props.cellProps, isDisabled = props.isDisabled, className = props.className, style = props.style, status = props.status, rest = __rest(props, ["cellElementProps", "children", "startIcon", "endIcon", "cellProps", "isDisabled", "className", "style", "status"]);
51
+ return (react_1.default.createElement("div", __assign({}, cellElementProps, rest, { className: (0, classnames_1.default)(cellElementClassName, className, (_a = {
52
+ 'iui-disabled': isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(cellProps.row.original)
53
+ },
54
+ _a["iui-".concat(status)] = !!status,
55
+ _a)), style: __assign(__assign({}, cellElementStyle), style) }),
56
+ startIcon && react_1.default.createElement("div", { className: 'iui-cell-start-icon' }, startIcon),
57
+ children,
58
+ endIcon && react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, endIcon)));
53
59
  };
54
60
  exports.DefaultCell = DefaultCell;
55
61
  exports.default = exports.DefaultCell;
@@ -61,7 +61,7 @@ export type { RadioProps } from './Radio';
61
61
  export { RadioTile, RadioTileGroup } from './RadioTiles';
62
62
  export type { RadioTileGroupProps, RadioTileProps } from './RadioTiles';
63
63
  export { Select } from './Select';
64
- export type { SelectProps, SelectOption, ItemRendererProps } from './Select';
64
+ export type { SelectProps, SelectOption, ItemRendererProps, SelectValueChangeEvent, } from './Select';
65
65
  export { SideNavigation, SidenavButton, SidenavSubmenu, SidenavSubmenuHeader, } from './SideNavigation';
66
66
  export type { SideNavigationProps, SidenavButtonProps, SidenavSubmenuProps, SidenavSubmenuHeaderProps, } from './SideNavigation';
67
67
  export { SkipToContentLink } from './SkipToContentLink';
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { CommonProps } from '../props';
3
3
  export declare type MiddleTextTruncationProps = {
4
4
  /**
@@ -10,12 +10,26 @@ export declare type MiddleTextTruncationProps = {
10
10
  * @default 6
11
11
  */
12
12
  endCharsCount?: number;
13
+ /**
14
+ * Custom renderer for the truncated text.
15
+ */
16
+ textRenderer?: (truncatedText: string, originalText: string) => React.ReactNode;
13
17
  } & CommonProps;
14
18
  /**
15
19
  * Truncates text with the ellipsis in the middle,
16
20
  * leaving defined number of chars at the end.
17
21
  * @example
18
22
  * <MiddleTextTruncation text='ThisIsMyVeryLongFileName.dgn' />
23
+ * @example
24
+ * <MiddleTextTruncation text='ThisIsMyVeryLongFileName.dgn' endCharsCount={10} />
25
+ * @example
26
+ * <MiddleTextTruncation
27
+ * text='ThisIsMyVeryLongFileName.dgn'
28
+ * textRenderer={React.useCallback(
29
+ * (truncatedText) => <b>{truncatedText}</b>,
30
+ * []
31
+ * )}
32
+ * />
19
33
  */
20
34
  export declare const MiddleTextTruncation: (props: MiddleTextTruncationProps) => JSX.Element;
21
35
  export default MiddleTextTruncation;
@@ -38,10 +38,21 @@ var ELLIPSIS_CHAR = '…';
38
38
  * leaving defined number of chars at the end.
39
39
  * @example
40
40
  * <MiddleTextTruncation text='ThisIsMyVeryLongFileName.dgn' />
41
+ * @example
42
+ * <MiddleTextTruncation text='ThisIsMyVeryLongFileName.dgn' endCharsCount={10} />
43
+ * @example
44
+ * <MiddleTextTruncation
45
+ * text='ThisIsMyVeryLongFileName.dgn'
46
+ * textRenderer={React.useCallback(
47
+ * (truncatedText) => <b>{truncatedText}</b>,
48
+ * []
49
+ * )}
50
+ * />
41
51
  */
42
52
  var MiddleTextTruncation = function (props) {
43
- var text = props.text, _a = props.endCharsCount, endCharsCount = _a === void 0 ? 6 : _a, style = props.style, rest = __rest(props, ["text", "endCharsCount", "style"]);
44
- var _b = (0, useOverflow_1.useOverflow)(text), ref = _b[0], visibleCount = _b[1];
53
+ var _a;
54
+ var text = props.text, _b = props.endCharsCount, endCharsCount = _b === void 0 ? 6 : _b, textRenderer = props.textRenderer, style = props.style, rest = __rest(props, ["text", "endCharsCount", "textRenderer", "style"]);
55
+ var _c = (0, useOverflow_1.useOverflow)(text), ref = _c[0], visibleCount = _c[1];
45
56
  var truncatedText = react_1.default.useMemo(function () {
46
57
  if (visibleCount < text.length) {
47
58
  return "".concat(text.substring(0, visibleCount - endCharsCount - ELLIPSIS_CHAR.length)).concat(ELLIPSIS_CHAR).concat(text.substring(text.length - endCharsCount));
@@ -50,7 +61,7 @@ var MiddleTextTruncation = function (props) {
50
61
  return text;
51
62
  }
52
63
  }, [endCharsCount, text, visibleCount]);
53
- return (react_1.default.createElement("span", __assign({ style: __assign({ display: 'flex', minWidth: 0, flexGrow: 1, whiteSpace: 'nowrap' }, style), ref: ref }, rest), truncatedText));
64
+ return (react_1.default.createElement("span", __assign({ style: __assign({ display: 'flex', minWidth: 0, flexGrow: 1, whiteSpace: 'nowrap' }, style), ref: ref }, rest), (_a = textRenderer === null || textRenderer === void 0 ? void 0 : textRenderer(truncatedText, text)) !== null && _a !== void 0 ? _a : truncatedText));
54
65
  };
55
66
  exports.MiddleTextTruncation = MiddleTextTruncation;
56
67
  exports.default = exports.MiddleTextTruncation;