@mezzanine-ui/react 1.0.0-canary.2 → 1.0.0-canary.3

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 (113) hide show
  1. package/AlertBanner/AlertBanner.d.ts +93 -0
  2. package/AlertBanner/AlertBanner.js +135 -0
  3. package/AlertBanner/index.d.ts +2 -0
  4. package/AlertBanner/index.js +1 -0
  5. package/{Overlay/Overlay.d.ts → Backdrop/Backdrop.d.ts} +12 -16
  6. package/Backdrop/Backdrop.js +33 -0
  7. package/Backdrop/index.d.ts +2 -0
  8. package/Backdrop/index.js +1 -0
  9. package/Badge/Badge.d.ts +20 -14
  10. package/Badge/Badge.js +14 -16
  11. package/Badge/BadgeContainer.d.ts +1 -1
  12. package/Badge/BadgeContainer.js +1 -1
  13. package/Badge/index.d.ts +1 -2
  14. package/Badge/typings.d.ts +42 -0
  15. package/Button/Button.js +2 -2
  16. package/Calendar/CalendarContext.js +1 -1
  17. package/DismissButton/DismissButton.d.ts +34 -0
  18. package/DismissButton/DismissButton.js +19 -0
  19. package/DismissButton/index.d.ts +3 -0
  20. package/DismissButton/index.js +5 -0
  21. package/Drawer/Drawer.js +2 -2
  22. package/Dropdown/Dropdown.js +12 -22
  23. package/InlineMessage/InlineMessage.d.ts +33 -0
  24. package/InlineMessage/InlineMessage.js +37 -0
  25. package/InlineMessage/InlineMessageGroup.d.ts +24 -0
  26. package/InlineMessage/InlineMessageGroup.js +21 -0
  27. package/InlineMessage/index.d.ts +4 -0
  28. package/InlineMessage/index.js +2 -0
  29. package/Message/Message.d.ts +4 -2
  30. package/Message/Message.js +85 -8
  31. package/Message/MessageTimerController.d.ts +14 -0
  32. package/Message/MessageTimerController.js +27 -0
  33. package/Modal/Modal.js +2 -2
  34. package/Modal/useModalContainer.d.ts +1 -1
  35. package/Modal/useModalContainer.js +2 -4
  36. package/Navigation/NavigationSubMenu.js +15 -26
  37. package/Notifier/NotifierManager.d.ts +15 -2
  38. package/Notifier/NotifierManager.js +60 -18
  39. package/Notifier/createNotifier.d.ts +9 -0
  40. package/Notifier/createNotifier.js +3 -2
  41. package/Notifier/typings.d.ts +3 -1
  42. package/PageFooter/PageFooter.d.ts +58 -8
  43. package/PageFooter/PageFooter.js +34 -3
  44. package/Popover/Popover.js +4 -8
  45. package/Popper/Popper.d.ts +15 -10
  46. package/Popper/Popper.js +88 -17
  47. package/Popper/index.d.ts +1 -1
  48. package/Portal/Portal.d.ts +13 -5
  49. package/Portal/Portal.js +25 -10
  50. package/Portal/index.d.ts +2 -0
  51. package/Portal/index.js +1 -0
  52. package/Portal/portalRegistry.d.ts +17 -0
  53. package/Portal/portalRegistry.js +99 -0
  54. package/Provider/ConfigProvider.d.ts +1 -0
  55. package/Provider/ConfigProvider.js +1 -0
  56. package/ResultState/ResultState.d.ts +36 -0
  57. package/ResultState/ResultState.js +24 -0
  58. package/ResultState/index.d.ts +2 -0
  59. package/ResultState/index.js +1 -0
  60. package/Skeleton/Skeleton.d.ts +10 -3
  61. package/Skeleton/Skeleton.js +12 -4
  62. package/Spin/Spin.d.ts +39 -0
  63. package/{Loading/Loading.js → Spin/Spin.js} +8 -8
  64. package/Spin/index.d.ts +2 -0
  65. package/Spin/index.js +1 -0
  66. package/Stepper/Step.d.ts +1 -35
  67. package/Stepper/Step.js +43 -10
  68. package/Stepper/Stepper.d.ts +1 -14
  69. package/Stepper/Stepper.js +49 -15
  70. package/Stepper/index.d.ts +3 -2
  71. package/Stepper/index.js +1 -0
  72. package/Stepper/typings.d.ts +77 -0
  73. package/Stepper/useStepDistance.d.ts +10 -0
  74. package/Stepper/useStepDistance.js +81 -0
  75. package/Stepper/useStepper.d.ts +21 -0
  76. package/Stepper/useStepper.js +26 -0
  77. package/Table/Table.js +2 -2
  78. package/Table/TableBody.js +2 -2
  79. package/Tag/Tag.d.ts +2 -25
  80. package/Tag/Tag.js +14 -13
  81. package/Tag/index.d.ts +1 -1
  82. package/Tag/typings.d.ts +79 -0
  83. package/Toggle/Toggle.d.ts +46 -0
  84. package/Toggle/Toggle.js +29 -0
  85. package/Toggle/index.d.ts +3 -0
  86. package/Toggle/index.js +1 -0
  87. package/Tooltip/Tooltip.d.ts +13 -2
  88. package/Tooltip/Tooltip.js +48 -10
  89. package/Tooltip/useDelayMouseEnterLeave.d.ts +1 -2
  90. package/Tooltip/useDelayMouseEnterLeave.js +0 -4
  91. package/Tree/TreeNode.js +5 -5
  92. package/_internal/InputTriggerPopper/InputTriggerPopper.js +14 -24
  93. package/_internal/SlideFadeOverlay/SlideFadeOverlay.d.ts +2 -2
  94. package/_internal/SlideFadeOverlay/SlideFadeOverlay.js +4 -27
  95. package/hooks/useScrollLock.d.ts +28 -0
  96. package/hooks/useScrollLock.js +134 -0
  97. package/index.d.ts +87 -80
  98. package/index.js +74 -69
  99. package/package.json +7 -7
  100. package/utils/get-css-variable-value.d.ts +1 -0
  101. package/utils/get-css-variable-value.js +9 -0
  102. package/Loading/Loading.d.ts +0 -33
  103. package/Loading/index.d.ts +0 -2
  104. package/Loading/index.js +0 -1
  105. package/Overlay/Overlay.js +0 -31
  106. package/Overlay/index.d.ts +0 -2
  107. package/Overlay/index.js +0 -1
  108. package/Switch/Switch.d.ts +0 -43
  109. package/Switch/Switch.js +0 -29
  110. package/Switch/index.d.ts +0 -3
  111. package/Switch/index.js +0 -1
  112. package/utils/scroll-lock.d.ts +0 -2
  113. package/utils/scroll-lock.js +0 -24
