@mezzanine-ui/react 0.9.2 → 0.10.2

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 (184) hide show
  1. package/Accordion/Accordion.js +5 -4
  2. package/Accordion/AccordionDetails.js +2 -2
  3. package/Accordion/AccordionSummary.js +3 -4
  4. package/Alert/Alert.js +1 -3
  5. package/AppBar/AppBar.js +1 -1
  6. package/AppBar/AppBarBrand.d.ts +1 -1
  7. package/AppBar/AppBarBrand.js +1 -1
  8. package/AppBar/AppBarMain.d.ts +1 -1
  9. package/AppBar/AppBarMain.js +1 -1
  10. package/AppBar/AppBarSupport.d.ts +1 -1
  11. package/AppBar/AppBarSupport.js +1 -1
  12. package/Badge/Badge.js +2 -2
  13. package/Badge/BadgeContainer.d.ts +1 -1
  14. package/Badge/BadgeContainer.js +1 -1
  15. package/Button/Button.d.ts +2 -2
  16. package/Button/Button.js +7 -5
  17. package/Button/ButtonGroup.js +7 -5
  18. package/Button/IconButton.d.ts +3 -3
  19. package/Button/IconButton.js +1 -1
  20. package/Calendar/Calendar.js +9 -10
  21. package/Calendar/CalendarCell.js +2 -2
  22. package/Calendar/CalendarContext.d.ts +3 -3
  23. package/Calendar/CalendarContext.js +20 -12
  24. package/Calendar/CalendarControls.js +3 -3
  25. package/Calendar/CalendarDayOfWeek.js +1 -1
  26. package/Calendar/CalendarDays.js +4 -5
  27. package/Calendar/CalendarMonths.js +4 -4
  28. package/Calendar/CalendarWeeks.js +4 -5
  29. package/Calendar/CalendarYears.js +4 -4
  30. package/Calendar/useCalendarControls.d.ts +2 -3
  31. package/Card/Card.js +5 -5
  32. package/Card/CardActions.js +1 -2
  33. package/Checkbox/CheckAll.js +2 -2
  34. package/Checkbox/Checkbox.js +5 -3
  35. package/Checkbox/CheckboxGroup.js +5 -5
  36. package/ConfirmActions/ConfirmActions.js +1 -2
  37. package/DatePicker/DatePicker.js +2 -3
  38. package/DatePicker/DatePickerCalendar.js +1 -1
  39. package/DateRangePicker/DateRangePicker.js +2 -3
  40. package/DateRangePicker/DateRangePickerCalendar.js +3 -4
  41. package/DateRangePicker/useDateRangeCalendarControls.d.ts +1 -2
  42. package/DateRangePicker/useDateRangePickerValue.d.ts +12 -13
  43. package/DateTimePicker/DateTimePicker.js +2 -3
  44. package/DateTimePicker/DateTimePickerPanel.js +1 -3
  45. package/Drawer/Drawer.js +1 -1
  46. package/Dropdown/Dropdown.d.ts +1 -1
  47. package/Dropdown/Dropdown.js +2 -2
  48. package/Empty/Empty.js +3 -4
  49. package/Form/FormField.js +2 -2
  50. package/Form/FormLabel.js +1 -2
  51. package/Form/FormMessage.d.ts +1 -1
  52. package/Form/FormMessage.js +1 -1
  53. package/Form/useAutoCompleteValueControl.d.ts +30 -11
  54. package/Form/useAutoCompleteValueControl.js +71 -31
  55. package/Form/useInputWithTagsModeValue.js +2 -1
  56. package/Form/useSelectValueControl.d.ts +1 -1
  57. package/Icon/Icon.d.ts +4 -0
  58. package/Icon/Icon.js +4 -4
  59. package/Input/Input.d.ts +1 -1
  60. package/Input/Input.js +5 -4
  61. package/Loading/Loading.js +4 -5
  62. package/Menu/Menu.js +5 -3
  63. package/Menu/MenuDivider.d.ts +1 -1
  64. package/Menu/MenuDivider.js +1 -1
  65. package/Menu/MenuItem.js +2 -3
  66. package/Menu/MenuItemGroup.js +1 -2
  67. package/Message/Message.js +2 -3
  68. package/Modal/Modal.js +5 -5
  69. package/Modal/ModalActions.js +1 -1
  70. package/Modal/ModalBody.d.ts +1 -1
  71. package/Modal/ModalBody.js +1 -1
  72. package/Modal/ModalFooter.d.ts +1 -1
  73. package/Modal/ModalFooter.js +1 -1
  74. package/Modal/ModalHeader.js +2 -3
  75. package/Modal/useModalContainer.js +1 -1
  76. package/Navigation/Navigation.js +2 -2
  77. package/Navigation/NavigationItem.js +1 -1
  78. package/Navigation/NavigationSubMenu.js +3 -5
  79. package/Notification/Notification.js +2 -7
  80. package/Notifier/NotifierManager.js +1 -1
  81. package/Notifier/createNotifier.js +1 -1
  82. package/Overlay/Overlay.js +3 -3
  83. package/PageFooter/PageFooter.js +1 -2
  84. package/Pagination/Pagination.js +2 -3
  85. package/Pagination/PaginationItem.js +4 -4
  86. package/Pagination/PaginationJumper.js +2 -4
  87. package/Picker/PickerTrigger.d.ts +1 -1
  88. package/Picker/PickerTrigger.js +2 -2
  89. package/Picker/RangePickerTrigger.d.ts +1 -1
  90. package/Picker/RangePickerTrigger.js +2 -4
  91. package/Picker/usePickerInputValue.d.ts +2 -2
  92. package/Picker/usePickerValue.d.ts +6 -7
  93. package/Picker/useRangePickerValue.d.ts +9 -10
  94. package/Popconfirm/Popconfirm.js +1 -1
  95. package/Popover/Popover.js +2 -3
  96. package/Popper/Popper.js +2 -2
  97. package/Portal/Portal.js +1 -1
  98. package/Progress/Progress.js +9 -9
  99. package/Provider/ConfigProvider.d.ts +8 -0
  100. package/Provider/ConfigProvider.js +13 -0
  101. package/Provider/context.d.ts +6 -0
  102. package/Provider/context.js +7 -0
  103. package/Provider/index.d.ts +4 -0
  104. package/Provider/index.js +2 -0
  105. package/Radio/Radio.js +5 -3
  106. package/Radio/RadioGroup.js +5 -5
  107. package/Select/AutoComplete.d.ts +40 -14
  108. package/Select/AutoComplete.js +37 -28
  109. package/Select/Option.js +2 -2
  110. package/Select/Select.d.ts +2 -51
  111. package/Select/Select.js +15 -49
  112. package/Select/SelectTrigger.d.ts +8 -1
  113. package/Select/SelectTrigger.js +8 -12
  114. package/Select/SelectTriggerTags.d.ts +19 -0
  115. package/Select/SelectTriggerTags.js +33 -0
  116. package/Select/TreeSelect.js +3 -4
  117. package/Select/index.d.ts +1 -0
  118. package/Select/index.js +1 -0
  119. package/Select/useSelectTriggerTags.d.ts +19 -0
  120. package/Select/useSelectTriggerTags.js +61 -0
  121. package/Skeleton/Skeleton.js +1 -1
  122. package/Slider/Slider.d.ts +1 -1
  123. package/Slider/Slider.js +7 -11
  124. package/Stepper/Step.js +2 -2
  125. package/Stepper/Stepper.js +1 -1
  126. package/Switch/Switch.js +2 -3
  127. package/Table/Table.d.ts +1 -1
  128. package/Table/Table.js +3 -10
  129. package/Table/TableBody.js +2 -4
  130. package/Table/TableBodyRow.js +4 -7
  131. package/Table/TableCell.js +3 -3
  132. package/Table/TableExpandedTable.js +5 -6
  133. package/Table/TableHeader.d.ts +2 -1
  134. package/Table/TableHeader.js +3 -6
  135. package/Table/editable/TableEditRenderWrapper.js +2 -2
  136. package/Table/expandable/TableExpandable.js +2 -2
  137. package/Table/pagination/TablePagination.js +1 -2
  138. package/Table/refresh/TableRefresh.js +1 -1
  139. package/Table/rowSelection/TableRowSelection.js +5 -6
  140. package/Table/sorting/TableSortingIcon.js +2 -2
  141. package/Table/sorting/useTableSorting.d.ts +2 -2
  142. package/Table/useTableScroll.d.ts +178 -178
  143. package/Tabs/Tab.js +2 -2
  144. package/Tabs/TabPane.js +1 -1
  145. package/Tabs/Tabs.js +1 -3
  146. package/Tag/Tag.js +7 -6
  147. package/TextField/TextField.js +7 -5
  148. package/TextField/useTextFieldControl.d.ts +2 -2
  149. package/Textarea/Textarea.d.ts +1 -1
  150. package/Textarea/Textarea.js +5 -4
  151. package/TimePanel/TimePanel.js +1 -4
  152. package/TimePanel/TimePanelAction.js +1 -1
  153. package/TimePanel/TimePanelColumn.js +2 -5
  154. package/TimePicker/TimePicker.js +2 -3
  155. package/TimePicker/TimePickerPanel.js +1 -1
  156. package/Tooltip/Tooltip.js +3 -3
  157. package/Transition/Collapse.js +3 -2
  158. package/Transition/Fade.js +2 -2
  159. package/Transition/Grow.js +3 -2
  160. package/Transition/SlideFade.js +2 -2
  161. package/Transition/Transition.js +2 -2
  162. package/Transition/Zoom.js +2 -2
  163. package/Tree/Tree.js +1 -1
  164. package/Tree/TreeNode.js +9 -9
  165. package/Tree/TreeNodeList.js +5 -4
  166. package/Tree/getTreeNodeEntities.js +6 -3
  167. package/Typography/Typography.d.ts +2 -2
  168. package/Typography/Typography.js +2 -2
  169. package/Upload/UploadButton.js +2 -2
  170. package/Upload/UploadInput.js +1 -1
  171. package/Upload/UploadPicture.js +1 -1
  172. package/Upload/UploadPictureBlock.js +2 -8
  173. package/Upload/UploadPictureWall.d.ts +1 -1
  174. package/Upload/UploadPictureWall.js +1 -2
  175. package/Upload/UploadPictureWallItem.js +1 -1
  176. package/Upload/UploadResult.d.ts +19 -0
  177. package/Upload/UploadResult.js +6 -7
  178. package/_internal/InputCheck/InputCheck.js +2 -3
  179. package/_internal/InputCheck/InputCheckGroup.js +1 -1
  180. package/_internal/InputTriggerPopper/InputTriggerPopper.js +2 -2
  181. package/_internal/SlideFadeOverlay/SlideFadeOverlay.js +1 -1
  182. package/index.d.ts +3 -1
  183. package/index.js +3 -0
  184. package/package.json +12 -12
