@central-ui/react 0.3.0 → 0.5.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 (75) hide show
  1. package/dist/components/accordion/index.d.ts +14 -14
  2. package/dist/components/accordion/index.js +19 -19
  3. package/dist/components/autocomplete/index.d.ts +51 -47
  4. package/dist/components/autocomplete/index.js +57 -57
  5. package/dist/components/avatar/index.d.ts +7 -6
  6. package/dist/components/avatar/index.js +9 -9
  7. package/dist/components/banner/index.js +1 -1
  8. package/dist/components/carousel/index.d.ts +31 -11
  9. package/dist/components/carousel/index.js +25 -21
  10. package/dist/components/checkbox/index.d.ts +12 -11
  11. package/dist/components/checkbox/index.js +21 -21
  12. package/dist/components/combobox/index.d.ts +56 -56
  13. package/dist/components/combobox/index.js +67 -68
  14. package/dist/components/datepicker/index.d.ts +8 -9
  15. package/dist/components/datepicker/index.js +13 -13
  16. package/dist/components/dialog/index.d.ts +18 -18
  17. package/dist/components/dialog/index.js +22 -21
  18. package/dist/components/drawer/index.d.ts +24 -24
  19. package/dist/components/drawer/index.js +28 -27
  20. package/dist/components/exception/index.d.ts +23 -11
  21. package/dist/components/exception/index.js +17 -17
  22. package/dist/components/fileupload/index.d.ts +8 -8
  23. package/dist/components/input/index.d.ts +14 -14
  24. package/dist/components/input/index.js +27 -27
  25. package/dist/components/menu/index.d.ts +37 -37
  26. package/dist/components/menu/index.js +47 -47
  27. package/dist/components/numberinput/index.d.ts +22 -22
  28. package/dist/components/numberinput/index.js +35 -35
  29. package/dist/components/otpinput/index.d.ts +12 -12
  30. package/dist/components/otpinput/index.js +21 -21
  31. package/dist/components/pagination/index.d.ts +158 -0
  32. package/dist/components/pagination/index.js +157 -0
  33. package/dist/components/passwordinput/index.d.ts +15 -15
  34. package/dist/components/passwordinput/index.js +27 -27
  35. package/dist/components/popover/index.d.ts +16 -16
  36. package/dist/components/popover/index.js +20 -19
  37. package/dist/components/radio/index.d.ts +12 -12
  38. package/dist/components/radio/index.js +25 -25
  39. package/dist/components/ratinginput/index.d.ts +1 -1
  40. package/dist/components/ratinginput/index.js +3 -3
  41. package/dist/components/select/index.d.ts +29 -29
  42. package/dist/components/select/index.js +33 -33
  43. package/dist/components/slider/index.d.ts +20 -20
  44. package/dist/components/slider/index.js +27 -27
  45. package/dist/components/stepper/index.d.ts +135 -44
  46. package/dist/components/stepper/index.js +185 -62
  47. package/dist/components/switch/index.d.ts +9 -9
  48. package/dist/components/switch/index.js +17 -17
  49. package/dist/components/table/index.d.ts +2 -2
  50. package/dist/components/table/index.js +16 -16
  51. package/dist/components/tabs/index.d.ts +10 -10
  52. package/dist/components/tabs/index.js +11 -11
  53. package/dist/components/textarea/index.d.ts +13 -13
  54. package/dist/components/textarea/index.js +25 -25
  55. package/dist/components/toast/index.d.ts +11 -11
  56. package/dist/components/toast/index.js +11 -11
  57. package/dist/components/toggle/index.d.ts +7 -7
  58. package/dist/components/toggle/index.js +9 -9
  59. package/dist/components/tooltip/index.d.ts +6 -6
  60. package/dist/components/tooltip/index.js +6 -7
  61. package/dist/components/tour/index.d.ts +2 -2
  62. package/dist/components/tour/index.js +5 -4
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +1 -0
  65. package/dist/utils/icons.d.ts +104 -23
  66. package/dist/utils/icons.js +16 -3
  67. package/package.json +69 -69
  68. package/src/presets/shopify-polaris/shopify-polaris-accordion.css +28 -28
  69. package/src/presets/shopify-polaris/shopify-polaris-pagination.css +55 -0
  70. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +63 -27
  71. package/src/presets/shopify-polaris/shopify-polaris.css +1 -0
  72. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-accordion.css +28 -28
  73. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-pagination.css +49 -0
  74. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +64 -26
  75. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +1 -0
@@ -1,70 +1,161 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
- import type { UseStepsProps } from '@ark-ui/react/steps';
2
+ import type { SVGIconProps } from '../../types/Icon.ts';
3
3
  import { Steps } from '@ark-ui/react/steps';