package/Tag/Tag.d.ts CHANGED
@@ -1,29 +1,6 @@
1
- import { MouseEventHandler } from 'react';
2
- import { TagSize } from '@mezzanine-ui/core/tag';
3
- import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
4
- export interface TagProps extends NativeElementPropsWithoutKeyAndRef<'span'> {
5
- /**
6
- * Whether the tag can be closed.
7
- * @default false
8
- */
9
- closable?: boolean;
10
- /**
11
- * Whether the tag disabled.
12
- * @default false
13
- */
14
- disabled?: boolean;
15
- /**
16
- * Callback executed while tag closed.
17
- */
18
- onClose?: MouseEventHandler;
19
- /**
20
- * The size of the tag.
21
- * @default 'medium'
22
- */
23
- size?: TagSize;
24
- }
1
+ import { TagProps } from './typings';
25
2
  /**
26
3
  * The react component for `mezzanine` tag.
27
4
  */
28
- declare const Tag: import("react").ForwardRefExoticComponent<TagProps & import("react").RefAttributes<HTMLSpanElement>>;
5
+ declare const Tag: import("react").ForwardRefExoticComponent<TagProps & import("react").RefAttributes<HTMLButtonElement | HTMLSpanElement>>;
29
6
  export default Tag;
package/Tag/Tag.js CHANGED
@@ -1,25 +1,26 @@
1
1
  'use client';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { forwardRef, useContext } from 'react';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { forwardRef } from 'react';
4
4
  import { tagClasses } from '@mezzanine-ui/core/tag';
5
- import { TimesIcon } from '@mezzanine-ui/icons';
6
- import { MezzanineConfig } from '../Provider/context.js';
5
+ import { PlusIcon, CloseIcon } from '@mezzanine-ui/icons';
7
6
  import Icon from '../Icon/Icon.js';
7
+ import Badge from '../Badge/Badge.js';
8
8
  import cx from 'clsx';
9
9
 
10
10
  /**
11
11
  * The react component for `mezzanine` tag.
12
12
  */
