@mezzanine-ui/react 0.13.1 → 0.13.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.
@@ -10,12 +10,15 @@ import cx from 'clsx';
10
10
  const Loading = forwardRef(function Loading(props, ref) {
11
11
  const hostRef = useRef(null);
12
12
  const { children, className, stretch = false, iconProps = {}, loading = false, overlayProps = {}, tip, tipClassName, } = props;
13
- const { className: iconClassName, color: iconColor, ...iconPropsRest } = iconProps;
13
+ const { className: iconClassName, color: iconColor, size: iconSize, style: iconStyle, ...iconPropsRest } = iconProps;
14
14
  const isNestedPattern = typeof children !== 'undefined';
15
15
  const composedHostRef = useComposeRefs([ref, hostRef]);
16
16
  const spinElement = loading ? (jsxs("div", { ref: isNestedPattern ? null : ref, className: cx(iconClasses.spin, {
17
17
  [iconClasses.stretch]: stretch,
18
- }), children: [jsx(Icon, { ...iconPropsRest, className: cx(iconClasses.icon, iconClassName), color: iconColor || 'primary', icon: SpinnerIcon, spin: true }), tip ? (jsx("span", { className: cx(iconClasses.tip, tipClassName), children: tip })) : null] })) : null;
18
+ }), children: [jsx(Icon, { ...iconPropsRest, className: cx(iconClasses.icon, iconClassName), color: iconColor || 'primary', icon: SpinnerIcon, spin: true, style: {
19
+ ...(iconSize ? { fontSize: `${iconSize}px` } : {}),
20
+ ...(iconStyle || {}),
21
+ } }), tip ? (jsx("span", { className: cx(iconClasses.tip, tipClassName), children: tip })) : null] })) : null;
19
22
  if (isNestedPattern) {
20
23
  return (jsxs("div", { ref: composedHostRef, className: cx(iconClasses.host, {
21
24
  [iconClasses.stretch]: stretch,
@@ -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' | 'readOnly' | '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' | 'onScroll' | 'readOnly' | 'renderValue' | 'value'>, FormElementFocusHandlers, PickRenameMulti<Pick<MenuProps, 'itemsInView' | 'maxHeight' | 'role' | 'size'>, {
10
10
  maxHeight: 'menuMaxHeight';
11
11
  role: 'menuRole';
12
12
  size: 'menuSize';
@@ -18,6 +18,13 @@ export interface SelectBaseProps extends Omit<SelectTriggerProps, 'active' | 'in
18
18
  * The other native props for input element.
19
19
  */
20
20
  inputProps?: Omit<SelectTriggerInputProps, 'onBlur' | 'onChange' | 'onFocus' | 'placeholder' | 'role' | 'value' | `aria-${'controls' | 'expanded' | 'owns'}`>;
21
+ /**
22
+ * Popup menu scroll listener
23
+ */
24
+ onMenuScroll?: (computed: {
25
+ scrollTop: number;
26
+ maxScrollTop: number;
27
+ }, target: HTMLUListElement) => void;
21
28
  /**
22
29
  * select input placeholder
23
30
  */
package/Select/Select.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { forwardRef, useContext, useState, useRef, useMemo } from 'react';
2
+ import { forwardRef, useContext, useState, useRef, useCallback, useMemo } from 'react';
3
3
  import { selectClasses } from '@mezzanine-ui/core/select';
4
4
  import isArray from 'lodash/isArray';
5
5
  import { useComposeRefs } from '../hooks/useComposeRefs.js';
@@ -16,7 +16,7 @@ const MENU_ID = 'mzn-select-menu-id';
16
16
  const Select = forwardRef(function Select(props, ref) {
17
17
  var _a, _b;
18
18
  const { disabled: disabledFromFormControl, fullWidth: fullWidthFromFormControl, required: requiredFromFormControl, severity, } = useContext(FormControlContext) || {};
19
- const { children, className, clearable = false, defaultValue, disabled = disabledFromFormControl || false, disablePortal = 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;
19
+ const { children, className, clearable = false, defaultValue, disabled = disabledFromFormControl || false, disablePortal = false, error = severity === 'error' || false, fullWidth = fullWidthFromFormControl || false, inputProps, inputRef, itemsInView = 4, menuMaxHeight, menuRole = 'listbox', menuSize, mode = 'single', onBlur, onChange: onChangeProp, onClear: onClearProp, onFocus, onMenuScroll, placeholder = '', popperOptions = {}, prefix, renderValue, required = requiredFromFormControl || false, size, suffixActionIcon, value: valueProp, } = props;
20
20
  const [open, toggleOpen] = useState(false);
21
21
  const onOpen = () => {
22
22
  onFocus === null || onFocus === void 0 ? void 0 : onFocus();
@@ -98,6 +98,17 @@ const Select = forwardRef(function Select(props, ref) {
98
98
  }
99
99
  }
100
100
  };
101
+ /** menu onScroll listener */
102
+ const onMenuScrollCallback = useCallback(async (evt) => {
103
+ if (onMenuScroll) {
104
+ const target = evt.target;
105
+ const maxScrollTop = target.scrollHeight - target.getBoundingClientRect().height;
106
+ onMenuScroll({
107
+ scrollTop: target.scrollTop,
108
+ maxScrollTop,
109
+ }, target);
110
+ }
111
+ }, [onMenuScroll]);
101
112
  const resolvedInputProps = {
102
113
  ...inputProps,
103
114
  'aria-controls': MENU_ID,
@@ -110,7 +121,7 @@ const Select = forwardRef(function Select(props, ref) {
110
121
  onChange,
111
122
  value,
112
123
  }), [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, disablePortal: disablePortal, open: open, options: popperOptions, sameWidth: true, 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 }) })] }) }));
124
+ 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, disablePortal: disablePortal, open: open, options: popperOptions, sameWidth: true, 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, onScroll: onMenuScrollCallback, role: menuRole, size: menuSize, style: { border: 0 }, children: children }) })] }) }));
114
125
  });
