@moneyforward/mfui-components 3.21.0 → 3.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/src/Dialog/Dialog.d.ts +1 -1
  2. package/dist/src/Dialog/Dialog.types.d.ts +7 -1
  3. package/dist/src/FormFooter/FormFooter.types.d.ts +2 -3
  4. package/dist/src/SidePane/SidePane.d.ts +1 -1
  5. package/dist/src/SidePane/SidePane.types.d.ts +1 -3
  6. package/dist/src/Stepper/DoneStepIcon.d.ts +9 -0
  7. package/dist/src/Stepper/DoneStepIcon.js +11 -0
  8. package/dist/src/Stepper/Step/Step.d.ts +7 -0
  9. package/dist/src/Stepper/Step/Step.js +47 -0
  10. package/dist/src/Stepper/Step/Step.types.d.ts +20 -0
  11. package/dist/src/Stepper/Step/Step.types.js +1 -0
  12. package/dist/src/Stepper/Step/index.d.ts +2 -0
  13. package/dist/src/Stepper/Step/index.js +1 -0
  14. package/dist/src/Stepper/StepContext.d.ts +10 -0
  15. package/dist/src/Stepper/StepContext.js +2 -0
  16. package/dist/src/Stepper/Stepper.d.ts +26 -0
  17. package/dist/src/Stepper/Stepper.js +49 -0
  18. package/dist/src/Stepper/Stepper.types.d.ts +21 -0
  19. package/dist/src/Stepper/Stepper.types.js +1 -0
  20. package/dist/src/Stepper/StepperContext.d.ts +5 -0
  21. package/dist/src/Stepper/StepperContext.js +2 -0
  22. package/dist/src/Stepper/index.d.ts +3 -0
  23. package/dist/src/Stepper/index.js +1 -0
  24. package/dist/src/Tooltip/Tooltip.js +12 -3
  25. package/dist/src/Tooltip/hooks/useTooltipDisplayController.d.ts +1 -0
  26. package/dist/src/Tooltip/hooks/useTooltipDisplayController.js +1 -0
  27. package/dist/src/index.d.ts +1 -0
  28. package/dist/src/index.js +1 -0
  29. package/dist/styled-system/recipes/form-footer-slot-recipe.d.ts +1 -1
  30. package/dist/styled-system/recipes/form-footer-slot-recipe.js +0 -1
  31. package/dist/styled-system/recipes/index.d.ts +1 -0
  32. package/dist/styled-system/recipes/index.js +1 -0
  33. package/dist/styled-system/recipes/stepper-slot-recipe.d.ts +44 -0
  34. package/dist/styled-system/recipes/stepper-slot-recipe.js +118 -0
  35. package/dist/styled-system/tokens/index.js +892 -44
  36. package/dist/styled-system/tokens/tokens.d.ts +4 -4
  37. package/dist/styles.css +199 -34
  38. package/dist/tsconfig.build.tsbuildinfo +1 -1
  39. package/package.json +3 -3
@@ -6,7 +6,7 @@
6
6
  */