@@ -1,7 +1,8 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { forwardRef, useContext, useState, useRef } from 'react';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { forwardRef, useContext, useState, useRef, useMemo } from 'react';
3
3
  import { selectClasses } from '@mezzanine-ui/core/select';
4
4
  import { PlusIcon } from '@mezzanine-ui/icons';
5
+ import isArray from 'lodash/isArray';
5
6
  import { useComposeRefs } from '../hooks/useComposeRefs.js';
6
7
  import Option from './Option.js';
7
8
  import { SelectControlContext } from './SelectControlContext.js';
@@ -10,7 +11,6 @@ import { useClickAway } from '../hooks/useClickAway.js';
10
11
  import SelectTrigger from './SelectTrigger.js';
11
12
  import InputTriggerPopper from '../_internal/InputTriggerPopper/InputTriggerPopper.js';
12
13
  import Menu from '../Menu/Menu.js';
13
- import Empty from '../Empty/Empty.js';
14
14
  import Icon from '../Icon/Icon.js';
15
15
  import { FormControlContext } from '../Form/FormControlContext.js';
16
16
  import cx from 'clsx';
@@ -22,16 +22,18 @@ const MENU_ID = 'mzn-select-autocomplete-menu-id';
22
22
  * should considering using the `Select` component with `onSearch` prop.
23
23
  */