13
13
  const Tag = forwardRef(function Tag(props, ref) {
14
- const { size: globalSize } = useContext(MezzanineConfig);
15
- const { children, className, closable = false, disabled = false, onClose, size = globalSize, ...rest } = props;
16
- return (jsxs("span", { ...rest, ref: ref, "aria-disabled": disabled, className: cx(tagClasses.host, tagClasses.size(size), {
17
- [tagClasses.disabled]: disabled,
18
- }, className), children: [jsx("span", { className: tagClasses.label, children: children }), closable && (jsx(Icon, { className: tagClasses.closeIcon, icon: TimesIcon, onClick: (event) => {
19
- if (!disabled && onClose) {
20
- onClose(event);
21
- }
22
- }, tabIndex: -1 }))] }));
14
+ const { active, className, count, disabled, label, onAdd, onClose, readOnly, size = 'main', type, ...rest } = props;
15
+ const commonClassName = cx(tagClasses.host, tagClasses.size(size), tagClasses.type(type), {
16
+ [tagClasses.disabled]: disabled,
17
+ [tagClasses.active]: active,
18
+ [tagClasses.readOnly]: readOnly,
19
+ }, className);
20
+ if (type === 'addable') {
21
+ return (jsxs("button", { ...rest, ref: ref, type: "button", onClick: onAdd, disabled: disabled, className: commonClassName, children: [jsx(Icon, { className: tagClasses.icon, icon: PlusIcon, size: 16 }), jsx("span", { className: tagClasses.label, children: label })] }));
22
+ }
23
+ return (jsxs("span", { ...rest, ref: ref, "aria-disabled": disabled, className: commonClassName, children: [type === 'static' && jsx("span", { className: tagClasses.label, children: label }), type === 'counter' && (jsxs(Fragment, { children: [jsx("span", { className: tagClasses.label, children: label }), jsx(Badge, { variant: "count-info", count: count })] })), type === 'overflow-counter' && (jsxs(Fragment, { children: [jsx(Icon, { className: tagClasses.icon, icon: PlusIcon, size: 16 }), jsx("span", { className: tagClasses.label, children: count })] })), type === 'dismissable' && (jsxs(Fragment, { children: [jsx("span", { className: tagClasses.label, children: label }), !readOnly && (jsx("button", { className: tagClasses.closeButton, type: "button", onClick: onClose, "aria-label": "Dismiss tag", disabled: disabled, children: jsx(Icon, { className: tagClasses.icon, icon: CloseIcon, size: 16 }) }))] }))] }));
23
24
  });
24
25
 
25
26
  export { Tag as default };
package/Tag/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export type { TagSize } from '@mezzanine-ui/core/tag';
2
- export type { TagProps } from './Tag';
2
+ export type { TagProps } from './typings';
3
3
  export { default } from './Tag';