7
7
  export declare const Dialog: import("react").ForwardRefExoticComponent<{
8
8
  children?: import("react").ReactNode;
9
- title: string;
9
+ title: import("react").ReactNode;
10
10
  open?: boolean;
11
11
  onClose?: () => void;
12
12
  actionSlot?: import("react").ReactNode;
@@ -7,8 +7,14 @@ export type DialogProps = {
7
7
  children?: ReactNode;
8
8
  /**
9
9
  * The heading title of the dialog.
10
+ *
11
+ * Accepts a string or any `ReactNode` (e.g. a `<Skeleton />` shown while the
12
+ * title is loading asynchronously). Keep the node heading-appropriate —
13
+ * inline text, status indicators, or icons — because the dialog uses
14
+ * `aria-labelledby` to announce the title and screen readers will read the
15
+ * entire subtree. Avoid placing interactive controls inside `title`.
10
16
  */
11
- title: string;
17
+ title: ReactNode;
12
18
  /**
13
19
  * Whether the dialog is shown or not.
14
20
  * This prop is optional and should be passed when using the dialog as a controlled component.
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
- export type FormFooterPosition = 'fixed' | 'stacking' | 'sticky';
2
+ export type FormFooterPosition = 'stacking' | 'sticky';
3
3
  export type FormFooterSectionPosition = 'fill' | 'center';
4
4
  export type FormFooterProps = {
5
5
  /**
@@ -10,8 +10,7 @@ export type FormFooterProps = {
10
10
  * It's for controlling the position of the component.
11
11
  *
12
12
  * - `"stacking"`: Displayed inline at the bottom of its container. Use for creation forms where preventing mid-session abandonment is important.
13
- * - `"fixed"`: Pinned to the bottom of the viewport at all times with a separator border. Use for edit screens where users return frequently.
14
- * - `"sticky"`: Sits inline below the last form field, and pins to the bottom of the nearest scrolling ancestor (e.g. inside `SidePane`) when the form overflows. Use inside scrollable containers such as `SidePane`.
13
+ * - `"sticky"`: Sits inline below the last form field, and pins to the bottom of the nearest scrolling ancestor when the form overflows. Use inside scrollable containers such as `SidePane`.
15
14
  *
16
15
  * @default "stacking"
17
16
  */
@@ -18,7 +18,7 @@ export declare const SidePane: import("react").ForwardRefExoticComponent<{
18
18
  disableBackdropClose?: boolean;
19
19
  enableAutoUnmount?: boolean;
20
20
  formFooterProps?: Pick<import("..").FormFooterProps, "optionsSlot" | "actionsSlot"> & {
21
- position?: Exclude<import("..").FormFooterProps["position"], "fixed">;
21
+ position?: import("..").FormFooterProps["position"];
22
22
  };
23
23
  insideProps?: {
24
24
  className?: string;
@@ -116,12 +116,10 @@ export type SidePaneProps = {
116
116
  * - `position: 'sticky'` (default): the footer is always pinned to the pane bottom, outside the scrollable content area.
117
117
  * - `position: 'stacking'`: the footer flows after the content inside the scroll area.
118
118
  *
119
- * `position: 'fixed'` is not supported here because it anchors to the viewport rather than the pane.
120
- *
121
119
  * @default undefined
122
120
  */
123
121
  formFooterProps?: Pick<FormFooterProps, 'optionsSlot' | 'actionsSlot'> & {
124
- position?: Exclude<FormFooterProps['position'], 'fixed'>;
122
+ position?: FormFooterProps['position'];
125
123
  };
126
124
  /**
127
125
  * Additional props to apply to the inside container element of the SidePane.
@@ -0,0 +1,9 @@
1
+ import { type SVGProps } from 'react';
2
+ /**
3
+ * Checkmark icon used inside the `done`-state step indicator.
4
+ *
5
+ * This component is private to `Stepper` and not exported from the package.
6
+ *
7
+ * @param props - SVG props forwarded to the root `<svg>`.
8
+ */
9
+ export declare function DoneStepIcon(props: SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Checkmark icon used inside the `done`-state step indicator.
4
+ *
5
+ * This component is private to `Stepper` and not exported from the package.
6
+ *
7
+ * @param props - SVG props forwarded to the root `<svg>`.
8
+ */
9
+ export function DoneStepIcon(props) {
10
+ return (_jsx("svg", { width: 18, height: 18, viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M14.0002 6.00001C14.2764 6.27616 14.2764 6.72387 14.0002 7.00001L8.00024 13L3.99894 8.99871C3.72279 8.72257 3.7241 8.27616 4.00024 8.00001C4.27638 7.72387 4.7241 7.72387 5.00024 8.00001L8.00024 11L13.0002 6.00001C13.2764 5.72387 13.7241 5.72387 14.0002 6.00001Z", fill: "currentColor" }) }));
11
+ }
@@ -0,0 +1,7 @@
1
+ import { type StepperStepProps } from './Step.types';
2
+ /**
3
+ * A single step inside `Stepper`. Rendered either as a static container, a
4
+ * `<button>` (when `onClick` is provided), or an `<a>`/custom link (when
5
+ * `href` is provided).
6
+ */
7
+ export declare function Step({ children, onClick, href, customLinkComponent }: StepperStepProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { createElement, useContext } from 'react';
4
+ import { cx } from '../../../styled-system/css';
5
+ import { stepperSlotRecipe } from '../../../styled-system/recipes';
6
+ import { FocusIndicator } from '../../FocusIndicator';
7
+ import { Typography } from '../../Typography';
8
+ import { DoneStepIcon } from '../DoneStepIcon';
9
+ import { StepperContext } from '../StepperContext';
10
+ import { StepContext } from '../StepContext';
11
+ /**
12
+ * A single step inside `Stepper`. Rendered either as a static container, a
13
+ * `<button>` (when `onClick` is provided), or an `<a>`/custom link (when
14
+ * `href` is provided).
15
+ */
16
+ export function Step({ children, onClick, href, customLinkComponent }) {
17
+ const stepperContext = useContext(StepperContext);
18
+ const stepContext = useContext(StepContext);
19
+ if (!stepperContext || !stepContext) {
20
+ throw new Error('Stepper.Step must be rendered inside a Stepper.');
21
+ }
22
+ const { labelPosition } = stepperContext;
23
+ const { index, status, isLast } = stepContext;
24
+ const interactive = onClick !== undefined || href !== undefined;
25
+ const classes = stepperSlotRecipe({
26
+ labelPosition,
27
+ status,
28
+ interactive,
29
+ });
30
+ const indicatorContent = status === 'done' ? _jsx(DoneStepIcon, { "aria-hidden": true }) : _jsx("span", { "aria-hidden": true, children: index + 1 });
31
+ const labelVariant = status === 'current' ? 'strongBody' : 'body';
32
+ const inner = (_jsxs(_Fragment, { children: [_jsx("span", { className: cx(classes.indicator, 'mfui-Stepper__indicator'), "data-mfui-stepper-slot": "indicator", children: indicatorContent }), _jsx(Typography, { variant: labelVariant, className: cx(classes.label, 'mfui-Stepper__label'), "data-mfui-stepper-slot": "label", children: children })] }));
33
+ const ariaCurrent = status === 'current' ? 'step' : undefined;
34
+ const contentClassName = cx(classes.content, 'mfui-Stepper__content');
35
+ let contentElement;
36
+ if (!interactive) {
37
+ contentElement = (_jsx("div", { className: contentClassName, "aria-current": ariaCurrent, children: inner }));
38
+ }
39
+ else if (href !== undefined) {
40
+ const LinkTag = customLinkComponent ?? 'a';
41
+ contentElement = (_jsx(FocusIndicator, { children: createElement(LinkTag, { className: contentClassName, href, 'aria-current': ariaCurrent }, inner) }));
42
+ }
43
+ else {
44
+ contentElement = (_jsx(FocusIndicator, { children: _jsx("button", { type: "button", className: contentClassName, "aria-current": ariaCurrent, onClick: onClick, children: inner }) }));
45
+ }
46
+ return (_jsxs("li", { className: cx(classes.item, 'mfui-Stepper__item'), "data-mfui-is-last": isLast ? 'true' : undefined, "data-mfui-step-status": status, children: [contentElement, !isLast ? _jsx("span", { "aria-hidden": true, className: cx(classes.connector, 'mfui-Stepper__connector') }) : null] }));
47
+ }
@@ -0,0 +1,20 @@
1
+ import { type ElementType, type MouseEventHandler, type ReactNode } from 'react';
2
+ export type StepperStepProps = {
3
+ /** Step label content. */
4
+ children: ReactNode;
5
+ /**
6
+ * When provided, the step renders as a `<button>` and triggers `onClick` when
7
+ * activated by mouse or keyboard. Ignored when `href` is also provided.
8
+ */
9
+ onClick?: MouseEventHandler<HTMLButtonElement>;
10
+ /**
11
+ * When provided, the step renders as an `<a>` (or `customLinkComponent`) and
12
+ * navigates on activation.
13
+ */
14
+ href?: string;
15
+ /**
16
+ * Custom link component (e.g. Next.js `<Link>`). Only applied when `href` is
17
+ * also provided. Falls back to a plain `<a>` tag when omitted.
18
+ */
19
+ customLinkComponent?: ElementType;
20
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Step } from './Step';
2
+ export type { StepperStepProps } from './Step.types';
@@ -0,0 +1 @@
1
+ export { Step } from './Step';
@@ -0,0 +1,10 @@
1
+ export type StepStatus = 'current' | 'done' | 'upcoming';
2
+ export type StepContextValue = {
3
+ /** 0-based step index. */
4
+ index: number;
5
+ /** Derived status of this step. */
6
+ status: StepStatus;
7
+ /** True when this step is the last in the list (no trailing connector). */
8
+ isLast: boolean;
9
+ };
10
+ export declare const StepContext: import("react").Context<StepContextValue | null>;
@@ -0,0 +1,2 @@
1
+ import { createContext } from 'react';
2
+ export const StepContext = createContext(null);
@@ -0,0 +1,26 @@
1
+ import { Step } from './Step';
2
+ import { type StepperProps } from './Stepper.types';
3
+ declare function Base({ currentStepIndex, labelPosition, children, className, 'aria-label': ariaLabel, ...rest }: StepperProps): import("react/jsx-runtime").JSX.Element;
4
+ /**
5
+ * Stepper displays a wizard-style flow's overall steps and the user's current
6
+ * position within it. Steps are derived from `Stepper.Step` children, and each
7
+ * step's status (`done` / `current` / `upcoming`) is derived from
8
+ * `currentStepIndex`.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <Stepper currentStepIndex={1}>
13
+ * <Stepper.Step>申請内容の入力</Stepper.Step>
14
+ * <Stepper.Step onClick={() => goto(1)}>内容の確認</Stepper.Step>
15
+ * <Stepper.Step>送信</Stepper.Step>
16
+ * </Stepper>
17
+ * ```
18
+ */
19
+ export declare const Stepper: typeof Base & {
20
+ /**
21
+ * A single step. Use one `Stepper.Step` per step in the flow. Provide
22
+ * `onClick` or `href` to make the step interactive.
23
+ */
24
+ Step: typeof Step;
25
+ };
26
+ export {};
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Children, useMemo } from 'react';
4
+ import { cx } from '../../styled-system/css';
5
+ import { stepperSlotRecipe } from '../../styled-system/recipes';
6
+ import { StepperContext } from './StepperContext';
7
+ import { StepContext } from './StepContext';
8
+ import { Step } from './Step';
9
+ function deriveStatus(index, currentStepIndex) {
10
+ if (index < currentStepIndex)
11
+ return 'done';
12
+ if (index === currentStepIndex)
13
+ return 'current';
14
+ return 'upcoming';
15
+ }
16
+ function StepProvider({ index, status, isLast, children, }) {
17
+ const value = useMemo(() => ({ index, status, isLast }), [index, status, isLast]);
18
+ return _jsx(StepContext.Provider, { value: value, children: children });
19
+ }
20
+ function Base({ currentStepIndex, labelPosition = 'right', children, className, 'aria-label': ariaLabel = 'ステップ', ...rest }) {
21
+ const classes = stepperSlotRecipe({ labelPosition });
22
+ const stepperContextValue = useMemo(() => ({ labelPosition }), [labelPosition]);
23
+ // Filter out falsy children (booleans, null, undefined) so that conditional
24
+ // rendering of steps doesn't produce phantom indices.
25
+ const steps = Children.toArray(children);
26
+ return (_jsx(StepperContext.Provider, { value: stepperContextValue, children: _jsx("nav", { ...rest, className: cx(classes.root, 'mfui-Stepper__root', className), "aria-label": ariaLabel, children: _jsx("ol", { className: cx(classes.list, 'mfui-Stepper__list'), children: steps.map((child, index) => (_jsx(StepProvider, { index: index, status: deriveStatus(index, currentStepIndex), isLast: index === steps.length - 1, children: child }, index))) }) }) }));
27
+ }
28
+ /**
29
+ * Stepper displays a wizard-style flow's overall steps and the user's current
30
+ * position within it. Steps are derived from `Stepper.Step` children, and each
31
+ * step's status (`done` / `current` / `upcoming`) is derived from
32
+ * `currentStepIndex`.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * <Stepper currentStepIndex={1}>
37
+ * <Stepper.Step>申請内容の入力</Stepper.Step>
38
+ * <Stepper.Step onClick={() => goto(1)}>内容の確認</Stepper.Step>
39
+ * <Stepper.Step>送信</Stepper.Step>
40
+ * </Stepper>
41
+ * ```
42
+ */
43
+ export const Stepper = Object.assign(Base, {
44
+ /**
45
+ * A single step. Use one `Stepper.Step` per step in the flow. Provide
46
+ * `onClick` or `href` to make the step interactive.
47
+ */
48
+ Step,
49
+ });
@@ -0,0 +1,21 @@
1
+ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
2
+ export type StepperLabelPosition = 'right' | 'bottom';
3
+ export type StepperProps = {
4
+ /**
5
+ * 0-based index of the current step.
6
+ * Steps before this index are rendered as `done`, the step at this index
7
+ * is `current`, and steps after are `upcoming`.
8
+ */
9
+ currentStepIndex: number;
10
+ /**
11
+ * Position of each step's label relative to its indicator.
12
+ *
13
+ * - `right` (default): label sits to the right of the indicator on the same line.
14
+ * - `bottom`: label is centered directly below the indicator.
15
+ *
16
+ * @default 'right'
17
+ */
18
+ labelPosition?: StepperLabelPosition;
19
+ /** `Stepper.Step` elements. */
20
+ children: ReactNode;
21
+ } & Omit<ComponentPropsWithoutRef<'nav'>, 'children'>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type StepperLabelPosition } from './Stepper.types';
2
+ export type StepperContextValue = {
3
+ labelPosition: StepperLabelPosition;
4
+ };
5
+ export declare const StepperContext: import("react").Context<StepperContextValue | null>;
@@ -0,0 +1,2 @@
1
+ import { createContext } from 'react';
2
+ export const StepperContext = createContext(null);
@@ -0,0 +1,3 @@
1
+ export { Stepper } from './Stepper';
2
+ export type { StepperProps, StepperLabelPosition } from './Stepper.types';
3
+ export type { StepperStepProps } from './Step';
@@ -0,0 +1 @@
1
+ export { Stepper } from './Stepper';
@@ -1,11 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { forwardRef, useId, useRef, isValidElement, cloneElement, useEffect } from 'react';
3
+ import { forwardRef, useId, useRef, isValidElement, cloneElement, useEffect, useMemo } from 'react';
4
4
  import { getOverflowAncestors } from '@floating-ui/react-dom';
5
5
  import { cx } from '../../styled-system/css';
6
6
  import { tooltipSlotRecipe } from '../../styled-system/recipes';
7
7
  import { Typography } from '../Typography';
8
8
  import { mergeRefs } from '../utilities/dom/mergeRefs';
9
+ import { useOnClickOutside } from '../utilities/dom/useOnClickOutside';
9
10
  import { useTooltipDisplayController } from './hooks/useTooltipDisplayController';
10
11
  import { ArrowIcon } from './icons/ArrowIcon';
11
12
  import { usePopoverController } from './hooks/usePopoverController';
@@ -46,11 +47,12 @@ export const DEFAULT_MAX_WIDTH = '268px';
46
47
  export const Tooltip = forwardRef(({ children, open, onOpenStateChanged, content, targetDOMNode, placement, trigger = ['hover', 'focus'], disabled = false, hideFromScreenReader = false, maxWidth = DEFAULT_MAX_WIDTH, className, contentProps, ...wrapperProps }, ref) => {
47
48
  const rootRef = useRef(null);
48
49
  const arrowRef = useRef(null);
50
+ const tooltipRef = useRef(null);
49
51
  const tooltipId = useId();
50
52
  // Use automatic target resolution matching Portal.tsx pattern
51
53
  // Resolution order: explicit prop → parent context → document.body fallback
52
54
  const targetElement = useAutomaticTargetDomNode(targetDOMNode, rootRef.current);
53
- const { open: calculatedOpen, rootAttributes, tooltipAttributes, closeImmediate, } = useTooltipDisplayController({
55
+ const { open: calculatedOpen, rootAttributes, tooltipAttributes, closeImmediate, closeWithManager, } = useTooltipDisplayController({
54
56
  trigger,
55
57
  wrapperProps,
56
58
  tooltipOpen: open,
@@ -77,6 +79,13 @@ export const Tooltip = forwardRef(({ children, open, onOpenStateChanged, content
77
79
  });
78
80
  };
79
81
  }, [calculatedOpen, closeImmediate]);
82
+ const hasClickTrigger = useMemo(() => (Array.isArray(trigger) ? trigger : [trigger]).includes('click'), [trigger]);
83
+ // Skip the trigger (rootRef) so the existing onClick toggle handles re-clicks —
84
+ // closing here would race with onClick and immediately reopen the tooltip.
85
+ useOnClickOutside(rootRef, closeWithManager, {
86
+ ignoreRefs: [tooltipRef],
87
+ disabled: !calculatedOpen || !hasClickTrigger || open !== undefined,
88
+ });
80
89
  const triggerRef = mergeRefs(setTriggerReference, rootRef, ref);
81
90
  const classes = tooltipSlotRecipe();
82
91
  const ariaDescribedBy = !hideFromScreenReader && content != null ? tooltipId : undefined;
@@ -90,5 +99,5 @@ export const Tooltip = forwardRef(({ children, open, onOpenStateChanged, content
90
99
  clip: 'rect(0, 0, 0, 0)',
91
100
  whiteSpace: 'nowrap',
92
101
  borderWidth: 0,
93
- }, children: content }) })), calculatedOpen ? (_jsx(Portal, { targetDOMNode: targetElement, children: _jsxs("div", { ref: setTooltipReference, className: cx(classes.tooltip, 'mfui-Tooltip__tooltip', contentProps?.className), role: "tooltip", id: tooltipId, "aria-hidden": hideFromScreenReader ? true : undefined, style: { maxWidth, ...tooltipStyles }, ...tooltipAttributes, children: [typeof content === 'string' ? _jsx(Typography, { variant: "helpMessage", children: content }) : content, _jsx(ArrowIcon, { ref: arrowRef, "aria-hidden": true, placement: calculatedPlacement, className: cx(classes.arrow, 'mfui-Tooltip__arrow'), style: arrowStyles })] }) })) : null] }));
102
+ }, children: content }) })), calculatedOpen ? (_jsx(Portal, { targetDOMNode: targetElement, children: _jsxs("div", { ref: mergeRefs(setTooltipReference, tooltipRef), className: cx(classes.tooltip, 'mfui-Tooltip__tooltip', contentProps?.className), role: "tooltip", id: tooltipId, "aria-hidden": hideFromScreenReader ? true : undefined, style: { maxWidth, ...tooltipStyles }, ...tooltipAttributes, children: [typeof content === 'string' ? _jsx(Typography, { variant: "helpMessage", children: content }) : content, _jsx(ArrowIcon, { ref: arrowRef, "aria-hidden": true, placement: calculatedPlacement, className: cx(classes.arrow, 'mfui-Tooltip__arrow'), style: arrowStyles })] }) })) : null] }));
94
103
  });
