@wallarm-org/design-system 1.31.0 → 1.32.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.
- package/dist/components/Stepper/Stepper.d.ts +22 -0
- package/dist/components/Stepper/Stepper.figma.d.ts +1 -0
- package/dist/components/Stepper/Stepper.figma.js +59 -0
- package/dist/components/Stepper/Stepper.js +34 -0
- package/dist/components/Stepper/StepperContent.d.ts +16 -0
- package/dist/components/Stepper/StepperContent.js +28 -0
- package/dist/components/Stepper/StepperContext.d.ts +58 -0
- package/dist/components/Stepper/StepperContext.js +37 -0
- package/dist/components/Stepper/StepperDescription.d.ts +8 -0
- package/dist/components/Stepper/StepperDescription.js +30 -0
- package/dist/components/Stepper/StepperIndicator.d.ts +9 -0
- package/dist/components/Stepper/StepperIndicator.js +34 -0
- package/dist/components/Stepper/StepperItem.d.ts +19 -0
- package/dist/components/Stepper/StepperItem.js +48 -0
- package/dist/components/Stepper/StepperList.d.ts +12 -0
- package/dist/components/Stepper/StepperList.js +28 -0
- package/dist/components/Stepper/StepperNextTrigger.d.ts +14 -0
- package/dist/components/Stepper/StepperNextTrigger.js +28 -0
- package/dist/components/Stepper/StepperPrevTrigger.d.ts +13 -0
- package/dist/components/Stepper/StepperPrevTrigger.js +31 -0
- package/dist/components/Stepper/StepperRootProvider.d.ts +18 -0
- package/dist/components/Stepper/StepperRootProvider.js +25 -0
- package/dist/components/Stepper/StepperSeparator.d.ts +7 -0
- package/dist/components/Stepper/StepperSeparator.js +28 -0
- package/dist/components/Stepper/StepperTitle.d.ts +8 -0
- package/dist/components/Stepper/StepperTitle.js +32 -0
- package/dist/components/Stepper/StepperTrigger.d.ts +16 -0
- package/dist/components/Stepper/StepperTrigger.js +32 -0
- package/dist/components/Stepper/classes.d.ts +14 -0
- package/dist/components/Stepper/classes.js +37 -0
- package/dist/components/Stepper/constants.d.ts +22 -0
- package/dist/components/Stepper/constants.js +23 -0
- package/dist/components/Stepper/index.d.ts +15 -0
- package/dist/components/Stepper/index.js +14 -0
- package/dist/components/Stepper/takeAsChildDisabled.d.ts +11 -0
- package/dist/components/Stepper/takeAsChildDisabled.js +17 -0
- package/dist/components/Stepper/types.d.ts +11 -0
- package/dist/components/Stepper/types.js +0 -0
- package/dist/components/Stepper/useStepper.d.ts +38 -0
- package/dist/components/Stepper/useStepper.js +58 -0
- package/dist/components/Table/TableBody/TableBodyVirtualizedCore.js +1 -1
- package/dist/components/Table/TableBody/TableBodyVirtualizedWindow.js +30 -8
- package/dist/components/Table/TableInner/TableInnerWindow.js +7 -2
- package/dist/components/Table/hooks/index.d.ts +1 -0
- package/dist/components/Table/hooks/index.js +1 -0
- package/dist/components/Table/hooks/infiniteScroll/useInfiniteScroll.d.ts +4 -2
- package/dist/components/Table/hooks/infiniteScroll/useInfiniteScroll.js +6 -2
- package/dist/components/Table/hooks/infiniteScroll/useInitialAnchor.d.ts +7 -1
- package/dist/components/Table/hooks/infiniteScroll/useInitialAnchor.js +4 -3
- package/dist/components/Table/hooks/infiniteScroll/usePrependScrollAnchor.d.ts +4 -1
- package/dist/components/Table/hooks/infiniteScroll/usePrependScrollAnchor.js +13 -11
- package/dist/components/Table/hooks/infiniteScroll/useScrollEdge.d.ts +4 -1
- package/dist/components/Table/hooks/infiniteScroll/useScrollEdge.js +7 -18
- package/dist/components/Table/hooks/useWindowScrollRoot.d.ts +26 -0
- package/dist/components/Table/hooks/useWindowScrollRoot.js +62 -0
- package/dist/components/Table/lib/index.d.ts +1 -0
- package/dist/components/Table/lib/index.js +1 -0
- package/dist/components/Table/lib/scrollRoot.d.ts +24 -0
- package/dist/components/Table/lib/scrollRoot.js +22 -0
- package/dist/components/Table/types.d.ts +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/metadata/components.json +4097 -426
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FC, ReactNode, Ref } from 'react';
|
|
2
|
+
import { Steps as ArkSteps } from '@ark-ui/react/steps';
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
import type { StepperStatusLabels } from './types';
|
|
5
|
+
import { type StepperGuardProps, type StepperOmittedArkProps } from './useStepper';
|
|
6
|
+
export interface StepperProps extends Omit<ArkSteps.RootProps, StepperOmittedArkProps | keyof StepperGuardProps | 'asChild'>, StepperGuardProps, TestableProps {
|
|
7
|
+
/** `StepperList`, then optional `StepperContent`s and `StepperPrevTrigger` / `StepperNextTrigger`. */
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
/** Screen-reader-only suffixes for completed and danger steps. */
|
|
10
|
+
statusLabels?: StepperStatusLabels;
|
|
11
|
+
ref?: Ref<HTMLDivElement>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A horizontal row of numbered steps for a multi-step flow, such as a create drawer. Every step is
|
|
15
|
+
* a button, so people can move back and forward freely; the page owns each step's status
|
|
16
|
+
* (completed, danger, upcoming) and the current step is always shown as active.
|
|
17
|
+
*
|
|
18
|
+
* Compound, like Ark UI Steps: `StepperList` › `StepperItem index` › `StepperTrigger` (with
|
|
19
|
+
* `StepperIndicator`, `StepperTitle`, `StepperDescription`) and `StepperSeparator`, then optional
|
|
20
|
+
* `StepperContent index`, `StepperPrevTrigger` and `StepperNextTrigger`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const Stepper: FC<StepperProps>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import code_connect from "@figma/code-connect";
|
|
3
|
+
import { Stepper } from "./Stepper.js";
|
|
4
|
+
import { StepperDescription } from "./StepperDescription.js";
|
|
5
|
+
import { StepperIndicator } from "./StepperIndicator.js";
|
|
6
|
+
import { StepperItem } from "./StepperItem.js";
|
|
7
|
+
import { StepperList } from "./StepperList.js";
|
|
8
|
+
import { StepperSeparator } from "./StepperSeparator.js";
|
|
9
|
+
import { StepperTitle } from "./StepperTitle.js";
|
|
10
|
+
import { StepperTrigger } from "./StepperTrigger.js";
|
|
11
|
+
const STEPPER_URL = 'https://www.figma.com/design/VKb5gW46uSGw0rqrhZsbXT/WADS-Components?node-id=12463-208988';
|
|
12
|
+
const STEPPER_ITEM_URL = 'https://www.figma.com/design/VKb5gW46uSGw0rqrhZsbXT/WADS-Components?node-id=12463-208896';
|
|
13
|
+
code_connect.connect(Stepper, STEPPER_URL, {
|
|
14
|
+
props: {
|
|
15
|
+
children: code_connect.children('stepper-item')
|
|
16
|
+
},
|
|
17
|
+
example: ({ children })=>/*#__PURE__*/ jsx(Stepper, {
|
|
18
|
+
count: 4,
|
|
19
|
+
step: 0,
|
|
20
|
+
onStepChange: ()=>void 0,
|
|
21
|
+
children: /*#__PURE__*/ jsx(StepperList, {
|
|
22
|
+
"aria-label": "Steps",
|
|
23
|
+
children: children
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
code_connect.connect(StepperItem, STEPPER_ITEM_URL, {
|
|
28
|
+
props: {
|
|
29
|
+
status: code_connect["enum"]('Type', {
|
|
30
|
+
Completed: 'completed',
|
|
31
|
+
Danger: 'danger',
|
|
32
|
+
Upcoming: 'upcoming',
|
|
33
|
+
Active: void 0
|
|
34
|
+
}),
|
|
35
|
+
title: code_connect.string('step'),
|
|
36
|
+
description: code_connect.boolean("description", {
|
|
37
|
+
true: code_connect.string("descriptionText"),
|
|
38
|
+
false: void 0
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
example: ({ status, title, description })=>/*#__PURE__*/ jsxs(StepperItem, {
|
|
42
|
+
index: 0,
|
|
43
|
+
status: status,
|
|
44
|
+
children: [
|
|
45
|
+
/*#__PURE__*/ jsxs(StepperTrigger, {
|
|
46
|
+
children: [
|
|
47
|
+
/*#__PURE__*/ jsx(StepperIndicator, {}),
|
|
48
|
+
/*#__PURE__*/ jsx(StepperTitle, {
|
|
49
|
+
children: title
|
|
50
|
+
}),
|
|
51
|
+
description && /*#__PURE__*/ jsx(StepperDescription, {
|
|
52
|
+
children: description
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
}),
|
|
56
|
+
/*#__PURE__*/ jsx(StepperSeparator, {})
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps } from "@ark-ui/react/steps";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { TestIdProvider } from "../../utils/testId.js";
|
|
5
|
+
import { stepperVariants } from "./classes.js";
|
|
6
|
+
import { StepperRootContext } from "./StepperContext.js";
|
|
7
|
+
import { useStepperGuards } from "./useStepper.js";
|
|
8
|
+
const Stepper = ({ children, count, step, defaultStep, onStepChange, statusLabels, className, ref, 'data-testid': testId, ...rest })=>{
|
|
9
|
+
const guarded = useStepperGuards({
|
|
10
|
+
count,
|
|
11
|
+
step,
|
|
12
|
+
defaultStep,
|
|
13
|
+
onStepChange
|
|
14
|
+
});
|
|
15
|
+
return /*#__PURE__*/ jsx(Steps.Root, {
|
|
16
|
+
...rest,
|
|
17
|
+
...guarded,
|
|
18
|
+
ref: ref,
|
|
19
|
+
"data-slot": "stepper",
|
|
20
|
+
"data-testid": testId,
|
|
21
|
+
className: cn(stepperVariants(), className),
|
|
22
|
+
children: /*#__PURE__*/ jsx(TestIdProvider, {
|
|
23
|
+
value: testId,
|
|
24
|
+
children: /*#__PURE__*/ jsx(StepperRootContext.Provider, {
|
|
25
|
+
value: {
|
|
26
|
+
statusLabels
|
|
27
|
+
},
|
|
28
|
+
children: children
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
Stepper.displayName = 'Stepper';
|
|
34
|
+
export { Stepper };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperContentProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
|
|
4
|
+
/** 0-based step this body belongs to. */
|
|
5
|
+
index: number;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
ref?: Ref<HTMLDivElement>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The body of one step, shown only while that step is current. Every body stays mounted (hidden),
|
|
11
|
+
* so form state survives moving between steps. It is a `group` named by its `StepperTrigger`
|
|
12
|
+
* (Ark's `aria-labelledby`), so render the matching trigger in the same `Stepper`. Set trigger
|
|
13
|
+
* ids with the root `ids.triggerId` prop, not an `id` on `StepperTrigger`: the body only knows the
|
|
14
|
+
* root's ids.
|
|
15
|
+
*/
|
|
16
|
+
export declare const StepperContent: FC<StepperContentProps>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps, useStepsContext } from "@ark-ui/react/steps";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { useTestId } from "../../utils/testId.js";
|
|
5
|
+
import { stepperContentVariants } from "./classes.js";
|
|
6
|
+
import { ARK_CONTENT_ARIA_RESET } from "./constants.js";
|
|
7
|
+
import { clampStep, useStepperRootContext } from "./StepperContext.js";
|
|
8
|
+
const StepperContent = ({ index, children, className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
9
|
+
useStepperRootContext('StepperContent');
|
|
10
|
+
const { value, count } = useStepsContext();
|
|
11
|
+
const current = index === clampStep(value, count);
|
|
12
|
+
const testId = useTestId(`content-${index}`, testIdProp);
|
|
13
|
+
return /*#__PURE__*/ jsx(Steps.Content, {
|
|
14
|
+
index: index,
|
|
15
|
+
...ARK_CONTENT_ARIA_RESET,
|
|
16
|
+
role: "group",
|
|
17
|
+
...rest,
|
|
18
|
+
ref: ref,
|
|
19
|
+
hidden: !current,
|
|
20
|
+
"data-state": current ? 'open' : 'closed',
|
|
21
|
+
"data-slot": "stepper-content",
|
|
22
|
+
"data-testid": testId,
|
|
23
|
+
className: cn(stepperContentVariants(), className),
|
|
24
|
+
children: children
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
StepperContent.displayName = 'StepperContent';
|
|
28
|
+
export { StepperContent };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { StepperStatusLabels, StepperVisualStatus } from './types';
|
|
2
|
+
interface StepperRootContextValue {
|
|
3
|
+
statusLabels?: StepperStatusLabels;
|
|
4
|
+
}
|
|
5
|
+
export declare const StepperRootContext: import("react").Context<StepperRootContextValue | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Reads the enclosing `Stepper` / `StepperRootProvider`. Called first by every root-level part, so
|
|
8
|
+
* misuse throws a `[Stepper]` error instead of Ark's internal `useStepsContext` one.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useStepperRootContext: (part: string) => StepperRootContextValue;
|
|
11
|
+
/** `true` inside a `StepperList`, so a `StepperItem` can tell it is rendered outside one. */
|
|
12
|
+
export declare const StepperListContext: import("react").Context<boolean>;
|
|
13
|
+
export interface StepperItemContextValue {
|
|
14
|
+
/** 0-based position, from the item's `index` prop. */
|
|
15
|
+
index: number;
|
|
16
|
+
/** This item is the current step. */
|
|
17
|
+
current: boolean;
|
|
18
|
+
/** This item is the last step: it renders no separator. */
|
|
19
|
+
last: boolean;
|
|
20
|
+
/** Rendered state: `'active'` while current, else the item's `status`. */
|
|
21
|
+
status: StepperVisualStatus;
|
|
22
|
+
/** Screen-reader-only suffix for completed and danger steps, already resolved. */
|
|
23
|
+
statusLabel?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const StepperItemContext: import("react").Context<StepperItemContextValue | undefined>;
|
|
26
|
+
/** Reads the enclosing `StepperItem`: `{ index, current, last, status }`. */
|
|
27
|
+
export declare const useStepperItemContext: () => StepperItemContextValue;
|
|
28
|
+
/**
|
|
29
|
+
* The current step, clamped to `[0, count - 1]`. Zag accepts `count` as a step (its "completed"
|
|
30
|
+
* state, where no step is current) and checks the range only on mount, so a step can fall out of
|
|
31
|
+
* range; the Stepper always shows one current step.
|
|
32
|
+
*/
|
|
33
|
+
export declare const clampStep: (value: number, count: number) => number;
|
|
34
|
+
export interface UseStepperContextReturn {
|
|
35
|
+
/** Current step, 0-based, always in `[0, count - 1]`. */
|
|
36
|
+
value: number;
|
|
37
|
+
/** Number of steps. */
|
|
38
|
+
count: number;
|
|
39
|
+
/** There is a later step. `false` on the last step. */
|
|
40
|
+
hasNextStep: boolean;
|
|
41
|
+
/** There is an earlier step. `false` on the first step. */
|
|
42
|
+
hasPrevStep: boolean;
|
|
43
|
+
/** Moves to the next step; does nothing on the last step. */
|
|
44
|
+
goToNextStep: () => void;
|
|
45
|
+
/** Moves to the previous step; does nothing on the first step. */
|
|
46
|
+
goToPrevStep: () => void;
|
|
47
|
+
/** Moves to the first step. */
|
|
48
|
+
resetStep: () => void;
|
|
49
|
+
/** Moves to `step`, clamped to `[0, count - 1]`. */
|
|
50
|
+
setStep: (step: number) => void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Reads the enclosing `Stepper`. Wraps Ark's `useStepsContext`, with one difference: it never
|
|
54
|
+
* moves past the last step, so there is always a current step (Ark's "completed" state is not
|
|
55
|
+
* part of the Stepper).
|
|
56
|
+
*/
|
|
57
|
+
export declare const useStepperContext: () => UseStepperContextReturn;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import { useStepsContext } from "@ark-ui/react/steps";
|
|
3
|
+
const StepperRootContext = /*#__PURE__*/ createContext(void 0);
|
|
4
|
+
const useStepperRootContext = (part)=>{
|
|
5
|
+
const context = useContext(StepperRootContext);
|
|
6
|
+
if (!context) throw new Error(`[Stepper] ${part} must be used inside a Stepper or StepperRootProvider.`);
|
|
7
|
+
return context;
|
|
8
|
+
};
|
|
9
|
+
const StepperListContext = /*#__PURE__*/ createContext(false);
|
|
10
|
+
const StepperItemContext = /*#__PURE__*/ createContext(void 0);
|
|
11
|
+
const useStepperItemContext = ()=>{
|
|
12
|
+
const context = useContext(StepperItemContext);
|
|
13
|
+
if (!context) throw new Error('[Stepper] useStepperItemContext must be used inside a StepperItem.');
|
|
14
|
+
return context;
|
|
15
|
+
};
|
|
16
|
+
const clampStep = (value, count)=>Math.min(Math.max(value, 0), Math.max(count - 1, 0));
|
|
17
|
+
const useStepperContext = ()=>{
|
|
18
|
+
useStepperRootContext('useStepperContext');
|
|
19
|
+
const api = useStepsContext();
|
|
20
|
+
const value = clampStep(api.value, api.count);
|
|
21
|
+
const hasNextStep = value < api.count - 1;
|
|
22
|
+
return {
|
|
23
|
+
value,
|
|
24
|
+
count: api.count,
|
|
25
|
+
hasNextStep,
|
|
26
|
+
hasPrevStep: value > 0,
|
|
27
|
+
goToNextStep: ()=>{
|
|
28
|
+
if (hasNextStep) api.setStep(value + 1);
|
|
29
|
+
},
|
|
30
|
+
goToPrevStep: ()=>{
|
|
31
|
+
if (value > 0) api.setStep(value - 1);
|
|
32
|
+
},
|
|
33
|
+
resetStep: api.resetStep,
|
|
34
|
+
setStep: (step)=>api.setStep(clampStep(step, api.count))
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export { StepperItemContext, StepperListContext, StepperRootContext, clampStep, useStepperContext, useStepperItemContext, useStepperRootContext };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperDescriptionProps extends HTMLAttributes<HTMLSpanElement>, TestableProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
ref?: Ref<HTMLSpanElement>;
|
|
6
|
+
}
|
|
7
|
+
/** An optional second line under the title, e.g. 'Optional' or 'Request · Lua · HMAC auth'. One line, ellipsis at 320px, with the full text in a tooltip when it overflows. */
|
|
8
|
+
export declare const StepperDescription: FC<StepperDescriptionProps>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from "../OverflowTooltip/index.js";
|
|
5
|
+
import { stepperDescriptionVariants } from "./classes.js";
|
|
6
|
+
import { useStepperItemContext } from "./StepperContext.js";
|
|
7
|
+
const StepperDescription = ({ children, className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
8
|
+
const { status } = useStepperItemContext();
|
|
9
|
+
const testId = useTestId("description", testIdProp);
|
|
10
|
+
return /*#__PURE__*/ jsxs(OverflowTooltip, {
|
|
11
|
+
children: [
|
|
12
|
+
/*#__PURE__*/ jsx(OverflowTooltipTrigger, {
|
|
13
|
+
ref: ref,
|
|
14
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
15
|
+
...rest,
|
|
16
|
+
"data-slot": "stepper-description",
|
|
17
|
+
"data-status": status,
|
|
18
|
+
"data-testid": testId,
|
|
19
|
+
className: cn(stepperDescriptionVariants(), className),
|
|
20
|
+
children: children
|
|
21
|
+
})
|
|
22
|
+
}),
|
|
23
|
+
/*#__PURE__*/ jsx(OverflowTooltipContent, {
|
|
24
|
+
children: children
|
|
25
|
+
})
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
StepperDescription.displayName = "StepperDescription";
|
|
30
|
+
export { StepperDescription };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperIndicatorProps extends HTMLAttributes<HTMLSpanElement>, TestableProps {
|
|
4
|
+
/** Replaces the default content: the step number, `!` for danger, a check for completed. */
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
ref?: Ref<HTMLSpanElement>;
|
|
7
|
+
}
|
|
8
|
+
/** The step badge. Decorative: Ark marks it `aria-hidden`, the title names the step. */
|
|
9
|
+
export declare const StepperIndicator: FC<StepperIndicatorProps>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps } from "@ark-ui/react/steps";
|
|
3
|
+
import { Check } from "../../icons/index.js";
|
|
4
|
+
import { cn } from "../../utils/cn.js";
|
|
5
|
+
import { useTestId } from "../../utils/testId.js";
|
|
6
|
+
import { stepperIndicatorVariants } from "./classes.js";
|
|
7
|
+
import { useStepperItemContext } from "./StepperContext.js";
|
|
8
|
+
const renderDefault = (status, index)=>{
|
|
9
|
+
if ('completed' === status) return /*#__PURE__*/ jsx(Check, {
|
|
10
|
+
size: "sm"
|
|
11
|
+
});
|
|
12
|
+
if ('danger' === status) return '!';
|
|
13
|
+
return index + 1;
|
|
14
|
+
};
|
|
15
|
+
const StepperIndicator = ({ children, className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
16
|
+
const { index, status } = useStepperItemContext();
|
|
17
|
+
const testId = useTestId('indicator', testIdProp);
|
|
18
|
+
return /*#__PURE__*/ jsx(Steps.Indicator, {
|
|
19
|
+
asChild: true,
|
|
20
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
21
|
+
...rest,
|
|
22
|
+
ref: ref,
|
|
23
|
+
"data-slot": "stepper-indicator",
|
|
24
|
+
"data-status": status,
|
|
25
|
+
"data-testid": testId,
|
|
26
|
+
className: cn(stepperIndicatorVariants({
|
|
27
|
+
status
|
|
28
|
+
}), className),
|
|
29
|
+
children: children ?? renderDefault(status, index)
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
StepperIndicator.displayName = 'StepperIndicator';
|
|
34
|
+
export { StepperIndicator };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FC, type LiHTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
import type { StepperItemStatus } from './types';
|
|
4
|
+
export interface StepperItemProps extends LiHTMLAttributes<HTMLLIElement>, TestableProps {
|
|
5
|
+
/** 0-based position of this step. Required, like Ark's `Steps.Item`. */
|
|
6
|
+
index: number;
|
|
7
|
+
/** Status set by the page. Ignored while this item is the current step. Default `'upcoming'`. */
|
|
8
|
+
status?: StepperItemStatus;
|
|
9
|
+
/** Overrides the root `statusLabels` suffix for this item. */
|
|
10
|
+
statusLabel?: string;
|
|
11
|
+
/** `StepperTrigger`, then `StepperSeparator`. */
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
ref?: Ref<HTMLLIElement>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One step: an `<li>` holding the step's `StepperTrigger` and its `StepperSeparator`. It resolves
|
|
17
|
+
* the rendered status (active while current, else `status`) for the parts inside it.
|
|
18
|
+
*/
|
|
19
|
+
export declare const StepperItem: FC<StepperItemProps>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
import { Steps, useStepsContext } from "@ark-ui/react/steps";
|
|
4
|
+
import { cn } from "../../utils/cn.js";
|
|
5
|
+
import { TestIdProvider, useTestId } from "../../utils/testId.js";
|
|
6
|
+
import { stepperItemVariants } from "./classes.js";
|
|
7
|
+
import { ARK_ITEM_ARIA_RESET, DEFAULT_STEPPER_STATUS_LABELS } from "./constants.js";
|
|
8
|
+
import { StepperItemContext, StepperListContext, clampStep, useStepperRootContext } from "./StepperContext.js";
|
|
9
|
+
const StepperItem = ({ index, status, statusLabel, children, className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
10
|
+
const { statusLabels } = useStepperRootContext('StepperItem');
|
|
11
|
+
const inList = useContext(StepperListContext);
|
|
12
|
+
if ('production' !== process.env.NODE_ENV && !inList) console.warn('[Stepper] StepperItem must be rendered inside a StepperList: an <li> outside the <ol> loses the list semantics.');
|
|
13
|
+
const { value, count } = useStepsContext();
|
|
14
|
+
const currentStep = clampStep(value, count);
|
|
15
|
+
const current = index === currentStep;
|
|
16
|
+
if ('production' !== process.env.NODE_ENV && current && value !== currentStep) console.warn(`[Stepper] current step ${value} is out of range [0, ${count - 1}]; showing step ${currentStep}.`);
|
|
17
|
+
const testId = useTestId(`item-${index}`, testIdProp);
|
|
18
|
+
const visual = current ? 'active' : status ?? 'upcoming';
|
|
19
|
+
const context = {
|
|
20
|
+
index,
|
|
21
|
+
current,
|
|
22
|
+
last: index === count - 1,
|
|
23
|
+
status: visual,
|
|
24
|
+
statusLabel: 'completed' === visual || 'danger' === visual ? statusLabel ?? statusLabels?.[visual] ?? DEFAULT_STEPPER_STATUS_LABELS[visual] : void 0
|
|
25
|
+
};
|
|
26
|
+
return /*#__PURE__*/ jsx(Steps.Item, {
|
|
27
|
+
index: index,
|
|
28
|
+
asChild: true,
|
|
29
|
+
...ARK_ITEM_ARIA_RESET,
|
|
30
|
+
children: /*#__PURE__*/ jsx("li", {
|
|
31
|
+
...rest,
|
|
32
|
+
ref: ref,
|
|
33
|
+
"data-slot": "stepper-item",
|
|
34
|
+
"data-status": visual,
|
|
35
|
+
"data-testid": testId,
|
|
36
|
+
className: cn(stepperItemVariants(), className),
|
|
37
|
+
children: /*#__PURE__*/ jsx(StepperItemContext.Provider, {
|
|
38
|
+
value: context,
|
|
39
|
+
children: /*#__PURE__*/ jsx(TestIdProvider, {
|
|
40
|
+
value: testId,
|
|
41
|
+
children: children
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
StepperItem.displayName = 'StepperItem';
|
|
48
|
+
export { StepperItem };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FC, OlHTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperListProps extends OlHTMLAttributes<HTMLOListElement>, TestableProps {
|
|
4
|
+
/** `StepperItem`s, each with its `index`. */
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
ref?: Ref<HTMLOListElement>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The step bar: an `<ol>` with the Figma bottom border and padding. Name it with `aria-label` or
|
|
10
|
+
* `aria-labelledby`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const StepperList: FC<StepperListProps>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps } from "@ark-ui/react/steps";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { useTestId } from "../../utils/testId.js";
|
|
5
|
+
import { stepperListVariants } from "./classes.js";
|
|
6
|
+
import { ARK_LIST_ARIA_RESET } from "./constants.js";
|
|
7
|
+
import { StepperListContext, useStepperRootContext } from "./StepperContext.js";
|
|
8
|
+
const StepperList = ({ children, className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
9
|
+
useStepperRootContext('StepperList');
|
|
10
|
+
const testId = useTestId('list', testIdProp);
|
|
11
|
+
return /*#__PURE__*/ jsx(Steps.List, {
|
|
12
|
+
asChild: true,
|
|
13
|
+
...ARK_LIST_ARIA_RESET,
|
|
14
|
+
children: /*#__PURE__*/ jsx("ol", {
|
|
15
|
+
...rest,
|
|
16
|
+
ref: ref,
|
|
17
|
+
"data-slot": "stepper-list",
|
|
18
|
+
"data-testid": testId,
|
|
19
|
+
className: cn(stepperListVariants(), className),
|
|
20
|
+
children: /*#__PURE__*/ jsx(StepperListContext.Provider, {
|
|
21
|
+
value: true,
|
|
22
|
+
children: children
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
StepperList.displayName = 'StepperList';
|
|
28
|
+
export { StepperList };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes, FC, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperNextTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement>, TestableProps {
|
|
4
|
+
/** Render the child (e.g. a `Button`) as the trigger instead of a plain `<button>`. */
|
|
5
|
+
asChild?: boolean;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
ref?: Ref<HTMLButtonElement>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Moves to the next step. Disabled on the last step, where the page renders its own submit
|
|
11
|
+
* button instead: Ark would otherwise move to its "completed" state, with no current step. A
|
|
12
|
+
* `disabled` on an `asChild` child is folded in, so the last step still disables it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const StepperNextTrigger: FC<StepperNextTriggerProps>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps, useStepsContext } from "@ark-ui/react/steps";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { clampStep, useStepperRootContext } from "./StepperContext.js";
|
|
5
|
+
import { takeAsChildDisabled } from "./takeAsChildDisabled.js";
|
|
6
|
+
const StepperNextTrigger = ({ asChild, children, disabled, onClick, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
7
|
+
useStepperRootContext('StepperNextTrigger');
|
|
8
|
+
const { value, count } = useStepsContext();
|
|
9
|
+
const atLast = clampStep(value, count) >= count - 1;
|
|
10
|
+
const testId = useTestId('next-trigger', testIdProp);
|
|
11
|
+
const child = takeAsChildDisabled(asChild, children);
|
|
12
|
+
const handleClick = (event)=>{
|
|
13
|
+
onClick?.(event);
|
|
14
|
+
if (atLast) event.preventDefault();
|
|
15
|
+
};
|
|
16
|
+
return /*#__PURE__*/ jsx(Steps.NextTrigger, {
|
|
17
|
+
...rest,
|
|
18
|
+
asChild: asChild,
|
|
19
|
+
ref: ref,
|
|
20
|
+
disabled: atLast || disabled || child.childDisabled || void 0,
|
|
21
|
+
onClick: handleClick,
|
|
22
|
+
"data-slot": "stepper-next-trigger",
|
|
23
|
+
"data-testid": testId,
|
|
24
|
+
children: child.children
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
StepperNextTrigger.displayName = 'StepperNextTrigger';
|
|
28
|
+
export { StepperNextTrigger };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes, FC, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperPrevTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement>, TestableProps {
|
|
4
|
+
/** Render the child (e.g. a `Button`) as the trigger instead of a plain `<button>`. */
|
|
5
|
+
asChild?: boolean;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
ref?: Ref<HTMLButtonElement>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Moves to the previous step. Disabled on the first step. Use `asChild` with a `Button`; a
|
|
11
|
+
* `disabled` on that child is folded in, so the first step still disables it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const StepperPrevTrigger: FC<StepperPrevTriggerProps>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps, useStepsContext } from "@ark-ui/react/steps";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { clampStep, useStepperRootContext } from "./StepperContext.js";
|
|
5
|
+
import { takeAsChildDisabled } from "./takeAsChildDisabled.js";
|
|
6
|
+
const StepperPrevTrigger = ({ asChild, children, disabled, onClick, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
7
|
+
useStepperRootContext('StepperPrevTrigger');
|
|
8
|
+
const { value, count, setStep } = useStepsContext();
|
|
9
|
+
const current = clampStep(value, count);
|
|
10
|
+
const atFirst = 0 === current;
|
|
11
|
+
const testId = useTestId('prev-trigger', testIdProp);
|
|
12
|
+
const child = takeAsChildDisabled(asChild, children);
|
|
13
|
+
const handleClick = (event)=>{
|
|
14
|
+
onClick?.(event);
|
|
15
|
+
if (event.defaultPrevented) return;
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
if (!atFirst) setStep(current - 1);
|
|
18
|
+
};
|
|
19
|
+
return /*#__PURE__*/ jsx(Steps.PrevTrigger, {
|
|
20
|
+
...rest,
|
|
21
|
+
asChild: asChild,
|
|
22
|
+
ref: ref,
|
|
23
|
+
disabled: atFirst || disabled || child.childDisabled || void 0,
|
|
24
|
+
onClick: handleClick,
|
|
25
|
+
"data-slot": "stepper-prev-trigger",
|
|
26
|
+
"data-testid": testId,
|
|
27
|
+
children: child.children
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
StepperPrevTrigger.displayName = 'StepperPrevTrigger';
|
|
31
|
+
export { StepperPrevTrigger };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FC, ReactNode, Ref } from 'react';
|
|
2
|
+
import { Steps as ArkSteps } from '@ark-ui/react/steps';
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
import type { StepperStatusLabels } from './types';
|
|
5
|
+
import type { UseStepperReturn } from './useStepper';
|
|
6
|
+
export interface StepperRootProviderProps extends Omit<ArkSteps.RootProviderProps, 'value' | 'asChild'>, TestableProps {
|
|
7
|
+
/** The machine from `useStepper()`, so the page can drive the steps from outside. */
|
|
8
|
+
value: UseStepperReturn;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
/** Screen-reader-only suffixes for completed and danger steps. */
|
|
11
|
+
statusLabels?: StepperStatusLabels;
|
|
12
|
+
ref?: Ref<HTMLDivElement>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The `Stepper` root for a machine created with `useStepper()`: the same parts, with the step
|
|
16
|
+
* state owned by the page (e.g. to move steps from a header action).
|
|
17
|
+
*/
|
|
18
|
+
export declare const StepperRootProvider: FC<StepperRootProviderProps>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps } from "@ark-ui/react/steps";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { TestIdProvider } from "../../utils/testId.js";
|
|
5
|
+
import { stepperVariants } from "./classes.js";
|
|
6
|
+
import { StepperRootContext } from "./StepperContext.js";
|
|
7
|
+
const StepperRootProvider = ({ value, children, statusLabels, className, ref, 'data-testid': testId, ...rest })=>/*#__PURE__*/ jsx(Steps.RootProvider, {
|
|
8
|
+
...rest,
|
|
9
|
+
value: value,
|
|
10
|
+
ref: ref,
|
|
11
|
+
"data-slot": "stepper",
|
|
12
|
+
"data-testid": testId,
|
|
13
|
+
className: cn(stepperVariants(), className),
|
|
14
|
+
children: /*#__PURE__*/ jsx(TestIdProvider, {
|
|
15
|
+
value: testId,
|
|
16
|
+
children: /*#__PURE__*/ jsx(StepperRootContext.Provider, {
|
|
17
|
+
value: {
|
|
18
|
+
statusLabels
|
|
19
|
+
},
|
|
20
|
+
children: children
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
StepperRootProvider.displayName = 'StepperRootProvider';
|
|
25
|
+
export { StepperRootProvider };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperSeparatorProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'>, TestableProps {
|
|
4
|
+
ref?: Ref<HTMLSpanElement>;
|
|
5
|
+
}
|
|
6
|
+
/** The line after a step, on its first row. Decorative, and renders nothing on the last step. */
|
|
7
|
+
export declare const StepperSeparator: FC<StepperSeparatorProps>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Steps } from "@ark-ui/react/steps";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { useTestId } from "../../utils/testId.js";
|
|
5
|
+
import { stepperSeparatorLineClassNames, stepperSeparatorVariants } from "./classes.js";
|
|
6
|
+
import { useStepperItemContext } from "./StepperContext.js";
|
|
7
|
+
const StepperSeparator = ({ className, ref, 'data-testid': testIdProp, ...rest })=>{
|
|
8
|
+
const { last, status } = useStepperItemContext();
|
|
9
|
+
const testId = useTestId('separator', testIdProp);
|
|
10
|
+
if (last) return null;
|
|
11
|
+
return /*#__PURE__*/ jsx(Steps.Separator, {
|
|
12
|
+
asChild: true,
|
|
13
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
14
|
+
...rest,
|
|
15
|
+
ref: ref,
|
|
16
|
+
"aria-hidden": "true",
|
|
17
|
+
"data-slot": "stepper-separator",
|
|
18
|
+
"data-status": status,
|
|
19
|
+
"data-testid": testId,
|
|
20
|
+
className: cn(stepperSeparatorVariants(), className),
|
|
21
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
22
|
+
className: stepperSeparatorLineClassNames
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
StepperSeparator.displayName = 'StepperSeparator';
|
|
28
|
+
export { StepperSeparator };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface StepperTitleProps extends HTMLAttributes<HTMLSpanElement>, TestableProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
ref?: Ref<HTMLSpanElement>;
|
|
6
|
+
}
|
|
7
|
+
/** The step name: one line, ellipsis at 320px, with the full text in a tooltip when it overflows. */
|
|
8
|
+
export declare const StepperTitle: FC<StepperTitleProps>;
|