@@ -0,0 +1,79 @@
1
+ import { TagSize, TagType } from '@mezzanine-ui/core/tag';
2
+ import { MouseEventHandler } from 'react';
3
+ import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
4
+ /**
5
+ * Props for the Tag component covering static, counter, overflow, dismissable, and addable variants.
6
+ */
7
+ export type TagProps = TagPropsShared & (TagPropsStatic | TagPropsCounter | TagPropsOverflowCounter | TagPropsDismissable | TagPropsAddable);
8
+ type TagPropsShared = NativeElementPropsWithoutKeyAndRef<'span'> & {
9
+ /** Custom class names on the host element. */
10
+ className?: string;
11
+ /** Active state. Only available on dismissable/addable tags. */
12
+ active?: boolean;
13
+ /** Disabled state. Only available on dismissable/addable tags. */
14
+ disabled?: boolean;
15
+ /** Text rendered inside label-based tags. */
16
+ label?: string;
17
+ /** Numeric value displayed by counter and overflow-counter variants. */
18
+ count?: number;
19
+ /** Handler fired when the addable tag is clicked. */
20
+ onAdd?: () => void;
21
+ /** Handler fired when the close button is clicked. */
22
+ onClose?: MouseEventHandler;
23
+ /** Applies read-only styling for dismissable tags. */
24
+ readOnly?: boolean;
25
+ /**
26
+ * Size of the tag.
27
+ * @default main
28
+ */
29
+ size?: TagSize;
30
+ /**
31
+ * Type of the tag.
32
+ */
33
+ type: TagType;
34
+ };
35
+ type TagPropsStatic = {
36
+ active?: never;
37
+ count?: never;
38
+ disabled?: never;
39
+ onAdd?: never;
40
+ onClose?: never;
41
+ readOnly?: never;
42
+ label: string;
43
+ type: 'static';
44
+ };
45
+ type TagPropsCounter = {
46
+ active?: never;
47
+ disabled?: never;
48
+ onAdd?: never;
49
+ onClose?: never;
50
+ readOnly?: never;
51
+ label: string;
52
+ count: number;
53
+ type: 'counter';
54
+ };
55
+ type TagPropsOverflowCounter = {
56
+ active?: never;
57
+ disabled?: never;
58
+ label?: never;
59
+ onAdd?: never;
60
+ onClose?: never;
61
+ readOnly?: never;
62
+ count: number;
63
+ type: 'overflow-counter';
64
+ };
65
+ type TagPropsDismissable = {
66
+ count?: never;
67
+ onAdd?: never;
68
+ label: string;
69
+ onClose: MouseEventHandler;
70
+ type: 'dismissable';
71
+ };
72
+ type TagPropsAddable = {
73
+ count?: never;
74
+ onClose?: never;
75
+ readOnly?: never;
76
+ label: string;
77
+ type: 'addable';
78
+ };
79
+ export {};
@@ -0,0 +1,46 @@
1
+ import { ChangeEventHandler } from 'react';
2
+ import { ToggleSize } from '@mezzanine-ui/core/toggle';
3
+ import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
4
+ export interface ToggleProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'onChange'> {
5
+ /**
6
+ * Whether the toggle is checked.
7
+ */
8
+ checked?: boolean;
9
+ /**
10
+ * Whether the toggle is checked by default.
11
+ * Only used for uncontrolled.
12
+ */
13
+ defaultChecked?: boolean;
14
+ /**
15
+ * Whether the toggle is disabled.
16
+ * @default false
17
+ */
18
+ disabled?: boolean;
19
+ /**
20
+ * Since at Mezzanine we use a host element to wrap our input, most derived props will be passed to the host element.
21
+ * If you need direct control to the input element, use this prop to provide to it.
22
+ */
23
+ inputProps?: Omit<NativeElementPropsWithoutKeyAndRef<'input'>, 'checked' | 'defaultChecked' | 'disabled' | 'onChange' | 'placeholder' | 'type' | 'value' | `aria-${'disabled' | 'checked'}`>;
24
+ /**
25
+ * The label text displayed beside the toggle.
26
+ */
27
+ label?: string;
28
+ /**
29
+ * Invoked by input change event.
30
+ */
31
+ onChange?: ChangeEventHandler<HTMLInputElement>;
32
+ /**
33
+ * The size of toggle.
34
+ * @default 'main'
35
+ */
36
+ size?: ToggleSize;
37
+ /**
38
+ * Supporting text displayed below the label.
39
+ */
40
+ supportingText?: string;
41
+ }
42
+ /**
43
+ * The react component for `mezzanine` toggle.
44
+ */
45
+ declare const Toggle: import("react").ForwardRefExoticComponent<ToggleProps & import("react").RefAttributes<HTMLDivElement>>;
46
+ export default Toggle;
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useContext } from 'react';
4
+ import { toggleClasses } from '@mezzanine-ui/core/toggle';
5
+ import { useSwitchControlValue } from '../Form/useSwitchControlValue.js';
6
+ import Typography from '../Typography/Typography.js';
7
+ import { FormControlContext } from '../Form/FormControlContext.js';
8
+ import cx from 'clsx';
9
+
10
+ /**
11
+ * The react component for `mezzanine` toggle.
12
+ */
13
+ const Toggle = forwardRef(function Toggle(props, ref) {
14
+ const { disabled: disabledFromFormControl } = useContext(FormControlContext) || {};
15
+ const { checked: checkedProp, className, defaultChecked, disabled = disabledFromFormControl, inputProps, label, onChange: onChangeProp, size = 'main', supportingText, ...rest } = props;
16
+ const [checked, onChange] = useSwitchControlValue({
17
+ checked: checkedProp,
18
+ defaultChecked,
19
+ onChange: onChangeProp,
20
+ });
21
+ return (jsxs("div", { ref: ref, ...rest, className: cx(toggleClasses.host, {
22
+ [toggleClasses.checked]: checked,
23
+ [toggleClasses.disabled]: disabled,
24
+ [toggleClasses.main]: size === 'main',
25
+ [toggleClasses.sub]: size === 'sub',
26
+ }, className), children: [jsxs("div", { className: toggleClasses.inputContainer, children: [jsx("span", { className: toggleClasses.knob }), jsx("input", { ...inputProps, "aria-checked": checked, "aria-disabled": disabled, checked: checked, className: toggleClasses.input, disabled: disabled, onChange: onChange, type: "checkbox" })] }), label && (jsxs("div", { className: toggleClasses.textContainer, children: [jsx(Typography, { color: "text-neutral-solid", variant: "label-primary", children: label }), supportingText && (jsx(Typography, { color: "text-neutral", variant: "caption", children: supportingText }))] }))] }));
27
+ });
28
+
29
+ export { Toggle as default };
@@ -0,0 +1,3 @@
1
+ export type { ToggleSize } from '@mezzanine-ui/core/toggle';
2
+ export type { ToggleProps } from './Toggle';
3
+ export { default } from './Toggle';
@@ -0,0 +1 @@
1
+ export { default } from './Toggle.js';
@@ -1,13 +1,24 @@
1
1
  import { ReactElement, MouseEventHandler, ReactNode } from 'react';