115
126
  var Select$1 = Select;
116
127
 
@@ -7,7 +7,7 @@ import { InputTriggerPopperProps } from '../_internal/InputTriggerPopper';
7
7
  import { SelectTriggerProps, SelectTriggerInputProps } from './SelectTrigger';
8
8
  import { SelectValue, TreeSelectOption } from './typings';
9
9
  import { TreeProps } from '../Tree';
10
- export interface TreeSelectProps extends Omit<SelectTriggerProps, 'active' | 'onBlur' | 'onChange' | 'onClear' | 'onClick' | 'onFocus' | 'onKeyDown' | 'readOnly' | 'searchInputProps'>, FormElementFocusHandlers, Pick<TreeProps, 'defaultExpandAll' | 'disabledValues' | 'expandControllerRef'>, PickRenameMulti<Pick<MenuProps, 'itemsInView' | 'maxHeight' | 'role' | 'size'>, {
10
+ export interface TreeSelectProps extends Omit<SelectTriggerProps, 'active' | 'onBlur' | 'onChange' | 'onClear' | 'onClick' | 'onFocus' | 'onKeyDown' | 'readOnly' | 'searchInputProps'>, FormElementFocusHandlers, Pick<TreeProps, 'defaultExpandAll' | 'disabledValues' | 'expandControllerRef' | 'onExpand'>, PickRenameMulti<Pick<MenuProps, 'itemsInView' | 'maxHeight' | 'role' | 'size'>, {
11
11
  maxHeight: 'menuMaxHeight';
12
12
  role: 'menuRole';
13
13
  size: 'menuSize';
@@ -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, mode = 'single', onBlur, onChange: onChangeProp, onFocus, options, placeholder = '', popperOptions, prefix, renderValue, required = requiredFromFormControl || false, sameWidth = false, size, 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, onExpand: onExpandProp, 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';
@@ -142,6 +142,7 @@ const TreeSelect = forwardRef((props, ref) => {
142
142
  return {
143
143
  label: option.name,
144
144
  value: option.id,
145
+ dynamicNodesFetching: option.dynamicChildrenFetching,
145
146
  nodes: (_a = option.siblings) === null || _a === void 0 ? void 0 : _a.map((sibling) => mapOptionToNode(sibling)),
146
147
  };
147
148
  }
@@ -186,6 +187,7 @@ const TreeSelect = forwardRef((props, ref) => {
186
187
  const onExpand = (value) => {
187
188
  const newExpandedValues = toggleValue(value, expandedValues);
188
189
  setExpandedValues(newExpandedValues);
190
+ onExpandProp === null || onExpandProp === void 0 ? void 0 : onExpandProp(value);
189
191
  };
190
192
  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: {
191
193
  ...restStyle,
@@ -3,6 +3,7 @@ export interface SelectValue {
3
3
  name: string;
4
4
  }
5
5
  export interface TreeSelectOption extends SelectValue {
6
+ dynamicChildrenFetching?: boolean;
6
7
  siblings?: TreeSelectOption[];
7
8
  }
8
9
  export interface SelectControl {
package/Tree/TreeNode.js CHANGED
@@ -4,6 +4,7 @@ import { CaretRightIcon } from '@mezzanine-ui/icons';
4
4
  import { forwardRef, useContext, useMemo } from 'react';
5
5
  import Typography from '../Typography/Typography.js';
6
6
  import { MezzanineConfig } from '../Provider/context.js';
7
+ import Loading from '../Loading/Loading.js';
7
8
  import Icon from '../Icon/Icon.js';
8
9
  import Checkbox from '../Checkbox/Checkbox.js';
9
10
  import Collapse from '../Transition/Collapse.js';
@@ -14,7 +15,7 @@ import cx from 'clsx';
14
15
  */
15
16
  const TreeNode = forwardRef(function TreeNode(props, ref) {
16
17
  const { size: globalSize, } = useContext(MezzanineConfig);
17
- const { children, className, disabled, expanded, indeterminate, label, multiple = false, onExpand: onExpandProp, onSelect: onSelectProp, selectable = false, selected, size = globalSize, value, ...restRootProps } = props;
18
+ const { children, className, disabled, dynamicNodesFetching, expanded, indeterminate, label, multiple = false, onExpand: onExpandProp, onSelect: onSelectProp, selectable = false, selected, size = globalSize, value, ...restRootProps } = props;
18
19
  const variant = useMemo(() => {
19
20
  if (size === 'small') {
20
21
  return 'input3';
@@ -26,7 +27,8 @@ const TreeNode = forwardRef(function TreeNode(props, ref) {
26
27
  }, [size]);
27
28
  const onExpand = onExpandProp ? () => { onExpandProp(value); } : undefined;
28
29
  const onSelect = selectable && onSelectProp && !disabled ? () => { onSelectProp(value); } : undefined;
29
- return (jsxs("li", { ref: ref, ...restRootProps, className: cx(treeClasses.node, treeClasses.nodeSize(size), className), children: [jsxs("div", { className: treeClasses.nodeStem, children: [children ? (jsx(Icon, { icon: CaretRightIcon, className: cx(treeClasses.nodeCaret, {
30
+ const mayHaveChildren = children || dynamicNodesFetching;
31
+ return (jsxs("li", { ref: ref, ...restRootProps, className: cx(treeClasses.node, treeClasses.nodeSize(size), className), children: [jsxs("div", { className: treeClasses.nodeStem, children: [mayHaveChildren ? (jsx(Icon, { icon: CaretRightIcon, className: cx(treeClasses.nodeCaret, {
30
32
  [treeClasses.nodeCaretExpanded]: expanded,
31
33
  }), role: "button", onClick: onExpand })) : (jsx("div", {})), multiple
32
34
  ? (jsx(Checkbox, { checked: !!selected, disabled: disabled, indeterminate: indeterminate, onChange: onSelect, size: size, value: `${value}`, children: label }))
@@ -35,7 +37,7 @@ const TreeNode = forwardRef(function TreeNode(props, ref) {
35
37
  [treeClasses.nodeLabelIndeterminate]: indeterminate,
36
38
  [treeClasses.nodeLabelActive]: selected,
37
39
  [treeClasses.nodeLabelDisabled]: disabled,
38
- }), children: label }))] }), children && (jsx(Collapse, { in: expanded, appear: false, children: children }))] }));
40
+ }), children: label }))] }), mayHaveChildren && (jsx(Collapse, { in: expanded, appear: false, children: children || jsx(Loading, { loading: true, iconProps: { size: 16 } }) }))] }));
39
41
  });
40
42
  var TreeNode$1 = TreeNode;
41
43
 
@@ -10,6 +10,6 @@ export interface UseTreeExpandedValueProps {
10
10
  }
11
11
  export declare function useTreeExpandedValue(props: UseTreeExpandedValueProps): {
12
12
  expandedValues: TreeNodeValue[];
13
- onExpand: (value: TreeNodeValue) => void;
13
+ onExpand: ((value: TreeNodeValue) => void) | undefined;
14
14
  setExpandedValues: import("react").Dispatch<import("react").SetStateAction<TreeNodeValue[]>>;
15
15
  };
@@ -21,10 +21,11 @@ function useTreeExpandedValue(props) {
21
21
  const onExpand = (value) => {
22
22
  const newExpandedValues = toggleValue(value, expandedValues);
23
23
  setExpandedValues(newExpandedValues);
24
+ onExpandProp === null || onExpandProp === void 0 ? void 0 : onExpandProp(value);
24
25
  };
25
26
  return {
26
27
  expandedValues: expandedValuesProp || expandedValues,
27
- onExpand: (expandedValuesProp && onExpandProp) ? onExpandProp : onExpand,
28
+ onExpand: expandedValuesProp ? onExpandProp : onExpand,
28
29
  setExpandedValues,
29
30
  };
30
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mezzanine-ui/react",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "React components for mezzanine-ui",
5
5
  "author": "Mezzanine",
6
6
  "repository": {
@@ -31,9 +31,9 @@
31
31
  "react-dom": "^18.2.0"
32
32
  },
33
33
  "dependencies": {
34
- "@mezzanine-ui/core": "^0.13.1",
35
- "@mezzanine-ui/icons": "^0.13.1",
36
- "@mezzanine-ui/system": "^0.13.1",
34
+ "@mezzanine-ui/core": "^0.13.2",
35
+ "@mezzanine-ui/icons": "^0.13.2",
36
+ "@mezzanine-ui/system": "^0.13.2",
37
37
  "@popperjs/core": "^2.11.6",
38
38
  "@types/react-transition-group": "^4.4.5",
39
39
  "clsx": "^1.2.1",