4
- export declare function useSteps(props: UseStepsProps): import("@ark-ui/react/steps").UseStepsReturn;
5
- export { useStepsContext } from '@ark-ui/react/steps';
6
- export { useStepsItemContext } from '@ark-ui/react/steps';
4
+ import type { ComponentProps, ReactElement, ReactNode, Ref } from 'react';
5
+ export type RootProps = {
6
+ /** Every step's value, in order, like ['details', 'shipping', 'review']. Each Item and Content takes one of these as its value. */
7
+ items: readonly string[];
8
+ /** The current step's value, or null once every step is done, which shows CompletedContent. Use with onValueChange to control it yourself. */
9
+ value?: string | null;
10
+ /**
11
+ * The step shown first, when you don't control value.
12
+ * @default items[0]
13
+ */
14
+ defaultValue?: string | null;
15
+ /** Called with the new step's value whenever it changes, or with null when NextButton is clicked on the last step, finishing them all. */
16
+ onValueChange?: (value: string | null) => void;
17
+ /**
18
+ * Makes the steps unclickable, so the user can only move with PreviousButton and NextButton, in order. Use it when a step needs the previous one done first, like payment after shipping.
19
+ * @default false
20
+ */
21
+ preventStepClicks?: boolean;
22
+ /** The Container. */
23
+ children: ReactNode;
24
+ };
7
25
  /**
8
- * Root owns the active step. Keep each Item in List with its index, and match Content indices to those items. NextButton/PreviousButton navigate between steps; pass asChild to give their behavior to your own buttons instead. Indicator reflects progress automatically; CompletedContent is shown after the last step.
26
+ * Splits a long task, like a checkout or an onboarding form, into steps the user goes through one by one.
27
+ * Root holds the current step and renders nothing itself. List every step's value in items, in order, then give each Item and Content one of them, like Tabs.
28
+ * Each Content holds its step's Body and Footer, and that Footer holds the step's own PreviousButton and NextButton, so every step words its buttons for itself, like "I agree" or "Place order". Never place the buttons outside a Content.
29
+ * NextButton on the last step finishes them all, showing CompletedContent. Indicator, IndicatorIcon, IndicatorText and Separator follow progress automatically.
9
30
  *
10
31
  * @example Complete composition
11
32
  * import { Button, Stepper } from '@central-ui/react'
12
33
  *
13
34
  * function Example() {
14
35
  * return (
15
- * <Stepper.Root count={2} defaultStep={0}>
16
- * <div className="flex items-start gap-4">
17
- * <Stepper.List className="w-32 shrink-0">
18
- * <Stepper.Item index={0}>
19
- * <Stepper.OpenButton>
20
- * <Stepper.Indicator />
21
- * Details
22
- * </Stepper.OpenButton>
36
+ * <Stepper.Root items={['details', 'review']}>
37
+ * <Stepper.Container>
38
+ * <Stepper.ItemsList>
39
+ * <Stepper.Item value="details">
40
+ * <Stepper.Indicator>
41
+ * <Stepper.IndicatorIcon />
42
+ * <Stepper.IndicatorText />
43
+ * </Stepper.Indicator>
44
+ * <Stepper.ItemTitle>Details</Stepper.ItemTitle>
45
+ * <Stepper.ItemDescription>Set your basics</Stepper.ItemDescription>
23
46
  * <Stepper.Separator />
24
47
  * </Stepper.Item>
25
- * <Stepper.Item index={1}>
26
- * <Stepper.OpenButton>
27
- * <Stepper.Indicator />
28
- * Review
29
- * </Stepper.OpenButton>
48
+ * <Stepper.Item value="review">
49
+ * <Stepper.Indicator>
50
+ * <Stepper.IndicatorIcon />
51
+ * <Stepper.IndicatorText />
52
+ * </Stepper.Indicator>
53
+ * <Stepper.ItemTitle>Review</Stepper.ItemTitle>
54
+ * <Stepper.ItemDescription>Check everything</Stepper.ItemDescription>
55
+ * <Stepper.Separator />
30
56
  * </Stepper.Item>
31
- * </Stepper.List>
32
- * <div className="w-full flex flex-col gap-3">
33
- * <Stepper.Content index={0}>Set your basics.</Stepper.Content>
34
- * <Stepper.Content index={1}>Check everything.</Stepper.Content>
35
- * <Stepper.CompletedContent>Done.</Stepper.CompletedContent>
36
- * <div className="flex gap-2">
37
- * <Stepper.PreviousButton>Previous</Stepper.PreviousButton>
57
+ * </Stepper.ItemsList>
58
+ * <Stepper.Content value="details">
59
+ * <Stepper.Body>Set your basics.</Stepper.Body>
60
+ * <Stepper.Footer>
61
+ * <Stepper.NextButton asChild>
62
+ * <Button.default variant="primary" size="small">
63
+ * Continue
64
+ * </Button.default>
65
+ * </Stepper.NextButton>
66
+ * </Stepper.Footer>
67
+ * </Stepper.Content>
68
+ * <Stepper.Content value="review">
69
+ * <Stepper.Body>Check everything.</Stepper.Body>
70
+ * <Stepper.Footer>
71
+ * <Stepper.PreviousButton>Back</Stepper.PreviousButton>
38
72
  * <Stepper.NextButton asChild>
39
73
  * <Button.default variant="primary" size="small">
40
- * Next
74
+ * Place order
41
75
  * </Button.default>
42
76
  * </Stepper.NextButton>
43
- * </div>
44
- * </div>
45
- * </div>
77
+ * </Stepper.Footer>
78
+ * </Stepper.Content>
79
+ * <Stepper.CompletedContent>Done.</Stepper.CompletedContent>
80
+ * </Stepper.Container>
46
81
  * </Stepper.Root>
47
82
  * )
48
83
  * }
49
84
  *
50
- * @example Show the steps horizontally
51
- * // Keep the same indexed Item and Content pairs.
52
- * ;<Stepper.Root count={2} orientation="horizontal">
85
+ * @example Control the step
86
+ * const [step, setStep] = useState<string | null>('details')
87
+ *
88
+ * ;<Stepper.Root items={['details', 'review']} value={step} onValueChange={setStep}>
53
89
  * {
54
90
  * // Rest of components here
55
91
  * }
56
92
  * </Stepper.Root>
57
93
  */