2
2
  import { PopperProps } from '../Popper';
3
- export interface TooltipProps extends Omit<PopperProps, 'children' | 'title'> {
3
+ export interface TooltipProps extends Omit<PopperProps, 'arrow' | 'children' | 'disablePortal' | 'title'> {
4
4
  /**
5
- * child function that can receive events
5
+ * show arrow or not
6
+ * @default true
7
+ */
8
+ arrow?: boolean;
9
+ /**
10
+ * child function that can receive events and ref
6
11
  */
7
12
  children(opt: {
8
13
  onMouseEnter: MouseEventHandler;
9
14
  onMouseLeave: MouseEventHandler;
15
+ ref: React.RefCallback<HTMLElement>;
10
16
  }): ReactElement<any>;
17
+ /**
18
+ * Whether to disable portal. If true, it will be a normal component.
19
+ * @default true
20
+ */
21
+ disablePortal?: boolean;
11
22
  /**
12
23
  * delay time to hide when mouse leave. unit: s.
13
24
  * @default 0.1
@@ -1,28 +1,66 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { forwardRef, useRef } from 'react';
2
+ import { forwardRef, useRef, useState, useCallback } from 'react';
3
3
  import { tooltipClasses } from '@mezzanine-ui/core/tooltip';
4
+ import { offset, flip, shift } from '@floating-ui/react-dom';
5
+ import { spacingPrefix } from '@mezzanine-ui/system/spacing';
4
6
  import { useComposeRefs } from '../hooks/useComposeRefs.js';
5
7
  import { useDelayMouseEnterLeave } from './useDelayMouseEnterLeave.js';
8
+ import { getCSSVariableValue } from '../utils/get-css-variable-value.js';
6
9
  import Popper from '../Popper/Popper.js';
7
10
  import cx from 'clsx';
8
11
 
9
- const offsetModifier = {
10
- name: 'offset',
11
- options: { offset: [0, 8] },
12
- };
13
12
  /**
14
13
  * The react component for `mezzanine` tooltip.
15
14
  */
16
15
  const Tooltip = forwardRef(function Tooltip(props, ref) {
17
- const { anchor: anchorProp, children, className, mouseLeaveDelay = 0.1, open = false, options = {}, title, ...rest } = props;
18
- const { modifiers = [] } = options;
16
+ const { anchor: anchorProp, arrow: showArrow = true, children, className, disablePortal = true, mouseLeaveDelay = 0.1, open = false, options = {}, title, ...rest } = props;
17
+ const { middleware: middlewareProp = [] } = options;
19
18
  const tooltipRef = useRef(null);
19
+ const [targetRef, _setTargetRef] = useState({
20
+ current: null,
21
+ });
20
22
  const composedRef = useComposeRefs([ref, tooltipRef]);
21
- const { anchor, onLeave, onPopperEnter, onTargetEnter, visible } = useDelayMouseEnterLeave({ mouseLeaveDelay });
23
+ const { onLeave, onPopperEnter, onTargetEnter, visible } = useDelayMouseEnterLeave({ mouseLeaveDelay });
22
24
  /** tooltip shown only when title existed && visible is true */
23
25
  const isTooltipVisible = open || (visible && Boolean(title));
24
- return (jsxs(Fragment, { children: [jsx(Popper, { ...rest, ref: composedRef, anchor: anchorProp || anchor, className: cx(tooltipClasses.host, className), onMouseEnter: onPopperEnter, onMouseLeave: onLeave, open: isTooltipVisible, options: { ...options, modifiers: [...modifiers, offsetModifier] }, children: title }), typeof children === 'function' &&
25
- children({ onMouseEnter: onTargetEnter, onMouseLeave: onLeave })] }));
26
+ const offsetValue = Number(getCSSVariableValue(`--${spacingPrefix}-gap-base`).replace('rem', '')) * 16;
27
+ const placement = options.placement || 'top';
28
+ const isPlacementAtEdge = placement.endsWith('-start') || placement.endsWith('-end');
29
+ // 設置 target element,並重新渲染
30
+ const setTargetRef = useCallback((element) => {
31
+ _setTargetRef({ current: element });
32
+ }, []);
33
+ // middleware (shift, flip 會衝突,所以依照官方推薦設定 https://floating-ui.com/docs/flip#combining-with-shift)
34
+ const middleware = [offset({ mainAxis: offsetValue })];
35
+ const flipMiddleware = flip({
36
+ crossAxis: 'alignment',
37
+ fallbackAxisSideDirection: 'end',
38
+ });
39
+ const shiftMiddleware = shift();
40
+ if (placement.includes('-')) {
41
+ middleware.push(flipMiddleware, shiftMiddleware);
42
+ }
43
+ else {
44
+ middleware.push(shiftMiddleware, flipMiddleware);
45
+ }
46
+ return (jsxs(Fragment, { children: [jsx(Popper, { ...rest, ref: composedRef, anchor: anchorProp || targetRef.current, arrow: showArrow
47
+ ? {
48
+ className: tooltipClasses.arrow,
49
+ enabled: true,
50
+ padding: isPlacementAtEdge
51
+ ? Number(getCSSVariableValue(`--${spacingPrefix}-padding-horizontal-comfort`).replace('rem', '')) * 16
52
+ : 0,
53
+ }
54
+ : undefined, className: cx(tooltipClasses.host, className), disablePortal: disablePortal, onMouseEnter: onPopperEnter, onMouseLeave: onLeave, open: isTooltipVisible, options: {
55
+ ...options,
56
+ placement,
57
+ middleware: [...middleware, ...middlewareProp],
58
+ }, children: title }), typeof children === 'function' &&
59
+ children({
60
+ onMouseEnter: onTargetEnter,
61
+ onMouseLeave: onLeave,
62
+ ref: setTargetRef,
63
+ })] }));
26
64
  });
27
65
 
28
66
  export { Tooltip as default };
@@ -2,10 +2,9 @@ export interface UseDelayMouseEnterLeave {
2
2
  mouseLeaveDelay?: number;
3
3
  }
4
4
  export interface DelayMouseEnterLeave {
5
- anchor: HTMLButtonElement | null;
6
5
  onLeave(v: any): void;
7
6
  onPopperEnter(v: any): void;
8
- onTargetEnter(v: React.MouseEvent<HTMLButtonElement, MouseEvent>): void;
7
+ onTargetEnter(v: React.MouseEvent<HTMLElement, MouseEvent>): void;
9
8
  visible: boolean;
10
9
  }
11
10
  export declare function useDelayMouseEnterLeave(opt: UseDelayMouseEnterLeave): DelayMouseEnterLeave;
@@ -4,8 +4,6 @@ function useDelayMouseEnterLeave(opt) {
4
4
  const { mouseLeaveDelay = 0.1 } = opt || {};
5
5
  /** state that control tooltip visible/invisible */
6
6
  const [visible, setVisible] = useState(false);
7
- /** tooltip reference anchor */
8
- const [anchor, setAnchor] = useState(null);
9
7
  /** timer for mouse leaving delay - use ref to persist across renders */
10
8
  const timerRef = useRef(null);
11
9
  const clearVisibilityDelayTimeout = useCallback(() => {
@@ -26,12 +24,10 @@ function useDelayMouseEnterLeave(opt) {
26
24
  }, [clearVisibilityDelayTimeout]);
27
25
  const onTargetEnter = useCallback((event) => {
28
26
  event.stopPropagation();
29
- setAnchor(event.currentTarget);
30
27
  clearVisibilityDelayTimeout();
31
28
  setVisible(true);
32
29
  }, [clearVisibilityDelayTimeout]);
33
30
  return {
34
- anchor,
35
31
  onLeave,
36
32
  onPopperEnter,
37
33
  onTargetEnter,
package/Tree/TreeNode.js CHANGED
@@ -5,7 +5,7 @@ import { CaretRightIcon } from '@mezzanine-ui/icons';
5
5
  import { forwardRef, useContext, useMemo } from 'react';
6
6
  import Typography from '../Typography/Typography.js';
7
7
  import { MezzanineConfig } from '../Provider/context.js';
8
- import Loading from '../Loading/Loading.js';
8
+ import Spin from '../Spin/Spin.js';
9
9
  import Icon from '../Icon/Icon.js';
10
10
  import Checkbox from '../Checkbox/Checkbox.js';
11
11
  import Collapse from '../Transition/Collapse.js';
@@ -19,12 +19,12 @@ const TreeNode = forwardRef(function TreeNode(props, ref) {
19
19
  const { children, className, disabled, dynamicNodesFetching, expanded, indeterminate, label, multiple = false, onExpand: onExpandProp, onSelect: onSelectProp, selectable = false, selected, size = globalSize, value, ...restRootProps } = props;
20
20
  const variant = useMemo(() => {
21
21
  if (size === 'small') {
22
- return 'input3';
22
+ return 'input';
23
23
  }
24
24
  if (size === 'large') {
25
- return 'input1';
25
+ return 'input';
26
26
  }
27
- return 'input2';
27
+ return 'input';
28
28
  }, [size]);
29
29
  const onExpand = onExpandProp
30
30
  ? () => {
@@ -44,7 +44,7 @@ const TreeNode = forwardRef(function TreeNode(props, ref) {
44
44
  [treeClasses.nodeLabelIndeterminate]: indeterminate,
45
45
  [treeClasses.nodeLabelActive]: selected,
46
46
  [treeClasses.nodeLabelDisabled]: disabled,
47
- }), children: label }))] }), mayHaveChildren && (jsx(Collapse, { in: expanded, appear: false, children: children || jsx(Loading, { loading: true, iconProps: { size: 16 } }) }))] }));
47
+ }), children: label }))] }), mayHaveChildren && (jsx(Collapse, { in: expanded, appear: false, children: children || jsx(Spin, { loading: true, iconProps: { size: 16 } }) }))] }));
48
48
  });