24
24
  const AutoComplete = forwardRef(function Select(props, ref) {
25
- var _a;
25
+ var _a, _b;
26
26
  const { disabled: disabledFromFormControl, fullWidth: fullWidthFromFormControl, required: requiredFromFormControl, severity, } = useContext(FormControlContext) || {};
27
- const { addable = false, className, disabled = disabledFromFormControl || false, disabledOptionsFilter = false, defaultValue, error = severity === 'error' || false, fullWidth = fullWidthFromFormControl || false, inputRef, inputProps, itemsInView = 4, menuMaxHeight, menuRole = 'listbox', menuSize = 'medium', onChange: onChangeProp, onClear: onClearProp, onInsert, onSearch, options: optionsProp, popperOptions = {}, placeholder = '', prefix, required = requiredFromFormControl || false, size = 'medium', value: valueProp, } = props;
27
+ const { addable = false, className, disabled = disabledFromFormControl || false, disabledOptionsFilter = false, defaultValue, error = severity === 'error' || false, fullWidth = fullWidthFromFormControl || false, inputRef, inputProps, itemsInView = 4, menuMaxHeight, menuRole = 'listbox', menuSize, mode = 'single', onChange: onChangeProp, onClear: onClearProp, onInsert, onSearch, options: optionsProp, popperOptions = {}, placeholder = '', prefix, required = requiredFromFormControl || false, size, value: valueProp, } = props;
28
28
  const [open, toggleOpen] = useState(false);
29
- const { focused, onFocus, onChange, onClear, options, searchText, setSearchText, setValue, value, } = useAutoCompleteValueControl({
29
+ const { focused, onFocus, onChange, onClear, options, searchText, selectedOptions, setSearchText, unselectedOptions, value, } = useAutoCompleteValueControl({
30
30
  defaultValue,
31
31
  disabledOptionsFilter,
32
+ mode,
32
33
  onChange: onChangeProp,
33
34
  onClear: onClearProp,
34
35
  onClose: () => toggleOpen(false),
36
+ onSearch,
35
37
  options: optionsProp,
36
38
  value: valueProp,
37
39
  });
@@ -41,6 +43,7 @@ const AutoComplete = forwardRef(function Select(props, ref) {
41
43
  const controlRef = useRef(null);
42
44
  const popperRef = useRef(null);
43
45
  const composedRef = useComposeRefs([ref, controlRef]);
46
+ const renderValue = focused ? () => searchText : undefined;
44
47
  useClickAway(() => {
45
48
  if (!open || focused)
46
49
  return;
@@ -53,11 +56,17 @@ const AutoComplete = forwardRef(function Select(props, ref) {
53
56
  open,
54
57
  toggleOpen,
55
58
  ]);
59
+ function getPlaceholder() {
60
+ if (focused && value && !isArray(value)) {
61
+ return value.name;
62
+ }
63
+ return placeholder;
64
+ }
56
65
  /** Trigger input props */
57
66
  const onSearchInputChange = (e) => {
58
67
  /** should sync both search input and value */
59
68
  setSearchText(e.target.value);
60
- setValue(e.target.value);
69
+ setInsertText(e.target.value);
61
70
  /** return current value to onSearch */
62
71
  onSearch === null || onSearch === void 0 ? void 0 : onSearch(e.target.value);
63
72
  };
@@ -73,6 +82,9 @@ const AutoComplete = forwardRef(function Select(props, ref) {
73
82
  onFocus(false);
74
83
  (_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
75
84
  };
85
+ const onClickSuffixActionIcon = () => {
86
+ toggleOpen((prev) => !prev);
87
+ };
76
88
  const resolvedInputProps = {
77
89
  ...inputProps,
78
90
  'aria-controls': MENU_ID,
@@ -81,30 +93,27 @@ const AutoComplete = forwardRef(function Select(props, ref) {
81
93
  onBlur: onSearchInputBlur,
82
94
  onChange: onSearchInputChange,
83
95
  onFocus: onSearchInputFocus,
84
- placeholder,
96
+ placeholder: getPlaceholder(),
85
97
  role: 'combobox',
86
98
  };
87
- return (jsx(SelectControlContext.Provider, Object.assign({ value: {
88
- onChange,
89
- value,
90
- } }, { children: jsxs("div", Object.assign({ ref: nodeRef, className: cx(selectClasses.host, {
99
+ const searchTextExistWithoutOption = !!searchText && options.find((option) => option.name === searchText) === undefined;
100
+ const context = useMemo(() => ({
101
+ onChange,
102
+ value,
103
+ }), [onChange, value]);
104
+ return (jsx(SelectControlContext.Provider, { value: context, children: jsxs("div", { ref: nodeRef, className: cx(selectClasses.host, {
91
105
  [selectClasses.hostFullWidth]: fullWidth,
92
- }) }, { children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: true, disabled: disabled, error: error, forceHideSuffixActionIcon: true, fullWidth: fullWidth, inputRef: inputRef, mode: "single", onTagClose: onChange, onClear: onClear, prefix: prefix, readOnly: false, required: required, inputProps: resolvedInputProps, size: size, suffixActionIcon: undefined, value: value }, void 0),
93
- jsxs(InputTriggerPopper, Object.assign({ ref: popperRef, anchor: controlRef, className: selectClasses.popper, open: open, sameWidth: true, options: popperOptions }, { children: [jsxs(Menu, Object.assign({ id: MENU_ID, "aria-activedescendant": (_a = value === null || value === void 0 ? void 0 : value.id) !== null && _a !== void 0 ? _a : '', itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: { border: 0 } }, { children: [jsx(Option, Object.assign({ value: searchText }, { children: searchText }), void 0),
94
- options.length ? options.map((option) => (jsx(Option, Object.assign({ value: option }, { children: option }), option))) : (jsx(Empty, { children: "\u67E5\u7121\u8CC7\u6599" }, void 0))] }), void 0),
95
- addable ? (jsxs("div", Object.assign({ className: selectClasses.autoComplete }, { children: [jsx("input", { type: "text", onChange: (e) => setInsertText(e.target.value), onClick: (e) => e.stopPropagation(), onFocus: (e) => e.stopPropagation(), placeholder: "\u65B0\u589E\u9078\u9805", value: insertText }, void 0),
96
- jsx(Icon, { className: cx(selectClasses.autoCompleteIcon, {
97
- [selectClasses.autoCompleteIconActive]: !!insertText,
98
- }), icon: PlusIcon, onClick: (e) => {
99
- var _a;
100
- e.stopPropagation();
101
- if (insertText) {
102
- const insertSuccess = (_a = onInsert === null || onInsert === void 0 ? void 0 : onInsert(insertText)) !== null && _a !== void 0 ? _a : false;
103
- if (insertSuccess) {
104
- setInsertText('');
105
- }
106
- }
107
- } }, void 0)] }), void 0)) : null] }), void 0)] }), void 0) }), void 0));
106
+ }), children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: true, disabled: disabled, ellipsis: true, error: error, fullWidth: fullWidth, inputRef: inputRef, mode: mode, onTagClose: onChange, onClear: onClear, prefix: prefix, readOnly: false, required: required, inputProps: resolvedInputProps, searchText: searchText, size: size, showTextInputAfterTags: true, suffixAction: onClickSuffixActionIcon, value: value, renderValue: renderValue }), jsxs(InputTriggerPopper, { ref: popperRef, anchor: controlRef, className: selectClasses.popper, open: open, sameWidth: true, options: popperOptions, children: [options.length ? (jsx(Menu, { id: MENU_ID, "aria-activedescendant": Array.isArray(value) ? (_b = (_a = value === null || value === void 0 ? void 0 : value[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '' : value === null || value === void 0 ? void 0 : value.id, itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: { border: 0 }, children: mode === 'single' ? (jsx(Fragment, { children: options.map((option) => (jsx(Option, { value: option.id, children: option.name }, option.id))) })) : (jsxs(Fragment, { children: [selectedOptions.map((option) => (jsx(Option, { value: option.id, children: option.name }, option.id))), unselectedOptions.map((option) => (jsx(Option, { value: option.id, children: option.name }, option.id)))] })) })) : null, searchTextExistWithoutOption && addable ? (jsxs("button", { type: "button", className: selectClasses.autoComplete, onClick: (e) => {
107
+ var _a;
108
+ e.stopPropagation();
109
+ if (insertText) {
110
+ const newOption = (_a = onInsert === null || onInsert === void 0 ? void 0 : onInsert(insertText)) !== null && _a !== void 0 ? _a : null;
111
+ if (newOption) {
112
+ setInsertText('');
113
+ onChange(newOption);
114
+ }
115
+ }
116
+ }, children: [jsx("p", { children: insertText }), jsx(Icon, { className: selectClasses.autoCompleteIcon, icon: PlusIcon })] })) : null] })] }) }));
108
117
  });
109
118
  var AutoComplete$1 = AutoComplete;
110
119
 
package/Select/Option.js CHANGED
@@ -35,10 +35,10 @@ const Option = forwardRef(function Option(props, ref) {
35
35
  break;
36
36
  }
37
37
  };
38
- return (jsx(MenuItem, Object.assign({}, rest, { ref: ref, active: active, "aria-selected": active, id: value, onClick: (evt) => {
38
+ return (jsx(MenuItem, { ...rest, ref: ref, active: active, "aria-selected": active, id: value, onClick: (evt) => {
39
39
  evt.stopPropagation();
40
40
  onSelect();
41
- }, onKeyDown: onKeyDown, role: role, tabIndex: 0 }, { children: children }), void 0));
41
+ }, onKeyDown: onKeyDown, role: role, tabIndex: 0, children: children }));
42
42
  });
43
43
  var Option$1 = Option;
44
44
 
@@ -6,7 +6,7 @@ import { PopperProps } from '../Popper';
6
6
  import { SelectValue } from './typings';
7
7
  import { PickRenameMulti } from '../utils/general';
8
8
  import { SelectTriggerProps, SelectTriggerInputProps } from './SelectTrigger';
9
- export interface SelectBaseProps extends Omit<SelectTriggerProps, 'active' | 'inputProps' | 'mode' | 'onBlur' | 'onChange' | 'onClick' | 'onFocus' | 'onKeyDown' | 'renderValue' | 'value'>, FormElementFocusHandlers, PickRenameMulti<Pick<MenuProps, 'itemsInView' | 'maxHeight' | 'role' | 'size'>, {
9
+ export interface SelectBaseProps extends Omit<SelectTriggerProps, 'active' | 'inputProps' | 'mode' | 'onBlur' | 'onChange' | 'onClick' | 'onFocus' | 'onKeyDown' | 'readOnly' | 'renderValue' | 'value'>, FormElementFocusHandlers, PickRenameMulti<Pick<MenuProps, 'itemsInView' | 'maxHeight' | 'role' | 'size'>, {
10
10
  maxHeight: 'menuMaxHeight';
11
11
  role: 'menuRole';
12
12
  size: 'menuSize';
@@ -17,10 +17,6 @@ export interface SelectBaseProps extends Omit<SelectTriggerProps, 'active' | 'in
17
17
  * The other native props for input element.
18
18
  */
19
19
  inputProps?: Omit<SelectTriggerInputProps, 'onBlur' | 'onChange' | 'onFocus' | 'placeholder' | 'role' | 'value' | `aria-${'controls' | 'expanded' | 'owns'}`>;
20
- /**
21
- * The search event handler, this prop won't work when mode is `multiple`
22
- */
23
- onSearch?(input: string): any;
24
20
  /**
25
21
  * select input placeholder
26
22
  */
@@ -36,7 +32,6 @@ export interface SelectBaseProps extends Omit<SelectTriggerProps, 'active' | 'in
36
32
  required?: boolean;
37
33
  /**
38
34
  * The size of input.
39
- * @default 'medium'
40
35
  */
41
36
  size?: SelectInputSize;
42
37
  }
@@ -87,49 +82,5 @@ export declare type SelectSingleProps = SelectBaseProps & {
87
82
  value?: SelectValue | null;
88
83
  };
89
84
  export declare type SelectProps = SelectMultipleProps | SelectSingleProps;
90
- declare const Select: import("react").ForwardRefExoticComponent<(SelectBaseProps & {
91
- /**
92
- * The default selection
93
- */
94
- defaultValue?: SelectValue[] | undefined;
95
- /**
96
- * Controls the layout of trigger.
97
- */
98
- mode: 'multiple';
99
- /**
100
- * The change event handler of input element.
101
- */
102
- onChange?(newOptions: SelectValue[]): any;
103
- /**
104
- * To customize rendering select input value
105
- */
106
- renderValue?(values: SelectValue[]): string;
107
- /**
108
- * The value of selection.
109
- * @default undefined
110
- */
111
- value?: SelectValue[] | undefined;
112
- } & import("react").RefAttributes<HTMLDivElement>) | (SelectBaseProps & {
113
- /**
114
- * The default selection
115
- */
116
- defaultValue?: SelectValue | undefined;
117
- /**
118
- * Controls the layout of trigger.
119
- */
120
- mode?: "single" | undefined;
121
- /**
122
- * The change event handler of input element.
123
- */
124
- onChange?(newOptions: SelectValue): any;
125
- /**
126
- * To customize rendering select input value
127
- */
128
- renderValue?(values: SelectValue | null): string;
129
- /**
130
- * The value of selection.
131
- * @default undefined
132
- */
133
- value?: SelectValue | null | undefined;
134
- } & import("react").RefAttributes<HTMLDivElement>)>;
85
+ declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLDivElement>>;
135
86
  export default Select;
package/Select/Select.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { forwardRef, useContext, useState, useRef, useLayoutEffect } from 'react';
2
+ import { forwardRef, useContext, useState, useRef, useMemo } from 'react';
3
3
  import { selectClasses } from '@mezzanine-ui/core/select';
4
- import { SearchIcon } from '@mezzanine-ui/icons';
4
+ import isArray from 'lodash/isArray';
5
5
  import { useComposeRefs } from '../hooks/useComposeRefs.js';
6
6
  import { SelectControlContext } from './SelectControlContext.js';
7
7
  import { useSelectValueControl } from '../Form/useSelectValueControl.js';
8
8
  import { useClickAway } from '../hooks/useClickAway.js';
9
9
  import SelectTrigger from './SelectTrigger.js';
10
- import Icon from '../Icon/Icon.js';
11
10
  import InputTriggerPopper from '../_internal/InputTriggerPopper/InputTriggerPopper.js';
12
11
  import Menu from '../Menu/Menu.js';
13
12
  import { FormControlContext } from '../Form/FormControlContext.js';
@@ -17,7 +16,7 @@ const MENU_ID = 'mzn-select-menu-id';
17
16
  const Select = forwardRef(function Select(props, ref) {
18
17
  var _a, _b;
19
18
  const { disabled: disabledFromFormControl, fullWidth: fullWidthFromFormControl, required: requiredFromFormControl, severity, } = useContext(FormControlContext) || {};
20
- const { children, className, clearable = false, defaultValue, disabled = disabledFromFormControl || false, error = severity === 'error' || false, fullWidth = fullWidthFromFormControl || false, inputProps, inputRef, itemsInView = 4, menuMaxHeight, menuRole = 'listbox', menuSize = 'medium', mode = 'single', onBlur, onChange: onChangeProp, onClear: onClearProp, onFocus, onSearch, placeholder = '', popperOptions = {}, prefix, renderValue: renderValueProp, required = requiredFromFormControl || false, size = 'medium', suffixActionIcon: suffixActionIconProp, value: valueProp, } = props;
19
+ const { children, className, clearable = false, defaultValue, disabled = disabledFromFormControl || false, error = severity === 'error' || false, fullWidth = fullWidthFromFormControl || false, inputProps, inputRef, itemsInView = 4, menuMaxHeight, menuRole = 'listbox', menuSize, mode = 'single', onBlur, onChange: onChangeProp, onClear: onClearProp, onFocus, placeholder = '', popperOptions = {}, prefix, renderValue, required = requiredFromFormControl || false, size, suffixActionIcon, value: valueProp, } = props;
21
20
  const [open, toggleOpen] = useState(false);
22
21
  const onOpen = () => {
23
22
  onFocus === null || onFocus === void 0 ? void 0 : onFocus();
@@ -47,46 +46,28 @@ const Select = forwardRef(function Select(props, ref) {
47
46
  const controlRef = useRef(null);
48
47
  const popperRef = useRef(null);
49
48
  const composedRef = useComposeRefs([ref, controlRef]);
50
- const searchable = typeof onSearch === 'function';
51
- const [searchText, changeSearchText] = useState('');
52
- const [focused, setFocused] = useState(false);
53
- const renderValue = focused && searchable ? () => searchText : renderValueProp;
54
49
  function getPlaceholder() {
55
- if (focused && searchable) {
56
- if (typeof renderValueProp === 'function') {
57
- return renderValueProp(value);
58
- }
59
- if (value) {
60
- return value.name;
61
- }
62
- return placeholder;
50
+ if (typeof renderValue === 'function') {
51
+ return renderValue(value);
52
+ }
53
+ if (value && !isArray(value)) {
54
+ return value.name;
63
55
  }
64
56
  return placeholder;
65
57
  }
66
- useLayoutEffect(() => {
67
- if (!focused) {
68
- changeSearchText('');
69
- if (typeof onSearch === 'function') {
70
- onSearch('');
71
- }
72
- }
73
- }, [focused, onSearch]);
74
58
  useClickAway(() => {
75
- if (!open || focused)
59
+ if (!open)
76
60
  return;
77
61
  return () => {
78
62
  onClose();
79
63
  };
80
64
  }, nodeRef, [
81
- focused,
82
65
  nodeRef,
83
66
  open,
84
67
  toggleOpen,
85
68
  ]);
86
- const suffixActionIcon = suffixActionIconProp || (searchable && open ? (jsx(Icon, { icon: SearchIcon }, void 0)) : undefined);
87
69
  const onClickTextField = () => {
88
- /** when searchable, should open menu when focus */
89
- if (!searchable && !disabled) {
70
+ if (!disabled) {
90
71
  onToggleOpen();
91
72
  }
92
73
  };
@@ -117,34 +98,19 @@ const Select = forwardRef(function Select(props, ref) {
117
98
  }
118
99
  }
119
100
  };
120
- /** Trigger input props */
121
- const onSearchInputChange = searchable ? (e) => {
122
- changeSearchText(e.target.value);
123
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
- onSearch(e.target.value);
125
- } : undefined;
126
- const onSearchInputFocus = searchable ? (e) => {
127
- e.stopPropagation();
128
- onToggleOpen();
129
- setFocused(true);
130
- } : undefined;
131
- const onSearchInputBlur = () => setFocused(false);
132
101
  const resolvedInputProps = {
133
102
  ...inputProps,
134
103
  'aria-controls': MENU_ID,
135
104
  'aria-expanded': open,
136
105
  'aria-owns': MENU_ID,
137
- onBlur: onSearchInputBlur,
138
- onChange: onSearchInputChange,
139
- onFocus: onSearchInputFocus,
140
106
  placeholder: getPlaceholder(),
141
107
  role: 'combobox',
142
108
  };
143
- return (jsx(SelectControlContext.Provider, Object.assign({ value: {
144
- onChange,
145
- value,
146
- } }, { children: jsxs("div", Object.assign({ ref: nodeRef, className: cx(selectClasses.host, fullWidth && selectClasses.hostFullWidth) }, { children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: clearable, disabled: disabled, error: error, fullWidth: fullWidth, inputRef: inputRef, mode: mode, onTagClose: onChange, onClear: onClear, onClick: onClickTextField, onKeyDown: onKeyDownTextField, prefix: prefix, readOnly: !searchable, required: required, inputProps: resolvedInputProps, size: size, suffixActionIcon: suffixActionIcon, value: value, renderValue: renderValue }, void 0),
147
- jsx(InputTriggerPopper, Object.assign({ ref: popperRef, anchor: controlRef, className: selectClasses.popper, open: open, sameWidth: true, options: popperOptions }, { children: jsx(Menu, Object.assign({ id: MENU_ID, "aria-activedescendant": Array.isArray(value) ? (_b = (_a = value === null || value === void 0 ? void 0 : value[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '' : value === null || value === void 0 ? void 0 : value.id, itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: { border: 0 } }, { children: children }), void 0) }), void 0)] }), void 0) }), void 0));
109
+ const context = useMemo(() => ({
110
+ onChange,
111
+ value,
112
+ }), [onChange, value]);
113
+ return (jsx(SelectControlContext.Provider, { value: context, children: jsxs("div", { ref: nodeRef, className: cx(selectClasses.host, fullWidth && selectClasses.hostFullWidth), children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: clearable, disabled: disabled, error: error, fullWidth: fullWidth, inputRef: inputRef, mode: mode, onTagClose: onChange, onClear: onClear, onClick: onClickTextField, onKeyDown: onKeyDownTextField, prefix: prefix, readOnly: true, renderValue: renderValue, required: required, inputProps: resolvedInputProps, size: size, suffixActionIcon: suffixActionIcon, value: value }), jsx(InputTriggerPopper, { ref: popperRef, anchor: controlRef, className: selectClasses.popper, open: open, sameWidth: true, options: popperOptions, children: jsx(Menu, { id: MENU_ID, "aria-activedescendant": Array.isArray(value) ? (_b = (_a = value === null || value === void 0 ? void 0 : value[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '' : value === null || value === void 0 ? void 0 : value.id, itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: { border: 0 }, children: children }) })] }) }));
148
114
  });
149
115
  var Select$1 = Select;
150
116
 
@@ -8,6 +8,10 @@ export interface SelectTriggerBaseProps extends Omit<TextFieldProps, 'active' |
8
8
  * Controls the chevron icon layout.
9
9
  */
10
10
  active?: boolean;
11
+ /**
12
+ * Tags arg ellipsis or not.
13
+ */
14
+ ellipsis?: boolean;
11
15
  /**
12
16
  * force hide suffixAction icons
13
17
  */
@@ -43,6 +47,9 @@ export interface SelectTriggerBaseProps extends Omit<TextFieldProps, 'active' |
43
47
  * @default false
44
48
  */
45
49
  required?: boolean;
50
+ searchText?: string;
51
+ showTextInputAfterTags?: boolean;
52
+ suffixAction?: VoidFunction;
46
53
  }
47
54
  export declare type SelectTriggerMultipleProps = SelectTriggerBaseProps & {
48
55
  /**
@@ -78,5 +85,5 @@ export declare type SelectTriggerSingleProps = SelectTriggerBaseProps & {
78
85
  };
79
86
  export declare type SelectTriggerComponentProps = SelectTriggerMultipleProps | SelectTriggerSingleProps;
80
87
  export declare type SelectTriggerProps = Omit<SelectTriggerComponentProps, 'innerRef'>;
81
- declare const SelectTrigger: import("react").ForwardRefExoticComponent<Pick<SelectTriggerComponentProps, "disabled" | "placeholder" | "readOnly" | "required" | "size" | "value" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "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" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "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" | "active" | "clearable" | "error" | "fullWidth" | "onClear" | "suffixActionIcon" | "forceHideSuffixActionIcon" | "inputProps" | "inputRef" | "onTagClose" | "renderValue" | "mode"> & import("react").RefAttributes<HTMLDivElement>>;
88
+ declare const SelectTrigger: import("react").ForwardRefExoticComponent<SelectTriggerProps & import("react").RefAttributes<HTMLDivElement>>;
82
89
  export default SelectTrigger;
@@ -2,14 +2,13 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { forwardRef } from 'react';
3
3
  import { selectClasses } from '@mezzanine-ui/core/select';
4
4
  import { ChevronDownIcon } from '@mezzanine-ui/icons';
5
+ import SelectTriggerTags from './SelectTriggerTags.js';
5
6
  import Icon from '../Icon/Icon.js';
6
7
  import TextField from '../TextField/TextField.js';
7
- import Tag from '../Tag/Tag.js';
8
8
  import cx from 'clsx';
9
9
 
10
10
  function SelectTriggerComponent(props) {
11
- var _a;
12
- const { active, className, disabled, forceHideSuffixActionIcon, inputProps, innerRef, inputRef, mode, onTagClose, readOnly, renderValue: renderValueProp, required, size, suffixActionIcon: suffixActionIconProp, value, ...restTextFieldProps } = props;
11
+ const { active, className, disabled, ellipsis = false, forceHideSuffixActionIcon, inputProps, innerRef, inputRef, mode, onTagClose, readOnly, renderValue: renderValueProp, required, searchText, size, showTextInputAfterTags = false, suffixAction, suffixActionIcon: suffixActionIconProp, value, ...restTextFieldProps } = props;
13
12
  /** Render value to string for input */
14
13
  const renderValue = () => {
15
14
  if (typeof renderValueProp === 'function') {
@@ -24,28 +23,25 @@ function SelectTriggerComponent(props) {
24
23
  return '';
25
24
  };
26
25
  /** Compute suffix action icon */
27
- const suffixActionIcon = suffixActionIconProp || (jsx(Icon, { icon: ChevronDownIcon, className: cx(selectClasses.triggerSuffixActionIcon, {
26
+ const suffixActionIcon = suffixActionIconProp || (jsx(Icon, { icon: ChevronDownIcon, onClick: suffixAction, className: cx(selectClasses.triggerSuffixActionIcon, {
28
27
  [selectClasses.triggerSuffixActionIconActive]: active,
29
- }) }, void 0));
28
+ }) }));
30
29
  const getTextFieldActive = () => {
31
30
  if (value) {
32
31
  if (Array.isArray(value)) {
33
- return !!(value === null || value === void 0 ? void 0 : value.length);
32
+ return !!value.length;
34
33
  }
35
34
  return !!value;
36
35
  }
37
36
  return false;
38
37
  };
39
- return (jsx(TextField, Object.assign({ ref: innerRef }, restTextFieldProps, { active: getTextFieldActive(), className: cx(selectClasses.trigger, className), disabled: disabled, size: size, suffixActionIcon: forceHideSuffixActionIcon ? undefined : suffixActionIcon }, { children: mode === 'multiple' && ((_a = value) === null || _a === void 0 ? void 0 : _a.length) ? (jsx("div", Object.assign({ className: selectClasses.triggerTags }, { children: value.map((selection) => (jsx(Tag, Object.assign({ closable: true, disabled: disabled, onClose: (e) => {
40
- e.stopPropagation();
41
- onTagClose === null || onTagClose === void 0 ? void 0 : onTagClose(selection);
42
- }, size: size }, { children: selection.name }), selection.id))) }), void 0)) : (jsx("input", Object.assign({}, inputProps, { ref: inputRef, "aria-autocomplete": "list", "aria-disabled": disabled, "aria-haspopup": "listbox", "aria-readonly": readOnly, "aria-required": required, autoComplete: "false", disabled: disabled, readOnly: readOnly, required: required, type: "search", value: renderValue() }), void 0)) }), void 0));
38
+ return (jsx(TextField, { ref: innerRef, ...restTextFieldProps, active: getTextFieldActive(), className: cx(selectClasses.trigger, className), disabled: disabled, size: size, suffixActionIcon: forceHideSuffixActionIcon ? undefined : suffixActionIcon, children: mode === 'multiple' && (value === null || value === void 0 ? void 0 : value.length) ? (jsx(SelectTriggerTags, { disabled: disabled, ellipsis: ellipsis, inputProps: inputProps, inputRef: inputRef, onTagClose: onTagClose, readOnly: readOnly, required: required, searchText: searchText, size: size, showTextInputAfterTags: showTextInputAfterTags, value: value })) : (jsx("input", { ...inputProps, ref: inputRef, "aria-autocomplete": "list", "aria-disabled": disabled, "aria-haspopup": "listbox", "aria-readonly": readOnly, "aria-required": required, autoComplete: "off", disabled: disabled, readOnly: readOnly, required: required, type: "search", value: renderValue() })) }));
43
39
  }
44
40
  const SelectTrigger = forwardRef((props, ref) => {
45
41
  if (props.mode === 'multiple') {
46
- return (jsx(SelectTriggerComponent, Object.assign({}, props, { innerRef: ref }), void 0));
42
+ return (jsx(SelectTriggerComponent, { ...props, innerRef: ref }));
47
43
  }
48
- return (jsx(SelectTriggerComponent, Object.assign({}, props, { innerRef: ref }), void 0));
44
+ return (jsx(SelectTriggerComponent, { ...props, innerRef: ref }));
49
45
  });
50
46
  var SelectTrigger$1 = SelectTrigger;
51
47
 
@@ -0,0 +1,19 @@
1
+ import { Ref } from 'react';
2
+ import { TagSize } from '@mezzanine-ui/core/tag';
3
+ import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
4
+ import { SelectValue } from './typings';
5
+ export interface SelectTriggerTagsProps {
6
+ disabled?: boolean;
7
+ ellipsis: boolean;
8
+ inputProps?: Omit<NativeElementPropsWithoutKeyAndRef<'input'>, 'autoComplete' | 'children' | 'defaultValue' | 'disabled' | 'readOnly' | 'required' | 'type' | 'value' | `aria-${'autocomplete' | 'disabled' | 'haspopup' | 'multiline' | 'readonly' | 'required'}`>;
9
+ inputRef?: Ref<HTMLInputElement>;
10
+ onTagClose?: (target: SelectValue) => void;
11
+ readOnly?: boolean;
12
+ required?: boolean;
13
+ searchText?: string;
14
+ size?: TagSize;
15
+ showTextInputAfterTags?: boolean;
16
+ value?: SelectValue[];
17
+ }
18
+ declare const SelectTriggerTags: import("react").ForwardRefExoticComponent<SelectTriggerTagsProps & import("react").RefAttributes<HTMLDivElement>>;
19
+ export default SelectTriggerTags;
@@ -0,0 +1,33 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { forwardRef, useRef } from 'react';
3
+ import { selectClasses } from '@mezzanine-ui/core/select';
4
+ import take from 'lodash/take';
5
+ import { useComposeRefs } from '../hooks/useComposeRefs.js';
6
+ import { useSelectTriggerTags } from './useSelectTriggerTags.js';
7
+ import Tag from '../Tag/Tag.js';
8
+ import cx from 'clsx';
9
+
10
+ const SelectTriggerTags = forwardRef(function SelectTriggerTags(props, ref) {
11
+ const { disabled, ellipsis, inputProps, inputRef, onTagClose, readOnly, required, searchText, size, showTextInputAfterTags, value, } = props;
12
+ const controlRef = useRef();
13
+ const composedRef = useComposeRefs([ref, controlRef]);
14
+ const { renderFakeTags, takeCount, } = useSelectTriggerTags({
15
+ controlRef,
16
+ value,
17
+ size,
18
+ });
19
+ return (jsxs("div", { ref: composedRef, className: cx(selectClasses.triggerTagsInputWrapper, {
20
+ [selectClasses.triggerTagsInputWrapperEllipsis]: ellipsis,
21
+ }), children: [jsxs("div", { className: cx(selectClasses.triggerTags, {
22
+ [selectClasses.triggerTagsEllipsis]: ellipsis,
23
+ }), children: [ellipsis ? (jsxs(Fragment, { children: [take(value, takeCount).map((selection) => (jsx(Tag, { closable: true, disabled: disabled, onClose: (e) => {
24
+ e.stopPropagation();
25
+ onTagClose === null || onTagClose === void 0 ? void 0 : onTagClose(selection);
26
+ }, size: size, children: selection.name }, selection.id))), value && value.length > takeCount ? (jsx(Tag, { disabled: disabled, size: size, children: `+${value.length - takeCount <= 99 ? value.length - takeCount : 99}...` })) : null] })) : (value === null || value === void 0 ? void 0 : value.map((selection) => (jsx(Tag, { closable: true, disabled: disabled, onClose: (e) => {
27
+ e.stopPropagation();
28
+ onTagClose === null || onTagClose === void 0 ? void 0 : onTagClose(selection);
29
+ }, size: size, children: selection.name }, selection.id)))), ellipsis ? renderFakeTags() : null] }), showTextInputAfterTags ? (jsx("div", { className: selectClasses.triggerTagsInput, children: jsx("input", { ...inputProps, ref: inputRef, "aria-autocomplete": "list", "aria-disabled": disabled, "aria-haspopup": "listbox", "aria-readonly": readOnly, "aria-required": required, autoComplete: "off", disabled: disabled, readOnly: readOnly, required: required, type: "search", value: searchText }) })) : null] }));
30
+ });
31
+ var SelectTriggerTags$1 = SelectTriggerTags;
32
+
33
+ export { SelectTriggerTags$1 as default };
@@ -14,7 +14,7 @@ import cx from 'clsx';
14
14
 
15
15
  const TreeSelect = forwardRef((props, ref) => {
16
16
  const { disabled: disabledFromFormControl, fullWidth: fullWidthFromFormControl, required: requiredFromFormControl, severity, } = useContext(FormControlContext) || {};
17
- const { className, clearable = false, defaultExpandAll, depth, disabled = disabledFromFormControl || false, disabledValues, error = severity === 'error' || false, expandControllerRef, fullWidth = fullWidthFromFormControl || false, inputProps, inputRef, itemsInView = 4, menuMaxHeight, menuProps, menuRole = 'listbox', menuSize = 'medium', mode = 'single', onBlur, onChange: onChangeProp, onFocus, options, placeholder = '', popperOptions, prefix, renderValue, required = requiredFromFormControl || false, sameWidth = false, size = 'medium', suffixActionIcon, treeProps, value: valueProp, } = props;
17
+ const { className, clearable = false, defaultExpandAll, depth, disabled = disabledFromFormControl || false, disabledValues, error = severity === 'error' || false, expandControllerRef, fullWidth = fullWidthFromFormControl || false, inputProps, inputRef, itemsInView = 4, menuMaxHeight, menuProps, menuRole = 'listbox', menuSize, mode = 'single', onBlur, onChange: onChangeProp, onFocus, options, placeholder = '', popperOptions, prefix, renderValue, required = requiredFromFormControl || false, sameWidth = false, size, suffixActionIcon, treeProps, value: valueProp, } = props;
18
18
  const { className: treeClassName, ...restTreeProps } = treeProps || {};
19
19
  const { width, border, ...restStyle } = (menuProps === null || menuProps === void 0 ? void 0 : menuProps.style) || {};
20
20
  const multiple = mode === 'multiple';
@@ -187,12 +187,11 @@ const TreeSelect = forwardRef((props, ref) => {
187
187
  const newExpandedValues = toggleValue(value, expandedValues);
188
188
  setExpandedValues(newExpandedValues);
189
189
  };
190
- return (jsxs("div", Object.assign({ ref: nodeRef, className: selectClasses.treeSelect }, { children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: clearable, disabled: disabled, error: error, fullWidth: fullWidth, inputProps: resolvedInputProps, inputRef: inputRef, mode: mode, onClear: onClear, onClick: onTextFieldClick, onKeyDown: onTextFieldKeydown, onTagClose: onTagClose, prefix: prefix, readOnly: true, renderValue: renderValue, required: required, size: size, suffixActionIcon: suffixActionIcon, value: valueProp }, void 0),
191
- jsx(InputTriggerPopper, Object.assign({ ref: popperRef, anchor: controlRef, className: selectClasses.popper, controllerRef: controllerRef, open: open, options: popperOptions, sameWidth: sameWidth }, { children: jsx(Menu, Object.assign({ itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: {
190
+ return (jsxs("div", { ref: nodeRef, className: selectClasses.treeSelect, children: [jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: clearable, disabled: disabled, error: error, fullWidth: fullWidth, inputProps: resolvedInputProps, inputRef: inputRef, mode: mode, onClear: onClear, onClick: onTextFieldClick, onKeyDown: onTextFieldKeydown, onTagClose: onTagClose, prefix: prefix, readOnly: true, renderValue: renderValue, required: required, size: size, suffixActionIcon: suffixActionIcon, value: valueProp }), jsx(InputTriggerPopper, { ref: popperRef, anchor: controlRef, className: selectClasses.popper, controllerRef: controllerRef, open: open, options: popperOptions, sameWidth: sameWidth, children: jsx(Menu, { itemsInView: itemsInView, maxHeight: menuMaxHeight, role: menuRole, size: menuSize, style: {
192
191
  ...restStyle,
193
192
  border: border || 0,
194
193
  width: width || `${panelWidth}px`,
195
- } }, { children: jsx(Tree, Object.assign({}, restTreeProps, { ref: ref, className: cx(selectClasses.tree, treeClassName), disabledValues: disabledValues, expandControllerRef: expandControllerRef, expandedValues: expandedValues, multiple: multiple, nodes: nodes, onExpand: onExpand, onSelect: onSelect, selectMethod: "target", selectable: true, values: selectedValues }), void 0) }), void 0) }), void 0)] }), void 0));
194
+ }, children: jsx(Tree, { ...restTreeProps, ref: ref, className: cx(selectClasses.tree, treeClassName), disabledValues: disabledValues, expandControllerRef: expandControllerRef, expandedValues: expandedValues, multiple: multiple, nodes: nodes, onExpand: onExpand, onSelect: onSelect, selectMethod: "target", selectable: true, values: selectedValues }) }) })] }));
196
195
  });
197
196
  var TreeSelect$1 = TreeSelect;
198
197
 
package/Select/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './typings';
2
2
  export { SelectControlContext, } from './SelectControlContext';
3
3
  export { SelectTriggerProps, SelectTriggerInputProps, default as SelectTrigger, } from './SelectTrigger';
4
+ export { SelectTriggerTagsProps, default as SelectTriggerTags, } from './SelectTriggerTags';
4
5
  export { SelectProps, default, } from './Select';
5
6
  export { OptionProps, default as Option, } from './Option';
6
7
  export { MenuItemGroupProps as OptionGroupProps, default as OptionGroup, } from '../Menu/MenuItemGroup';
package/Select/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { SelectControlContext } from './SelectControlContext.js';
2
2
  export { default as SelectTrigger } from './SelectTrigger.js';
3
+ export { default as SelectTriggerTags } from './SelectTriggerTags.js';
3
4
  export { default } from './Select.js';
4
5
  export { default as Option } from './Option.js';
5
6
  export { default as OptionGroup } from '../Menu/MenuItemGroup.js';
@@ -0,0 +1,19 @@
1
+ import { MutableRefObject } from 'react';
2
+ import { TagSize } from '@mezzanine-ui/core/tag';
3
+ import { SelectValue } from './typings';
4
+ export interface UseSelectTriggerTagsProps {
5
+ controlRef: MutableRefObject<HTMLDivElement | undefined>;
6
+ size?: TagSize;
7
+ value?: SelectValue[];
8
+ }
9
+ export interface UseSelectTriggerTagsValue {
10
+ renderFakeTags: () => JSX.Element | null;
11
+ takeCount: number;
12
+ }
13
+ export declare function calcTakeCount({ tagsWidths, maxWidth, ellipsisTagWidth, setTakeCount, }: {
14
+ tagsWidths: number[];
15
+ maxWidth: number;
16
+ ellipsisTagWidth: number;
17
+ setTakeCount: (count: number) => void;
18
+ }): void;
19
+ export declare function useSelectTriggerTags(props: UseSelectTriggerTagsProps): UseSelectTriggerTagsValue;
@@ -0,0 +1,61 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import take from 'lodash/take';
4
+ import Tag from '../Tag/Tag.js';
5
+
6
+ function calcTakeCount({ tagsWidths, maxWidth, ellipsisTagWidth, setTakeCount, }) {
7
+ let targetCount = 0;
8
+ for (let count = 0; count <= tagsWidths.length; count += 1) {
9
+ const prevTotal = take(tagsWidths, count).reduce((prev, curr) => prev + curr, 0);
10
+ const nowTotal = take(tagsWidths, count + 1).reduce((prev, curr) => prev + curr, 0);
11
+ targetCount = count;
12
+ if (prevTotal < maxWidth && nowTotal > maxWidth) {
13
+ if (prevTotal + ellipsisTagWidth > maxWidth) {
14
+ targetCount -= 1;
15
+ }
16
+ break;
17
+ }
18
+ }
19
+ setTakeCount(targetCount);
20
+ }
21
+ function useSelectTriggerTags(props) {
22
+ const { controlRef, value, size, } = props;
23
+ const [tagsWidths, setTagsWidths] = useState([]);
24
+ const [takeCount, setTakeCount] = useState(0);
25
+ const mznFakeTagClassName = 'mzn-fake-tag';
26
+ const mznFakeEllipsisTagClassName = 'mzn-fake-ellipsis-tag';
27
+ useEffect(() => {
28
+ var _a, _b, _c;
29
+ const elements = (_a = controlRef.current) === null || _a === void 0 ? void 0 : _a.getElementsByClassName(mznFakeTagClassName);
30
+ const ellipsisTagElement = (_b = controlRef.current) === null || _b === void 0 ? void 0 : _b.getElementsByClassName(mznFakeEllipsisTagClassName)[0];
31
+ if ((elements === null || elements === void 0 ? void 0 : elements.length) && ellipsisTagElement) {
32
+ const tagsWidthsArray = Array.from(elements).map((e) => e.clientWidth);
33
+ const parentWidth = ((_c = controlRef.current) === null || _c === void 0 ? void 0 : _c.clientWidth) || 0;
34
+ const maxWidth = parentWidth * 0.7;
35
+ const ellipsisTagWidth = ellipsisTagElement.clientWidth;
36
+ setTagsWidths(tagsWidthsArray);
37
+ calcTakeCount({
38
+ tagsWidths: tagsWidthsArray,
39
+ maxWidth,
40
+ ellipsisTagWidth,
41
+ setTakeCount,
42
+ });
43
+ }
44
+ }, [value, controlRef]);
45
+ const renderFakeTags = () => {
46
+ if (value && value.length === tagsWidths.length)
47
+ return null;
48
+ return (jsxs("div", { style: {
49
+ position: 'absolute',
50
+ visibility: 'hidden',
51
+ pointerEvents: 'none',
52
+ opacity: 0,
53
+ }, children: [value === null || value === void 0 ? void 0 : value.map((selection) => (jsx(Tag, { className: mznFakeTagClassName, closable: true, disabled: true, size: size, children: selection.name }, selection.id))), jsx(Tag, { disabled: true, className: mznFakeEllipsisTagClassName, size: size, children: "+99..." })] }));
54
+ };
55
+ return {
56
+ renderFakeTags,
57
+ takeCount,
58
+ };
59
+ }
60
+
61
+ export { calcTakeCount, useSelectTriggerTags };