@@ -34,4 +34,5 @@ export declare function useTooltipDisplayController({ trigger, wrapperProps, too
34
34
  onMouseLeave: () => void;
35
35
  };
36
36
  closeImmediate: () => void;
37
+ closeWithManager: () => void;
37
38
  };
@@ -220,5 +220,6 @@ export function useTooltipDisplayController({ trigger, wrapperProps, tooltipOpen
220
220
  rootAttributes,
221
221
  tooltipAttributes,
222
222
  closeImmediate,
223
+ closeWithManager,
223
224
  };
224
225
  }
@@ -47,6 +47,7 @@ export * from './Skeleton';
47
47
  export * from './SplitView';
48
48
  export * from './Stack';
49
49
  export * from './StatusLabel';
50
+ export * from './Stepper';
50
51
  export * from './SubNavigation';
51
52
  export * from './Tabs';
52
53
  export * from './Tag';
package/dist/src/index.js CHANGED
@@ -47,6 +47,7 @@ export * from './Skeleton';
47
47
  export * from './SplitView';
48
48
  export * from './Stack';
49
49
  export * from './StatusLabel';
50
+ export * from './Stepper';
50
51
  export * from './SubNavigation';
51
52
  export * from './Tabs';
52
53
  export * from './Tag';
@@ -3,7 +3,7 @@ import type { ConditionalValue } from '../types/index';
3
3
  import type { DistributiveOmit, Pretty } from '../types/system-types';