49
49
 
50
50
  export { TreeNode as default };
@@ -1,44 +1,34 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { inputTriggerPopperClasses } from '@mezzanine-ui/core/_internal/input-trigger-popper';
3
+ import { offset, size } from '@floating-ui/react-dom';
3
4
  import { forwardRef } from 'react';
4
5
  import Fade from '../../Transition/Fade.js';
5
6
  import Popper from '../../Popper/Popper.js';
6
7
  import cx from 'clsx';
7
8
 
9
+ // Middleware to make the popper have the same min-width as the reference element
10
+ const sameWidthMiddleware = size({
11
+ apply({ rects, elements }) {
12
+ Object.assign(elements.floating.style, {
13
+ minWidth: `${rects.reference.width}px`,
14
+ });
15
+ },
16
+ });
8
17
  /**
9
18
  * The react component for `mezzanine` input popper.
10
19
  */
11
20
  const InputTriggerPopper = forwardRef(function InputTriggerPopper(props, ref) {
12
21
  const { anchor, children, className, fadeProps, open, options, sameWidth, ...restPopperProps } = props;
13
- const { modifiers = [], ...restPopperOptions } = options || {};
14
- const sameWidthModifier = {
15
- name: 'sameWidth',
16
- enabled: true,
17
- phase: 'beforeWrite',
18
- requires: ['computeStyles'],
19
- fn: ({ state }) => {
20
- const reassignState = state;
21
- reassignState.styles.popper.minWidth = `${state.rects.reference.width}px`;
22
- },
23
- effect: ({ state }) => {
24
- const reassignState = state;
25
- reassignState.elements.popper.style.minWidth = `${state.elements.reference.getBoundingClientRect().width}px`;
26
- },
27
- };
22
+ const { middleware = [], ...restPopperOptions } = options || {};
28
23
  return (jsx(Fade, { ...fadeProps, in: open, ref: ref, children: jsx(Popper, { ...restPopperProps, open: true, anchor: anchor, className: cx(inputTriggerPopperClasses.host, className),
29
24
  /** Prevent event bubble (Because popper may use portal, then click away function would be buggy) */
30
25
  onClick: (e) => e.stopPropagation(), onTouchStart: (e) => e.stopPropagation(), onTouchMove: (e) => e.stopPropagation(), onTouchEnd: (e) => e.stopPropagation(), options: {
31
26
  placement: 'bottom-start',
32
27
  ...restPopperOptions,
33
- modifiers: [
34
- {
35
- name: 'offset',
36
- options: {
37
- offset: [0, 4],
38
- },
39
- },
40
- ...(sameWidth ? [sameWidthModifier] : []),
41
- ...modifiers,
28
+ middleware: [
29
+ offset({ mainAxis: 4 }),
30
+ ...(sameWidth ? [sameWidthMiddleware] : []),
31
+ ...middleware,
42
32
  ],
43
33
  }, children: children }) }));
44
34
  });
@@ -1,7 +1,7 @@
1
1
  import { NativeElementPropsWithoutKeyAndRef } from '../../utils/jsx-types';
2
- import { OverlayProps } from '../../Overlay';
2
+ import { BackdropProps } from '../../Backdrop';
3
3
  import { SlideFadeProps, SlideFadeDirection } from '../../Transition';
4
- export interface SlideFadeOverlayProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'children'>, Pick<OverlayProps, 'container' | 'disableCloseOnBackdropClick' | 'disablePortal' | 'invisibleBackdrop' | 'hideBackdrop' | 'onBackdropClick' | 'onClose' | 'open'>, Pick<SlideFadeProps, 'children'> {
4
+ export interface SlideFadeOverlayProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'children'>, Pick<BackdropProps, 'container' | 'disableCloseOnBackdropClick' | 'disablePortal' | 'onBackdropClick' | 'onClose' | 'open'>, Pick<SlideFadeProps, 'children'> {
5
5
  /**
6
6
  * Control slide fade in direction
7
7
  * @default 'down'
@@ -1,10 +1,9 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { overlayWithSlideFadeClasses } from '@mezzanine-ui/core/_internal/overlay-with-slide-fade';
3
- import { forwardRef, useState, useEffect } from 'react';
3
+ import { forwardRef, useState } from 'react';
4
4
  import { useDocumentEscapeKeyDown } from '../../hooks/useDocumentEscapeKeyDown.js';
5
- import { lockBodyScroll, allowBodyScroll } from '../../utils/scroll-lock.js';
6
5
  import useTopStack from './useTopStack.js';
7
- import Overlay from '../../Overlay/Overlay.js';
6
+ import Backdrop from '../../Backdrop/Backdrop.js';
8
7
  import SlideFade from '../../Transition/SlideFade.js';
9
8
  import cx from 'clsx';
10
9
 
@@ -12,7 +11,7 @@ import cx from 'clsx';
12
11
  * The react component for slide fade + overlay compose
13
12
  */
14
13
  const SlideFadeOverlay = forwardRef(function SlideFadeOverlay(props, ref) {
15
- const { children, className, container, direction = 'down', disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, hideBackdrop = false, invisibleBackdrop = false, onBackdropClick, onClose, open, } = props;
14
+ const { children, className, container, direction = 'down', disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, onBackdropClick, onClose, open, } = props;
16
15
  const [exited, setExited] = useState(true);
17
16
  /**
18
17
  * Escape keydown close: escape will only close the top modal
@@ -29,32 +28,10 @@ const SlideFadeOverlay = forwardRef(function SlideFadeOverlay(props, ref) {
29
28
  }
30
29
  };
31
30
  }, [disableCloseOnEscapeKeyDown, checkIsOnTheTop, open, onClose]);
32
- /** lock body scroll */
33
- useEffect(() => {
34
- if (open) {
35
- lockBodyScroll();
36
- }
37
- }, [open]);
38
- /** unlock body scroll */
39
- useEffect(() => {
40
- function checkAndAllowScroll() {
41
- // wait until dom element unmount, and check if other modal existed
42
- const allStacks = document.querySelectorAll('.mzn-overlay-with-slide-fade');
43
- if (!allStacks.length) {
44
- allowBodyScroll();
45
- }
46
- }
47
- if (!open && exited) {
48
- checkAndAllowScroll();
49
- }
50
- return () => {
51
- requestAnimationFrame(checkAndAllowScroll);
52
- };
53
- }, [open, exited]);
54
31
  if (!open && exited) {
55
32
  return null;
56
33
  }
57
- return (jsx(Overlay, { className: cx(overlayWithSlideFadeClasses.host, className), container: container, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disablePortal: disablePortal, hideBackdrop: hideBackdrop, invisibleBackdrop: invisibleBackdrop, onBackdropClick: onBackdropClick, onClose: onClose, open: open, role: "presentation", children: jsx(SlideFade, { ref: ref, in: open, direction: direction, onEntered: () => setExited(false), onExited: () => setExited(true), children: children }) }));
34
+ return (jsx(Backdrop, { className: cx(overlayWithSlideFadeClasses.host, className), container: container, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disablePortal: disablePortal, onBackdropClick: onBackdropClick, onClose: onClose, open: open, role: "presentation", children: jsx(SlideFade, { ref: ref, in: open, direction: direction, onEntered: () => setExited(false), onExited: () => setExited(true), children: children }) }));
58
35
  });
59
36
 
60
37
  export { SlideFadeOverlay as default };
@@ -0,0 +1,28 @@
1
+ interface ScrollLockOptions {
2
+ /**
3
+ * Whether the scroll lock is enabled
4
+ * @default false
5
+ */
6
+ enabled?: boolean;
7
+ /**
8
+ * Whether to reserve scrollbar width to prevent layout shift
9
+ * @default true
10
+ */
11
+ reserveScrollBarGap?: boolean;
12
+ }
13
+ /**
14
+ * Hook to lock/unlock body scroll
15
+ * Handles multiple concurrent locks (nested modals/overlays)
16
+ * Prevents layout shift by reserving scrollbar width
17
+ * Handles iOS rubber band scrolling
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * function Modal({ open }) {
22
+ * useScrollLock({ enabled: open });
23
+ * return <div>...</div>;
24
+ * }
25
+ * ```
26
+ */
27
+ export declare function useScrollLock(options?: ScrollLockOptions): void;
28
+ export {};