58
- export declare function Root({ children, className, orientation, ...props }: Omit<Steps.RootProps, 'asChild'>): import("react").JSX.Element;
59
- /** Moves to the next step. Pass asChild to give this behavior to your own button, like a "Continue" Button; it keeps the state data attributes but none of this part's styling. */
60
- export declare function NextButton({ asChild, disableStyle, ...props }: Steps.NextTriggerProps & StyleProps): import("react").JSX.Element;
61
- /** Moves to the previous step. Pass asChild to give this behavior to your own button, like a "Back" Button; it keeps the state data attributes but none of this part's styling. */
94
+ export declare function Root({ items, value, defaultValue, onValueChange, preventStepClicks, children, }: RootProps): import("react").JSX.Element;
95
+ /** Lays out ItemsList on the left of the current Content or CompletedContent. Spacing only, no look of its own. */
96
+ export declare function Container({ disableStyle, className, ref, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
97
+ /** Holds the Items; screen readers hear it as a tab list, no setup needed. */
98
+ export declare function ItemsList({ disableStyle, className, ...props }: Omit<Steps.ListProps, 'asChild'> & StyleProps): import("react").JSX.Element;
99
+ /**
100
+ * One step, as a single button opening its step on click, no click handler needed; does nothing with preventStepClicks.
101
+ * Carries data-current, data-complete or data-incomplete. Its value must be one of Root's items.
102
+ */
103
+ export declare function Item({ value, disableStyle, className, style, ...props }: Omit<Steps.TriggerProps, 'asChild'> & StyleProps & {
104
+ /** One of Root's items. */
105
+ value: string;
106
+ ref?: Ref<HTMLButtonElement>;
107
+ }): import("react").JSX.Element;
108
+ /** The circle marking the step, always shown. Holds IndicatorIcon and IndicatorText, which take turns automatically. */
109
+ export declare function Indicator({ disableStyle, className, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
110
+ type BuiltInIconProps = Omit<SVGIconProps, 'children'> & StyleProps & {
111
+ /** Omit for the supplied default icon; pass a child icon only to replace it. */
112
+ children?: ReactElement<SVGIconProps>;
113
+ };
114
+ /** Built-in check icon, shown only once the step is done; renders nothing before. Place inside Indicator. Omit children for the supplied default icon; pass an icon only to replace it. Defaults to strokeWidth 2.5. */
115
+ export declare function IndicatorIcon({ disableStyle, className, strokeWidth, children, ...props }: BuiltInIconProps): import("react").FunctionComponentElement<any> | null;
116
+ /** The step's number, worked out automatically; renders nothing once the step is done, leaving room for IndicatorIcon. Pass children only to show something else. Place inside Indicator. */
117
+ export declare function IndicatorText({ disableStyle, className, children, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element | null;
118
+ /**
119
+ * Optional small text above ItemTitle, like a date ("Jan 2024") or "Step 1 of 3". Add it only when the steps need that extra context; leave it out otherwise.
120
+ */
121
+ export declare function ItemMeta({ disableStyle, className, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
122
+ /** The step's name, beside the Indicator. */
123
+ export declare function ItemTitle({ disableStyle, className, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
124
+ /** A short hint under ItemTitle, like "Select product". */
125
+ export declare function ItemDescription({ disableStyle, className, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
126
+ /**
127
+ * The line joining a step to the next one, filled once the step is done. Renders nothing on the last step, so every Item can hold one.
128
+ *
129
+ * Changing its gap from the Indicators: the line lives inside its own Item, stretching between two distances measured from that Item's edges.
130
+ * - top: where the line starts, measured from the top of this Item. It must clear this step's Indicator, so it's the Indicator's height plus the gap you want under it.
131
+ * The preset's top-8.5 (34px) is the 26px Indicator + an 8px gap.
132
+ * - bottom: where the line ends, measured from the bottom of this Item. The next step's Indicator starts right at that edge, so bottom is exactly the gap above the next Indicator.
133
+ * The preset's bottom-1 is a 4px gap.
134
+ * Together they set the line's length: the Item's height minus top minus bottom. A taller Item, like one with a longer description, just makes a longer line with the same gaps.
135
+ * If you resize the Indicator, set top to its new height plus your gap, and left to half its width, so the line stays centered under it.
136
+ *
137
+ * @example Even 8px gaps on both ends
138
+ * // 26px Indicator + 8px gap = top-8.5; 8px gap = bottom-2
139
+ * ;<Stepper.Separator className="top-8.5 bottom-2" />
140
+ *
141
+ * @example A line touching both Indicators
142
+ * // top equals the Indicator's height; bottom is 0
143
+ * ;<Stepper.Separator className="top-6.5 bottom-0" />
144
+ */
145
+ export declare function Separator({ disableStyle, className, style, ref, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element | null;
146
+ /** Holds the step's main content, like its form fields. Place inside a Content, above its Footer. Spacing only, no look of its own. */
147
+ export declare function Body({ disableStyle, className, ref, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
148
+ /** One step's side, beside ItemsList, showing only while its step is current, no visibility condition needed. Holds the step's Body and Footer. Its value must be one of Root's items. */
149
+ export declare function Content({ value, disableStyle, className, ...props }: Omit<Steps.ContentProps, 'asChild' | 'index'> & StyleProps & {
150
+ /** One of Root's items. */
151
+ value: string;
152
+ }): import("react").JSX.Element;
153
+ /** Shows only once every step is done, after NextButton on the last step. */
154
+ export declare function CompletedContent({ disableStyle, className, ...props }: Omit<Steps.CompletedContentProps, 'asChild'> & StyleProps): import("react").JSX.Element;
155
+ /** The row under the step's Body, inside its Content, holding that step's PreviousButton and NextButton directly. Leave it out of a step needing no buttons. */
156
+ export declare function Footer({ disableStyle, className, ref, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
157
+ /** Moves to the previous step, no click handler needed. Place it in a Content's Footer, never outside a Content; leave it out of the first step's Footer. Pass asChild to give this behavior to your own button, like a "Back" Button; it keeps the state data attributes but none of this part's styling. */
62
158
  export declare function PreviousButton({ asChild, disableStyle, ...props }: Steps.PrevTriggerProps & StyleProps): import("react").JSX.Element;
63
- export declare function List({ disableStyle, className, ...props }: Steps.ListProps & StyleProps): import("react").JSX.Element;
64
- export declare function Item({ disableStyle, className, ...props }: Steps.ItemProps & StyleProps): import("react").JSX.Element;
65
- /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
66
- export declare function Indicator({ disableStyle, className, ...props }: Omit<Steps.IndicatorProps, 'children'> & StyleProps): import("react").JSX.Element;
67
- export declare function Separator({ disableStyle, className, ...props }: Steps.SeparatorProps & StyleProps): import("react").JSX.Element;
68
- export declare function Content({ disableStyle, className, ...props }: Steps.ContentProps & StyleProps): import("react").JSX.Element;
69
- export declare function CompletedContent({ disableStyle, className, ...props }: Steps.CompletedContentProps & StyleProps): import("react").JSX.Element;
70
- export declare function OpenButton({ disableStyle, className, ...props }: Steps.TriggerProps & StyleProps): import("react").JSX.Element;
159
+ /** Moves to the next step, no click handler needed; on the last step, it finishes them all. Place it in a Content's Footer, never outside a Content, worded for that step, like "I agree". Pass asChild to give this behavior to your own button, like a primary "Continue" Button; it keeps the state data attributes but none of this part's styling. */
160
+ export declare function NextButton({ asChild, disableStyle, ...props }: Steps.NextTriggerProps & StyleProps): import("react").JSX.Element;
161
+ export {};
@@ -1,99 +1,222 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { asChildStyleAttributes } from "../../utils/asChild.js";
3
- import { Steps, useSteps as useArkSteps } from '@ark-ui/react/steps';
3
+ import { Steps, useStepsItemContext } from '@ark-ui/react/steps';
4
4
  import { Check } from "../../utils/icons.js";
5
- // Creates a controlled steps state machine for RootProvider.
6
- export function useSteps(props) {
7
- return useArkSteps({ orientation: 'vertical', ...props });
8
- }
9
- // Reads the state of the nearest Steps root.
10
- export { useStepsContext } from '@ark-ui/react/steps';
11
- // Reads the state of the nearest Steps item.
12
- export { useStepsItemContext } from '@ark-ui/react/steps';
5
+ import { cloneElement, createContext, useContext } from 'react';
6
+ import { twMerge } from 'tailwind-merge';
7
+ const StepperContext = /* @__PURE__ */ createContext(null);
13
8
  /**
14
- * Root owns the active step. Keep each Item in List with its index, and match Content indices to those items. NextButton/PreviousButton navigate between steps; pass asChild to give their behavior to your own buttons instead. Indicator reflects progress automatically; CompletedContent is shown after the last step.
9
+ * Splits a long task, like a checkout or an onboarding form, into steps the user goes through one by one.
10
+ * Root holds the current step and renders nothing itself. List every step's value in items, in order, then give each Item and Content one of them, like Tabs.
11
+ * Each Content holds its step's Body and Footer, and that Footer holds the step's own PreviousButton and NextButton, so every step words its buttons for itself, like "I agree" or "Place order". Never place the buttons outside a Content.
12
+ * NextButton on the last step finishes them all, showing CompletedContent. Indicator, IndicatorIcon, IndicatorText and Separator follow progress automatically.
15
13
  *
16
14
  * @example Complete composition
17
15
  * import { Button, Stepper } from '@central-ui/react'
18
16
  *
19
17
  * function Example() {
20
18
  * return (
21
- * <Stepper.Root count={2} defaultStep={0}>
22
- * <div className="flex items-start gap-4">
23
- * <Stepper.List className="w-32 shrink-0">
24
- * <Stepper.Item index={0}>
25
- * <Stepper.OpenButton>
26
- * <Stepper.Indicator />
27
- * Details
28
- * </Stepper.OpenButton>
19
+ * <Stepper.Root items={['details', 'review']}>
20
+ * <Stepper.Container>
21
+ * <Stepper.ItemsList>
22
+ * <Stepper.Item value="details">
23
+ * <Stepper.Indicator>
24
+ * <Stepper.IndicatorIcon />
25
+ * <Stepper.IndicatorText />
26
+ * </Stepper.Indicator>
27
+ * <Stepper.ItemTitle>Details</Stepper.ItemTitle>
28
+ * <Stepper.ItemDescription>Set your basics</Stepper.ItemDescription>
29
29
  * <Stepper.Separator />
30
30
  * </Stepper.Item>
31
- * <Stepper.Item index={1}>
32
- * <Stepper.OpenButton>
33
- * <Stepper.Indicator />
34
- * Review
35
- * </Stepper.OpenButton>
31
+ * <Stepper.Item value="review">
32
+ * <Stepper.Indicator>
33
+ * <Stepper.IndicatorIcon />
34
+ * <Stepper.IndicatorText />
35
+ * </Stepper.Indicator>
36
+ * <Stepper.ItemTitle>Review</Stepper.ItemTitle>
37
+ * <Stepper.ItemDescription>Check everything</Stepper.ItemDescription>
38
+ * <Stepper.Separator />
36
39
  * </Stepper.Item>
37
- * </Stepper.List>
38
- * <div className="w-full flex flex-col gap-3">
39
- * <Stepper.Content index={0}>Set your basics.</Stepper.Content>
40
- * <Stepper.Content index={1}>Check everything.</Stepper.Content>
41
- * <Stepper.CompletedContent>Done.</Stepper.CompletedContent>
42
- * <div className="flex gap-2">
43
- * <Stepper.PreviousButton>Previous</Stepper.PreviousButton>
40
+ * </Stepper.ItemsList>
41
+ * <Stepper.Content value="details">
42
+ * <Stepper.Body>Set your basics.</Stepper.Body>
43
+ * <Stepper.Footer>
44
+ * <Stepper.NextButton asChild>
45
+ * <Button.default variant="primary" size="small">
46
+ * Continue
47
+ * </Button.default>
48
+ * </Stepper.NextButton>
49
+ * </Stepper.Footer>
50
+ * </Stepper.Content>
51
+ * <Stepper.Content value="review">
52
+ * <Stepper.Body>Check everything.</Stepper.Body>
53
+ * <Stepper.Footer>
54
+ * <Stepper.PreviousButton>Back</Stepper.PreviousButton>
44
55
  * <Stepper.NextButton asChild>
45
56
  * <Button.default variant="primary" size="small">
46
- * Next
57
+ * Place order
47
58
  * </Button.default>
48
59
  * </Stepper.NextButton>
49
- * </div>
50
- * </div>
51
- * </div>
60
+ * </Stepper.Footer>
61
+ * </Stepper.Content>
62
+ * <Stepper.CompletedContent>Done.</Stepper.CompletedContent>
63
+ * </Stepper.Container>
52
64
  * </Stepper.Root>
53
65
  * )
54
66
  * }
55
67
  *
56
- * @example Show the steps horizontally
57
- * // Keep the same indexed Item and Content pairs.
58
- * ;<Stepper.Root count={2} orientation="horizontal">
68
+ * @example Control the step
69
+ * const [step, setStep] = useState<string | null>('details')
70
+ *
71
+ * ;<Stepper.Root items={['details', 'review']} value={step} onValueChange={setStep}>
59
72
  * {
60
73
  * // Rest of components here
61
74
  * }
62
75
  * </Stepper.Root>
63
76
  */
64
- export function Root({ children, className, orientation = 'vertical', ...props }) {
65
- // className is left out, since Root renders no element of its own to receive it
66
- return (_jsx(Steps.Root, { ...props, orientation: orientation, asChild: true, children: _jsx(_Fragment, { children: children }) }));
77
+ export function Root({ items, value, defaultValue = items[0], onValueChange, preventStepClicks = false, children, }) {
78
+ if (new Set(items).size !== items.length)
79
+ throw new Error('Stepper.Root items must not repeat a value.');
80
+ // Ark counts steps by index, with one past the last meaning every step is done
81
+ const toStep = (stepValue) => (stepValue === null ? items.length : indexOf(items, stepValue, 'Root'));
82
+ return (_jsx(StepperContext.Provider, { value: { items, preventStepClicks }, children: _jsx(Steps.Root, { count: items.length, step: value === undefined ? undefined : toStep(value), defaultStep: toStep(defaultValue ?? null), onStepChange: onValueChange && ((details) => onValueChange(details.step === items.length ? null : items[details.step])), orientation: "vertical", linear: preventStepClicks, asChild: true, children: _jsx(_Fragment, { children: children }) }) }));
67
83
  }
68
- /** Moves to the next step. Pass asChild to give this behavior to your own button, like a "Continue" Button; it keeps the state data attributes but none of this part's styling. */
69
- export function NextButton({ asChild, disableStyle, ...props }) {
70
- const styleAttributes = asChildStyleAttributes({ asChild, component: 'stepper-nextbutton', disableStyle });
71
- return _jsx(Steps.NextTrigger, { ...props, asChild: asChild, ...styleAttributes });
84
+ /** Lays out ItemsList on the left of the current Content or CompletedContent. Spacing only, no look of its own. */
85
+ export function Container({ disableStyle, className, ref, ...props }) {
86
+ useStepperContext('Container');
87
+ return (_jsx("div", { ...props, ref: ref, "data-component": "stepper-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
72
88
  }
73
- /** Moves to the previous step. Pass asChild to give this behavior to your own button, like a "Back" Button; it keeps the state data attributes but none of this part's styling. */
74
- export function PreviousButton({ asChild, disableStyle, ...props }) {
75
- const styleAttributes = asChildStyleAttributes({ asChild, component: 'stepper-previousbutton', disableStyle });
76
- return _jsx(Steps.PrevTrigger, { ...props, asChild: asChild, ...styleAttributes });
89
+ /** Holds the Items; screen readers hear it as a tab list, no setup needed. */
90
+ export function ItemsList({ disableStyle, className, ...props }) {
91
+ return _jsx(Steps.List, { ...props, "data-component": "stepper-itemslist", "data-style-disabled": disableStyle ? '' : undefined, className: className });
77
92
  }
78
- export function List({ disableStyle, className, ...props }) {
79
- return (_jsx(Steps.List, { "data-component": "stepper-list", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
93
+ /**
94
+ * One step, as a single button opening its step on click, no click handler needed; does nothing with preventStepClicks.
95
+ * Carries data-current, data-complete or data-incomplete. Its value must be one of Root's items.
96
+ */
97
+ export function Item({ value, disableStyle, className, style, ...props }) {
98
+ const context = useStepperContext('Item');
99
+ // Ark splits a step into an Item and its Trigger; asChild merges them into one button
100
+ return (_jsx(Steps.Item, { index: indexOf(context.items, value, 'Item'), asChild: true, children: _jsx(Steps.Trigger, { ...props, "data-component": "stepper-item", "data-style-disabled": disableStyle ? '' : undefined, "data-prevent-clicks": context.preventStepClicks ? '' : undefined, className: className,
101
+ // Core: the Separator is positioned against it
102
+ style: { position: 'relative', ...style } }) }));
80
103
  }
81
- export function Item({ disableStyle, className, ...props }) {
82
- return (_jsx(Steps.Item, { "data-component": "stepper-item", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
104
+ /** The circle marking the step, always shown. Holds IndicatorIcon and IndicatorText, which take turns automatically. */
105
+ export function Indicator({ disableStyle, className, ref, ...props }) {
106
+ // A span, since it sits inside Item's button
107
+ return (_jsx(Steps.Indicator, { asChild: true, children: _jsx("span", { ...props, ref: ref, "data-component": "stepper-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className }) }));
83
108
  }
84
- /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
85
- export function Indicator({ disableStyle, className, ...props }) {
86
- return (_jsx(Steps.ItemContext, { children: (step) => (_jsx(Steps.Indicator, { "data-component": "stepper-indicator", "data-style-disabled": disableStyle ? '' : undefined, "data-completed": step.completed ? '' : undefined, className: className, ...props, children: step.completed ? (_jsx(Check, { "data-component": "stepper-indicator-1", strokeWidth: 2.5 })) : (_jsx("span", { "data-component": "stepper-indicator-2" })) })) }));
109
+ /** Built-in check icon, shown only once the step is done; renders nothing before. Place inside Indicator. Omit children for the supplied default icon; pass an icon only to replace it. Defaults to strokeWidth 2.5. */
110
+ export function IndicatorIcon({ disableStyle, className, strokeWidth, children, ...props }) {
111
+ const item = useStepsItemContext();
112
+ if (!item.completed)
113
+ return null;
114
+ return cloneElement(children ?? _jsx(Check, {}), {
115
+ 'aria-hidden': true,
116
+ ...props,
117
+ ...itemStateAttributes(item),
118
+ strokeWidth: strokeWidth ?? children?.props.strokeWidth ?? 2.5,
119
+ 'data-component': 'stepper-indicatoricon',
120
+ 'data-style-disabled': disableStyle ? '' : undefined,
121
+ className: twMerge(children?.props.className, className),
122
+ });
87
123
  }
88
- export function Separator({ disableStyle, className, ...props }) {
89
- return (_jsx(Steps.Separator, { "data-component": "stepper-separator", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
124
+ /** The step's number, worked out automatically; renders nothing once the step is done, leaving room for IndicatorIcon. Pass children only to show something else. Place inside Indicator. */
125
+ export function IndicatorText({ disableStyle, className, children, ref, ...props }) {
126
+ const item = useStepsItemContext();
127
+ if (item.completed)
128
+ return null;
129
+ return (_jsx("span", { ...props, ...itemStateAttributes(item), ref: ref, "data-component": "stepper-indicatortext", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: children ?? item.index + 1 }));
90
130
  }
91
- export function Content({ disableStyle, className, ...props }) {
92
- return (_jsx(Steps.Content, { "data-component": "stepper-content", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
131
+ /**
132
+ * Optional small text above ItemTitle, like a date ("Jan 2024") or "Step 1 of 3". Add it only when the steps need that extra context; leave it out otherwise.
133
+ */
134
+ export function ItemMeta({ disableStyle, className, ref, ...props }) {
135
+ const item = useStepsItemContext();
136
+ return (_jsx("span", { ...props, ...itemStateAttributes(item), ref: ref, "data-component": "stepper-itemmeta", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
93
137
  }
138
+ /** The step's name, beside the Indicator. */
139
+ export function ItemTitle({ disableStyle, className, ref, ...props }) {
140
+ const item = useStepsItemContext();
141
+ return (_jsx("span", { ...props, ...itemStateAttributes(item), ref: ref, "data-component": "stepper-itemtitle", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
142
+ }
143
+ /** A short hint under ItemTitle, like "Select product". */
144
+ export function ItemDescription({ disableStyle, className, ref, ...props }) {
145
+ const item = useStepsItemContext();
146
+ return (_jsx("span", { ...props, ...itemStateAttributes(item), ref: ref, "data-component": "stepper-itemdescription", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
147
+ }
148
+ /**
149
+ * The line joining a step to the next one, filled once the step is done. Renders nothing on the last step, so every Item can hold one.
150
+ *
151
+ * Changing its gap from the Indicators: the line lives inside its own Item, stretching between two distances measured from that Item's edges.
152
+ * - top: where the line starts, measured from the top of this Item. It must clear this step's Indicator, so it's the Indicator's height plus the gap you want under it.
153
+ * The preset's top-8.5 (34px) is the 26px Indicator + an 8px gap.
154
+ * - bottom: where the line ends, measured from the bottom of this Item. The next step's Indicator starts right at that edge, so bottom is exactly the gap above the next Indicator.
155
+ * The preset's bottom-1 is a 4px gap.
156
+ * Together they set the line's length: the Item's height minus top minus bottom. A taller Item, like one with a longer description, just makes a longer line with the same gaps.
157
+ * If you resize the Indicator, set top to its new height plus your gap, and left to half its width, so the line stays centered under it.
158
+ *
159
+ * @example Even 8px gaps on both ends
160
+ * // 26px Indicator + 8px gap = top-8.5; 8px gap = bottom-2
161
+ * ;<Stepper.Separator className="top-8.5 bottom-2" />
162
+ *
163
+ * @example A line touching both Indicators
164
+ * // top equals the Indicator's height; bottom is 0
165
+ * ;<Stepper.Separator className="top-6.5 bottom-0" />
166
+ */
167
+ export function Separator({ disableStyle, className, style, ref, ...props }) {
168
+ const item = useStepsItemContext();
169
+ if (item.last)
170
+ return null;
171
+ // A span, since it sits inside Item's button
172
+ return (_jsx(Steps.Separator, { asChild: true, children: _jsx("span", { ...props, ref: ref, "aria-hidden": true, "data-component": "stepper-separator", "data-style-disabled": disableStyle ? '' : undefined, className: className,
173
+ // Core: drawn over the Item; the preset places it
174
+ style: { position: 'absolute', ...style } }) }));
175
+ }
176
+ /** Holds the step's main content, like its form fields. Place inside a Content, above its Footer. Spacing only, no look of its own. */
177
+ export function Body({ disableStyle, className, ref, ...props }) {
178
+ useStepperContext('Body');
179
+ return (_jsx("div", { ...props, ref: ref, "data-component": "stepper-body", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
180
+ }
181
+ /** One step's side, beside ItemsList, showing only while its step is current, no visibility condition needed. Holds the step's Body and Footer. Its value must be one of Root's items. */
182
+ export function Content({ value, disableStyle, className, ...props }) {
183
+ const context = useStepperContext('Content');
184
+ return (_jsx(Steps.Content, { ...props, index: indexOf(context.items, value, 'Content'), "data-component": "stepper-content", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
185
+ }
186
+ /** Shows only once every step is done, after NextButton on the last step. */
94
187
  export function CompletedContent({ disableStyle, className, ...props }) {
95
- return (_jsx(Steps.CompletedContent, { "data-component": "stepper-completedcontent", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
188
+ return _jsx(Steps.CompletedContent, { ...props, "data-component": "stepper-completedcontent", "data-style-disabled": disableStyle ? '' : undefined, className: className });
189
+ }
190
+ /** The row under the step's Body, inside its Content, holding that step's PreviousButton and NextButton directly. Leave it out of a step needing no buttons. */
191
+ export function Footer({ disableStyle, className, ref, ...props }) {
192
+ useStepperContext('Footer');
193
+ return (_jsx("div", { ...props, ref: ref, "data-component": "stepper-footer", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
194
+ }
195
+ /** Moves to the previous step, no click handler needed. Place it in a Content's Footer, never outside a Content; leave it out of the first step's Footer. Pass asChild to give this behavior to your own button, like a "Back" Button; it keeps the state data attributes but none of this part's styling. */
196
+ export function PreviousButton({ asChild, disableStyle, ...props }) {
197
+ return _jsx(Steps.PrevTrigger, { ...props, asChild: asChild, ...asChildStyleAttributes({ asChild, component: 'stepper-previousbutton', disableStyle }) });
198
+ }
199
+ /** Moves to the next step, no click handler needed; on the last step, it finishes them all. Place it in a Content's Footer, never outside a Content, worded for that step, like "I agree". Pass asChild to give this behavior to your own button, like a primary "Continue" Button; it keeps the state data attributes but none of this part's styling. */
200
+ export function NextButton({ asChild, disableStyle, ...props }) {
201
+ return _jsx(Steps.NextTrigger, { ...props, asChild: asChild, ...asChildStyleAttributes({ asChild, component: 'stepper-nextbutton', disableStyle }) });
202
+ }
203
+ function useStepperContext(part) {
204
+ const context = useContext(StepperContext);
205
+ if (!context)
206
+ throw new Error(`Stepper.${part} must be placed inside Stepper.Root.`);
207
+ return context;
208
+ }
209
+ function indexOf(items, value, part) {
210
+ const index = items.indexOf(value);
211
+ if (index === -1)
212
+ throw new Error(`Stepper.${part} got the value "${value}", which is missing from Stepper.Root items.`);
213
+ return index;
96
214
  }
97
- export function OpenButton({ disableStyle, className, ...props }) {
98
- return (_jsx(Steps.Trigger, { "data-component": "stepper-openbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
215
+ // The same step-state attributes Ark puts on its own parts, for the parts rendered here
216
+ function itemStateAttributes(item) {
217
+ return {
218
+ 'data-current': item.current ? '' : undefined,
219
+ 'data-complete': item.completed ? '' : undefined,
220
+ 'data-incomplete': item.incomplete ? '' : undefined,
221
+ };
99
222
  }
@@ -38,22 +38,22 @@ export type RootProps = Pick<BaseSwitch.Root.Props, CoreKeys> & ValidationProps
38
38
  * </Switch.Root>
39
39
  */
40
40
  export declare function Root({ children, validation, checked, defaultChecked, onCheckedChange, id, ...props }: RootProps): import("react").JSX.Element;
41
- export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
42
- export declare const Button: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").SwitchRootProps, "className" | "render" | "nativeButton" | CoreKeys> & {
41
+ export declare function Container({ disableStyle, className, ref, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
42
+ export declare function Button({ disableStyle, className, ref, ...props }: (Omit<BaseSwitch.Root.Props, CoreKeys | 'className' | 'render' | 'nativeButton'> & {
43
43
  className?: string;
44
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
44
+ }) & StyleProps): import("react").JSX.Element;
45
45
  /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
46
- export declare const Indicator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").SwitchThumbProps, "className"> & {
46
+ export declare function Indicator({ disableStyle, className, ref, ...props }: (Omit<BaseSwitch.Thumb.Props, 'className' | 'render'> & {
47
47
  className?: string;
48
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
48
+ }) & StyleProps): import("react").JSX.Element;
49
49
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
50
- export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
51
- export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
50
+ export declare function Label({ disableStyle, className, ref, ...props }: Omit<ComponentProps<'label'>, 'htmlFor'> & StyleProps): import("react").JSX.Element;
51
+ export declare function Description({ disableStyle, className, id, ref, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
52
52
  type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
53
53
  children?: ValidationMessageChildren;
54
54
  };
55
55
  /** Shows itself only while Root's validation is `'error'`: with no children it shows the message from `['error', message]`, a function children formats that message, and other children replace it. */
56
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
56
+ export declare function Error({ children, ref, ...props }: MessageProps): import("react").JSX.Element | null;
57
57
  /** Shows itself only while Root's validation is `'success'`: with no children it shows the message from `['success', message]`, a function children formats that message, and other children replace it. */
58
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
58
+ export declare function Success({ children, ref, ...props }: MessageProps): import("react").JSX.Element | null;
59
59
  export {};