4
4
 
5
5
  interface FormFooterSlotRecipeVariant {
6
- position: "stacking" | "fixed" | "sticky"
6
+ position: "stacking" | "sticky"
7
7
  sectionPosition: "center" | "fill"
8
8
  }
9
9
 
@@ -38,7 +38,6 @@ export const formFooterSlotRecipe = /* @__PURE__ */ Object.assign(formFooterSlot
38
38
  variantMap: {
39
39
  "position": [
40
40
  "stacking",
41
- "fixed",
42
41
  "sticky"
43
42
  ],
44
43
  "sectionPosition": [
@@ -54,6 +54,7 @@ export * from './data-table-row-slot-recipe';
54
54
  export * from './sub-navigation-slot-recipe';
55
55
  export * from './progress-indicator-slot-recipe';
56
56
  export * from './stack-slot-recipe';
57
+ export * from './stepper-slot-recipe';
57
58
  export * from './multiple-select-box-slot-recipe';
58
59
  export * from './multiple-select-box-trigger-recipe';
59
60
  export * from './checkbox-card-slot-recipe';
@@ -53,6 +53,7 @@ export * from './data-table-row-slot-recipe.js';
53
53
  export * from './sub-navigation-slot-recipe.js';
54
54
  export * from './progress-indicator-slot-recipe.js';
55
55
  export * from './stack-slot-recipe.js';
56
+ export * from './stepper-slot-recipe.js';
56
57
  export * from './multiple-select-box-slot-recipe.js';
57
58
  export * from './multiple-select-box-trigger-recipe.js';
58
59
  export * from './checkbox-card-slot-recipe.js';
@@ -0,0 +1,44 @@
1
+ /* eslint-disable */
2
+ import type { ConditionalValue } from '../types/index';
3
+ import type { DistributiveOmit, Pretty } from '../types/system-types';
4
+
5
+ interface StepperSlotRecipeVariant {
6
+ /**
7
+ * @default "right"
8
+ */
9
+ labelPosition: "right" | "bottom"
10
+ /**
11
+ * @default "upcoming"
12
+ */
13
+ status: "current" | "done" | "upcoming"
14
+ /**
15
+ * @default false
16
+ */
17
+ interactive: boolean
18
+ }
19
+
20
+ type StepperSlotRecipeVariantMap = {
21
+ [key in keyof StepperSlotRecipeVariant]: Array<StepperSlotRecipeVariant[key]>
22
+ }
23
+
24
+ type StepperSlotRecipeSlot = "root" | "list" | "item" | "content" | "indicator" | "label" | "connector"
25
+
26
+ export type StepperSlotRecipeVariantProps = {
27
+ [key in keyof StepperSlotRecipeVariant]?: StepperSlotRecipeVariant[key] | undefined
28
+ }
29
+
30
+ export interface StepperSlotRecipeRecipe {
31
+ __slot: StepperSlotRecipeSlot
32
+ __type: StepperSlotRecipeVariantProps
33
+ (props?: StepperSlotRecipeVariantProps): Pretty<Record<StepperSlotRecipeSlot, string>>
34
+ raw: (props?: StepperSlotRecipeVariantProps) => StepperSlotRecipeVariantProps
35
+ variantMap: StepperSlotRecipeVariantMap
36
+ variantKeys: Array<keyof StepperSlotRecipeVariant>
37
+ splitVariantProps<Props extends StepperSlotRecipeVariantProps>(props: Props): [StepperSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof StepperSlotRecipeVariantProps>>]
38
+ getVariantProps: (props?: StepperSlotRecipeVariantProps) => StepperSlotRecipeVariantProps
39
+ }
40
+
41
+ /**
42
+ * Slot class created for the MFUI Stepper component.
43
+ */
44
+ export declare const stepperSlotRecipe: StepperSlotRecipeRecipe
@@ -0,0 +1,118 @@
1
+ import { compact, getSlotCompoundVariant, memo, splitProps } from '../helpers.js';
2
+ import { createRecipe } from './create-recipe.js';
3
+ const stepperSlotRecipeDefaultVariants = {
4
+ "labelPosition": "right",
5
+ "status": "upcoming",
6
+ "interactive": false
7
+ };
8
+ const stepperSlotRecipeCompoundVariants = [
9
+ {
10
+ "status": "done",
11
+ "interactive": true,
12
+ "css": {
13
+ "content": {
14
+ "&:hover > [data-mfui-stepper-slot=\"indicator\"], &:focus-visible > [data-mfui-stepper-slot=\"indicator\"]": {
15
+ "backgroundColor": "mfui.color.primary.content.hovered"
16
+ },
17
+ "&:active > [data-mfui-stepper-slot=\"indicator\"]": {
18
+ "backgroundColor": "mfui.color.primary.content.pressed"
19
+ }
20
+ }
21
+ }
22
+ },
23
+ {
24
+ "status": "current",
25
+ "interactive": true,
26
+ "css": {
27
+ "content": {
28
+ "&:hover > [data-mfui-stepper-slot=\"indicator\"], &:focus-visible > [data-mfui-stepper-slot=\"indicator\"]": {
29
+ "backgroundColor": "mfui.color.primary.content.hovered"
30
+ },
31
+ "&:active > [data-mfui-stepper-slot=\"indicator\"]": {
32
+ "backgroundColor": "mfui.color.primary.content.pressed"
33
+ }
34
+ }
35
+ }
36
+ },
37
+ {
38
+ "status": "upcoming",
39
+ "interactive": true,
40
+ "css": {
41
+ "content": {
42
+ "&:hover > [data-mfui-stepper-slot=\"indicator\"], &:focus-visible > [data-mfui-stepper-slot=\"indicator\"]": {
43
+ "backgroundColor": "mfui.color.neutral.sub-background.hovered",
44
+ "color": "mfui.color.neutral.content.hovered"
45
+ },
46
+ "&:active > [data-mfui-stepper-slot=\"indicator\"]": {
47
+ "backgroundColor": "mfui.color.neutral.sub-background.pressed",
48
+ "color": "mfui.color.neutral.content.pressed"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ];
54
+ const stepperSlotRecipeSlotNames = [
55
+ [
56
+ "root",
57
+ "Stepper__root"
58
+ ],
59
+ [
60
+ "list",
61
+ "Stepper__list"
62
+ ],
63
+ [
64
+ "item",
65
+ "Stepper__item"
66
+ ],
67
+ [
68
+ "content",
69
+ "Stepper__content"
70
+ ],
71
+ [
72
+ "indicator",
73
+ "Stepper__indicator"
74
+ ],
75
+ [
76
+ "label",
77
+ "Stepper__label"
78
+ ],
79
+ [
80
+ "connector",
81
+ "Stepper__connector"
82
+ ]
83
+ ];
84
+ const stepperSlotRecipeSlotFns = /* @__PURE__ */ stepperSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, stepperSlotRecipeDefaultVariants, getSlotCompoundVariant(stepperSlotRecipeCompoundVariants, slotName))]);
85
+ const stepperSlotRecipeFn = memo((props = {}) => {
86
+ return Object.fromEntries(stepperSlotRecipeSlotFns.map(([slotName, slotFn]) => [slotName, slotFn.recipeFn(props)]));
87
+ });
88
+ const stepperSlotRecipeVariantKeys = [
89
+ "labelPosition",
90
+ "status",
91
+ "interactive"
92
+ ];
93
+ const getVariantProps = (variants) => ({ ...stepperSlotRecipeDefaultVariants, ...compact(variants) });
94
+ export const stepperSlotRecipe = /* @__PURE__ */ Object.assign(stepperSlotRecipeFn, {
95
+ __recipe__: false,
96
+ __name__: 'stepperSlotRecipe',
97
+ raw: (props) => props,
98
+ classNameMap: {},
99
+ variantKeys: stepperSlotRecipeVariantKeys,
100
+ variantMap: {
101
+ "labelPosition": [
102
+ "right",
103
+ "bottom"
104
+ ],
105
+ "status": [
106
+ "current",
107
+ "done",
108
+ "upcoming"
109
+ ],
110
+ "interactive": [
111
+ "true"
112
+ ]
113
+ },
114
+ splitVariantProps(props) {
115
+ return splitProps(props, stepperSlotRecipeVariantKeys);
116
+ },
117
+ getVariantProps
118
+ });