@boxcustodia/library 2.0.0-alpha.12 → 2.0.0-alpha.14

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 (174) hide show
  1. package/dist/index.cjs.js +1 -138
  2. package/dist/index.d.ts +1087 -720
  3. package/dist/index.es.js +7011 -56097
  4. package/dist/theme.css +1 -1
  5. package/package.json +34 -26
  6. package/src/__doc__/Examples.tsx +1 -1
  7. package/src/__doc__/Intro.mdx +3 -3
  8. package/src/__doc__/Tabs.mdx +112 -0
  9. package/src/__doc__/V2.mdx +1246 -0
  10. package/src/components/accordion/accordion.stories.tsx +143 -0
  11. package/src/components/accordion/accordion.tsx +135 -0
  12. package/src/components/accordion/index.ts +1 -0
  13. package/src/components/alert/alert.stories.tsx +24 -4
  14. package/src/components/alert/alert.tsx +17 -9
  15. package/src/components/alert-dialog/alert-dialog.stories.tsx +24 -0
  16. package/src/components/alert-dialog/alert-dialog.test.tsx +1 -1
  17. package/src/components/alert-dialog/alert-dialog.tsx +58 -10
  18. package/src/components/auto-complete/auto-complete.stories.tsx +616 -200
  19. package/src/components/auto-complete/auto-complete.tsx +420 -68
  20. package/src/components/auto-complete/index.ts +0 -1
  21. package/src/components/avatar/avatar.stories.tsx +162 -21
  22. package/src/components/avatar/avatar.tsx +79 -20
  23. package/src/components/button/button.stories.tsx +219 -294
  24. package/src/components/button/button.test.tsx +10 -17
  25. package/src/components/button/button.tsx +78 -19
  26. package/src/components/button/components/base-button.tsx +30 -53
  27. package/src/components/button/index.ts +0 -1
  28. package/src/components/calendar/calendar.stories.tsx +1 -1
  29. package/src/components/calendar/calendar.tsx +4 -4
  30. package/src/components/card/card.stories.tsx +141 -69
  31. package/src/components/card/card.tsx +155 -54
  32. package/src/components/center/center.stories.tsx +22 -39
  33. package/src/components/checkbox/checkbox.stories.tsx +25 -5
  34. package/src/components/checkbox/checkbox.tsx +76 -15
  35. package/src/components/checkbox-group/checkbox-group.stories.tsx +116 -28
  36. package/src/components/checkbox-group/checkbox-group.tsx +84 -3
  37. package/src/components/combobox/combobox.stories.tsx +33 -23
  38. package/src/components/combobox/combobox.tsx +99 -77
  39. package/src/components/date-picker/date-input.stories.tsx +14 -6
  40. package/src/components/date-picker/date-input.tsx +2 -2
  41. package/src/components/date-picker/date-picker.model.ts +13 -4
  42. package/src/components/date-picker/date-picker.stories.tsx +38 -12
  43. package/src/components/date-picker/date-picker.tsx +28 -14
  44. package/src/components/dialog/dialog.stories.tsx +18 -0
  45. package/src/components/dialog/dialog.test.tsx +1 -1
  46. package/src/components/dialog/dialog.tsx +51 -20
  47. package/src/components/divider/divider.stories.tsx +126 -51
  48. package/src/components/divider/divider.tsx +16 -16
  49. package/src/components/dropzone/dropzone.stories.tsx +71 -90
  50. package/src/components/dropzone/dropzone.tsx +383 -105
  51. package/src/components/dropzone/index.ts +0 -1
  52. package/src/components/empty/empty.stories.tsx +165 -0
  53. package/src/components/empty/empty.tsx +156 -0
  54. package/src/components/empty/index.ts +1 -0
  55. package/src/components/field/field.stories.tsx +227 -4
  56. package/src/components/field/field.tsx +77 -42
  57. package/src/components/form/form.stories.tsx +320 -197
  58. package/src/components/form/form.tsx +3 -23
  59. package/src/components/index.ts +2 -6
  60. package/src/components/input/input.stories.tsx +5 -5
  61. package/src/components/input/input.tsx +4 -4
  62. package/src/components/kbd/kbd.stories.tsx +1 -0
  63. package/src/components/label/label.stories.tsx +16 -0
  64. package/src/components/label/label.tsx +13 -2
  65. package/src/components/loader/loader.stories.tsx +7 -5
  66. package/src/components/loader/loader.tsx +8 -3
  67. package/src/components/menu/menu-primitives.tsx +207 -196
  68. package/src/components/menu/menu.stories.tsx +276 -146
  69. package/src/components/menu/menu.tsx +146 -54
  70. package/src/components/number-input/number-input.stories.tsx +27 -4
  71. package/src/components/number-input/number-input.test.tsx +2 -2
  72. package/src/components/number-input/number-input.tsx +31 -33
  73. package/src/components/otp/index.ts +1 -0
  74. package/src/components/otp/otp.stories.tsx +209 -0
  75. package/src/components/otp/otp.tsx +100 -0
  76. package/src/components/pagination/index.ts +1 -0
  77. package/src/components/pagination/pagination.model.ts +2 -0
  78. package/src/components/pagination/pagination.stories.tsx +154 -59
  79. package/src/components/pagination/pagination.test.tsx +122 -57
  80. package/src/components/pagination/pagination.tsx +575 -77
  81. package/src/components/password/password.stories.tsx +18 -3
  82. package/src/components/password/password.tsx +29 -9
  83. package/src/components/popover/popover.stories.tsx +26 -5
  84. package/src/components/popover/popover.tsx +15 -23
  85. package/src/components/progress/progress.stories.tsx +1 -0
  86. package/src/components/radio-group/index.ts +1 -0
  87. package/src/components/radio-group/radio-group.stories.tsx +251 -0
  88. package/src/components/radio-group/radio-group.tsx +212 -0
  89. package/src/components/scroll-area/scroll-area.stories.tsx +1 -0
  90. package/src/components/select/select.stories.tsx +118 -19
  91. package/src/components/select/select.tsx +67 -62
  92. package/src/components/skeleton/skeleton.stories.tsx +1 -0
  93. package/src/components/stack/stack.stories.tsx +179 -89
  94. package/src/components/stack/stack.tsx +2 -2
  95. package/src/components/stepper/index.ts +1 -1
  96. package/src/components/stepper/stepper.stories.tsx +767 -83
  97. package/src/components/stepper/stepper.test.tsx +18 -18
  98. package/src/components/stepper/stepper.tsx +554 -0
  99. package/src/components/switch/switch.stories.tsx +15 -1
  100. package/src/components/switch/switch.tsx +17 -4
  101. package/src/components/table/index.ts +0 -2
  102. package/src/components/table/table.stories.tsx +131 -18
  103. package/src/components/table/table.test.tsx +1 -1
  104. package/src/components/table/table.tsx +183 -77
  105. package/src/components/tabs/tabs.stories.tsx +373 -155
  106. package/src/components/tabs/tabs.test.tsx +12 -12
  107. package/src/components/tabs/tabs.tsx +72 -149
  108. package/src/components/tag/index.ts +0 -1
  109. package/src/components/tag/tag.stories.tsx +155 -120
  110. package/src/components/tag/tag.tsx +47 -95
  111. package/src/components/textarea/textarea.stories.tsx +8 -22
  112. package/src/components/textarea/textarea.tsx +17 -79
  113. package/src/components/timeline/timeline.stories.tsx +323 -42
  114. package/src/components/timeline/timeline.tsx +359 -132
  115. package/src/components/toast/toast.stories.tsx +1 -0
  116. package/src/components/tooltip/tooltip.tsx +11 -9
  117. package/src/components/tree/index.ts +0 -1
  118. package/src/components/tree/tree.stories.tsx +365 -408
  119. package/src/components/tree/tree.test.tsx +163 -0
  120. package/src/components/tree/tree.tsx +212 -36
  121. package/src/hooks/useAsync/__doc__/useAsync.stories.tsx +5 -5
  122. package/src/hooks/useClipboard/__doc__/useClipboard.stories.tsx +1 -3
  123. package/src/hooks/useDebounceCallback/__doc__/useDebouncedCallback.stories.tsx +6 -6
  124. package/src/hooks/useDocumentTitle/__doc__/useDocumentTitle.stories.tsx +1 -1
  125. package/src/hooks/useEventListener/__test__/useEventListener.test.tsx +1 -1
  126. package/src/hooks/useLocalStorage/__doc__/useLocalStorage.stories.tsx +1 -1
  127. package/src/hooks/usePagination/usePagination.tsx +36 -24
  128. package/src/styles/theme.css +1 -1
  129. package/src/utils/form.tsx +67 -37
  130. package/src/utils/index.ts +1 -1
  131. package/src/__doc__/Migration.mdx +0 -475
  132. package/src/components/auto-complete/auto-complete-primitives.tsx +0 -155
  133. package/src/components/background-image/background-image.stories.tsx +0 -21
  134. package/src/components/background-image/background-image.test.tsx +0 -29
  135. package/src/components/background-image/background-image.tsx +0 -23
  136. package/src/components/background-image/index.ts +0 -1
  137. package/src/components/button/button.variants.ts +0 -44
  138. package/src/components/button/components/loader-overlay.tsx +0 -21
  139. package/src/components/button/components/loading-icon.tsx +0 -47
  140. package/src/components/dropzone/upload-primitives.tsx +0 -310
  141. package/src/components/dropzone/use-dropzone.ts +0 -122
  142. package/src/components/empty-state/empty-state.stories.tsx +0 -56
  143. package/src/components/empty-state/empty-state.tsx +0 -39
  144. package/src/components/empty-state/index.ts +0 -1
  145. package/src/components/heading/heading.stories.tsx +0 -74
  146. package/src/components/heading/heading.tsx +0 -28
  147. package/src/components/heading/heading.variants.ts +0 -27
  148. package/src/components/heading/index.ts +0 -1
  149. package/src/components/kbd/kbd.variants.ts +0 -26
  150. package/src/components/menu/util/render-menu-item.tsx +0 -54
  151. package/src/components/multi-select/hooks/use-multi-select.ts +0 -66
  152. package/src/components/multi-select/index.ts +0 -1
  153. package/src/components/multi-select/multi-select.stories.tsx +0 -294
  154. package/src/components/multi-select/multi-select.tsx +0 -300
  155. package/src/components/multi-select/multi-select.variants.ts +0 -22
  156. package/src/components/pagination/components/pagination-option.tsx +0 -27
  157. package/src/components/show/index.ts +0 -1
  158. package/src/components/show/show.stories.tsx +0 -197
  159. package/src/components/show/show.test.tsx +0 -41
  160. package/src/components/show/show.tsx +0 -16
  161. package/src/components/stepper/Stepper.tsx +0 -190
  162. package/src/components/stepper/context/stepper-context.tsx +0 -11
  163. package/src/components/table/table-primitives.tsx +0 -122
  164. package/src/components/table/table.model.ts +0 -20
  165. package/src/components/table-pagination/index.ts +0 -2
  166. package/src/components/table-pagination/table-pagination.model.ts +0 -2
  167. package/src/components/table-pagination/table-pagination.stories.tsx +0 -23
  168. package/src/components/table-pagination/table-pagination.test.tsx +0 -32
  169. package/src/components/table-pagination/table-pagination.tsx +0 -108
  170. package/src/components/tabs/context/tabs-context.tsx +0 -14
  171. package/src/components/tag/tag.variants.ts +0 -31
  172. package/src/components/timeline/timeline-status.ts +0 -5
  173. package/src/components/tree/hooks/use-controllable-tree-state.ts +0 -80
  174. package/src/components/tree/tree-primitives.tsx +0 -126
@@ -1,147 +1,374 @@
1
- import { HTMLProps, ReactNode } from "react";
1
+ import { mergeProps } from "@base-ui/react/merge-props";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
4
+ import { createContext, type ReactNode, useContext } from "react";
5
+
2
6
  import { cn } from "../../lib";
3
- import { TimelineStatus } from "./timeline-status";
4
7
 
5
- interface ItemTimeline {
6
- content?: ReactNode;
7
- icon?: ReactNode;
8
- status?: "done" | "pending" | "error";
9
- color?: string;
8
+ type TimelineOrientation = "horizontal" | "vertical";
9
+
10
+ interface TimelineContextValue {
11
+ activeStep: number;
12
+ setActiveStep: (step: number) => void;
10
13
  }
11
14
 
12
- interface TimelineProps {
13
- items: ItemTimeline[];
14
- itemsProps?: HTMLProps<HTMLDivElement>;
15
- containerProps?: HTMLProps<HTMLUListElement>;
16
- classNameContainer?: string;
17
- classNameItem?: string;
18
- classNameItemDot?: string;
19
- classNameItemContainerDot?: string;
20
- classNameItemContent?: string;
15
+ const TimelineContext = createContext<TimelineContextValue | undefined>(
16
+ undefined,
17
+ );
18
+
19
+ function useTimeline() {
20
+ const context = useContext(TimelineContext);
21
+ if (!context) {
22
+ throw new Error("useTimeline must be used within a TimelineRoot");
23
+ }
24
+ return context;
21
25
  }
22
- export const Timeline = ({
23
- items,
24
- classNameContainer,
25
- containerProps,
26
- ...itemsProps
27
- }: TimelineProps) => {
28
- return (
29
- <TimelineRoot className={classNameContainer} {...containerProps}>
30
- {items.map((item: ItemTimeline, i) => (
31
- <TimelineListItem
32
- key={i}
33
- icon={item.icon}
34
- color={item.color}
35
- status={item.status}
36
- {...itemsProps}
37
- >
38
- {item.content}
39
- </TimelineListItem>
40
- ))}
41
- </TimelineRoot>
42
- );
43
- };
44
26
 
45
- export const TimelineRoot = (props: HTMLProps<HTMLUListElement>) => {
46
- return (
47
- <ul
48
- data-slot="timeline"
49
- {...props}
50
- className={cn(
51
- "relative flex justify-center flex-col border-input",
52
- props.className,
53
- )}
54
- />
55
- );
56
- };
57
-
58
- interface TimelineListItemProps extends HTMLProps<HTMLLIElement> {
59
- icon?: ReactNode;
60
- status?: "done" | "pending" | "error";
61
- color?: string;
62
- itemsProps?: HTMLProps<HTMLDivElement>;
63
- classNameContainer?: string;
64
- classNameItemDot?: string;
65
- classNameItemContainerDot?: string;
66
- classNameItemContent?: string;
27
+ interface TimelineRootProps extends useRender.ComponentProps<"div"> {
28
+ defaultValue?: number;
29
+ value?: number;
30
+ onValueChange?: (value: number) => void;
31
+ orientation?: TimelineOrientation;
67
32
  }
68
- export const TimelineListItem = ({
69
- icon,
70
- status,
71
- color,
72
- classNameItemDot,
73
- classNameItemContainerDot,
74
- classNameItemContent,
75
- itemsProps,
33
+
34
+ export function TimelineRoot({
35
+ defaultValue = 1,
36
+ value,
37
+ onValueChange,
38
+ orientation = "vertical",
39
+ className,
40
+ render,
76
41
  children,
77
42
  ...props
78
- }: TimelineListItemProps) => {
43
+ }: TimelineRootProps) {
44
+ const [activeStep = 1, setActiveStep] = useControllableState<number>({
45
+ prop: value,
46
+ defaultProp: defaultValue,
47
+ onChange: onValueChange,
48
+ });
49
+
50
+ const defaultProps = {
51
+ className: cn(
52
+ "group/timeline flex data-[orientation=horizontal]:w-full data-[orientation=horizontal]:flex-row data-[orientation=vertical]:flex-col",
53
+ className,
54
+ ),
55
+ "data-orientation": orientation,
56
+ "data-slot": "timeline",
57
+ children,
58
+ };
59
+
79
60
  return (
80
- <li
81
- data-slot="timeline-item"
82
- className={cn(
83
- "rounded-lg w-full px-2 gap-1 grid hover:bg-muted transition-colors ease-in grid-cols-[minmax(auto,20px)_1fr]",
84
- props.className,
85
- )}
86
- {...props}
87
- >
88
- <TimelineItemDot
89
- icon={icon}
90
- status={status}
91
- color={color}
92
- classNameDot={classNameItemDot}
93
- classNameContainerDot={classNameItemContainerDot}
94
- />
95
- <TimelineItemContent className={classNameItemContent} {...itemsProps}>
96
- {children}
97
- </TimelineItemContent>
98
- </li>
61
+ <TimelineContext.Provider value={{ activeStep, setActiveStep }}>
62
+ {useRender({
63
+ defaultTagName: "div",
64
+ render,
65
+ props: mergeProps<"div">(defaultProps, props),
66
+ })}
67
+ </TimelineContext.Provider>
99
68
  );
100
- };
101
-
102
- interface TimelineItemDotProps {
103
- icon?: ReactNode;
104
- status?: "done" | "pending" | "error";
105
- color?: string;
106
- classNameDot?: string;
107
- classNameContainerDot?: string;
108
69
  }
109
- export const TimelineItemDot = ({
110
- icon,
111
- status = "pending",
112
- color,
113
- classNameDot,
114
- classNameContainerDot,
115
- }: TimelineItemDotProps) => {
116
- return (
117
- <div
118
- data-slot="timeline-item-dot"
119
- className={cn(
120
- "relative pb-6 last:after:hidden after:absolute after:top-0 after:bottom-0 after:left-1/2 after:w-px after:-translate-x-1/2 after:bg-gray-200",
121
- classNameContainerDot,
122
- )}
123
- >
124
- <div
125
- data-slot="timeline-item-dot-icon"
126
- className={cn(
127
- "relative z-10 flex text-white items-center justify-center rounded-full left-1/2 -translate-x-1/2",
128
- icon ? "aspect-square p-1.5 min-h-7 min-w-7 top-2" : "size-2 top-4",
129
- classNameDot,
130
- )}
131
- style={{ backgroundColor: color || TimelineStatus?.[status] }}
132
- >
133
- {icon}
134
- </div>
135
- </div>
136
- );
137
- };
138
70
 
139
- export const TimelineItemContent = (props: HTMLProps<HTMLDivElement>) => {
71
+ interface TimelineItemProps extends useRender.ComponentProps<"div"> {
72
+ step: number;
73
+ }
74
+
75
+ export function TimelineItem({
76
+ step,
77
+ className,
78
+ render,
79
+ children,
80
+ ...props
81
+ }: TimelineItemProps) {
82
+ const { activeStep } = useTimeline();
83
+
84
+ const defaultProps = {
85
+ className: cn(
86
+ "group/timeline-item relative flex flex-1 flex-col gap-0.5 group-data-[orientation=vertical]/timeline:ms-8 group-data-[orientation=horizontal]/timeline:mt-8 group-data-[orientation=horizontal]/timeline:not-last:pe-8 group-data-[orientation=vertical]/timeline:not-last:pb-6 has-[+[data-completed]]:**:data-[slot=timeline-separator]:bg-primary",
87
+ className,
88
+ ),
89
+ "data-completed": step <= activeStep || undefined,
90
+ "data-slot": "timeline-item",
91
+ children,
92
+ };
93
+
94
+ return useRender({
95
+ defaultTagName: "div",
96
+ render,
97
+ props: mergeProps<"div">(defaultProps, props),
98
+ });
99
+ }
100
+
101
+ export function TimelineHeader({
102
+ className,
103
+ render,
104
+ children,
105
+ ...props
106
+ }: useRender.ComponentProps<"div">) {
107
+ const defaultProps = {
108
+ className: cn(className),
109
+ "data-slot": "timeline-header",
110
+ children,
111
+ };
112
+
113
+ return useRender({
114
+ defaultTagName: "div",
115
+ render,
116
+ props: mergeProps<"div">(defaultProps, props),
117
+ });
118
+ }
119
+
120
+ export function TimelineTitle({
121
+ className,
122
+ render,
123
+ children,
124
+ ...props
125
+ }: useRender.ComponentProps<"h3">) {
126
+ const defaultProps = {
127
+ className: cn("font-medium text-sm", className),
128
+ "data-slot": "timeline-title",
129
+ children,
130
+ };
131
+
132
+ return useRender({
133
+ defaultTagName: "h3",
134
+ render,
135
+ props: mergeProps<"h3">(defaultProps, props),
136
+ });
137
+ }
138
+
139
+ export function TimelineDate({
140
+ className,
141
+ render,
142
+ children,
143
+ ...props
144
+ }: useRender.ComponentProps<"time">) {
145
+ const defaultProps = {
146
+ className: cn(
147
+ "mb-1 block font-medium text-muted-foreground text-xs group-data-[orientation=vertical]/timeline:max-sm:h-4",
148
+ className,
149
+ ),
150
+ "data-slot": "timeline-date",
151
+ children,
152
+ };
153
+
154
+ return useRender({
155
+ defaultTagName: "time",
156
+ render,
157
+ props: mergeProps<"time">(defaultProps, props),
158
+ });
159
+ }
160
+
161
+ export function TimelineContent({
162
+ className,
163
+ render,
164
+ children,
165
+ ...props
166
+ }: useRender.ComponentProps<"div">) {
167
+ const defaultProps = {
168
+ className: cn("text-muted-foreground text-sm", className),
169
+ "data-slot": "timeline-content",
170
+ children,
171
+ };
172
+
173
+ return useRender({
174
+ defaultTagName: "div",
175
+ render,
176
+ props: mergeProps<"div">(defaultProps, props),
177
+ });
178
+ }
179
+
180
+ export function TimelineIndicator({
181
+ className,
182
+ render,
183
+ children,
184
+ ...props
185
+ }: useRender.ComponentProps<"div">) {
186
+ const defaultProps = {
187
+ "aria-hidden": true,
188
+ className: cn(
189
+ "group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2 absolute size-4 rounded-full border-2 border-primary/20 group-data-[orientation=vertical]/timeline:top-0 group-data-[orientation=horizontal]/timeline:left-0 group-data-completed/timeline-item:border-primary",
190
+ className,
191
+ ),
192
+ "data-slot": "timeline-indicator",
193
+ children,
194
+ };
195
+
196
+ return useRender({
197
+ defaultTagName: "div",
198
+ render,
199
+ props: mergeProps<"div">(defaultProps, props),
200
+ });
201
+ }
202
+
203
+ export function TimelineSeparator({
204
+ className,
205
+ render,
206
+ children,
207
+ ...props
208
+ }: useRender.ComponentProps<"div">) {
209
+ const defaultProps = {
210
+ "aria-hidden": true,
211
+ className: cn(
212
+ "group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2 absolute self-start bg-primary/10 group-last/timeline-item:hidden group-data-[orientation=horizontal]/timeline:h-0.5 group-data-[orientation=vertical]/timeline:h-[calc(100%-1rem-0.25rem)] group-data-[orientation=horizontal]/timeline:w-[calc(100%-1rem-0.25rem)] group-data-[orientation=vertical]/timeline:w-0.5 group-data-[orientation=horizontal]/timeline:translate-x-4.5 group-data-[orientation=vertical]/timeline:translate-y-4.5",
213
+ className,
214
+ ),
215
+ "data-slot": "timeline-separator",
216
+ children,
217
+ };
218
+
219
+ return useRender({
220
+ defaultTagName: "div",
221
+ render,
222
+ props: mergeProps<"div">(defaultProps, props),
223
+ });
224
+ }
225
+
226
+ type TimelineVariant = "default" | "alternate" | "date-left";
227
+
228
+ interface TimelineItemData {
229
+ title?: ReactNode;
230
+ content?: ReactNode;
231
+ date?: ReactNode;
232
+ indicator?: ReactNode;
233
+ }
234
+
235
+ interface TimelineProps extends Omit<TimelineRootProps, "children"> {
236
+ items: TimelineItemData[];
237
+ variant?: TimelineVariant;
238
+ /** Styles applied to each internal slot. */
239
+ classNames?: {
240
+ /** Single timeline entry wrapper. */
241
+ item?: string;
242
+ /** Row that holds the indicator, date, and title. */
243
+ header?: string;
244
+ /** Title text inside the header. */
245
+ title?: string;
246
+ /** Date label inside the header. */
247
+ date?: string;
248
+ /** Body text below the header. */
249
+ content?: string;
250
+ /** Round dot marking the step. */
251
+ indicator?: string;
252
+ /** Line connecting consecutive items. */
253
+ separator?: string;
254
+ };
255
+ }
256
+
257
+ export function Timeline({
258
+ items,
259
+ variant = "default",
260
+ classNames,
261
+ ...props
262
+ }: TimelineProps) {
140
263
  return (
141
- <div
142
- data-slot="timeline-item-content"
143
- {...props}
144
- className={cn("grow px-2 pb-4 pt-2", props.className)}
145
- />
264
+ <TimelineRoot {...props}>
265
+ {items.map((item, i) => {
266
+ if (variant === "alternate") {
267
+ return (
268
+ <TimelineItem
269
+ key={i}
270
+ step={i + 1}
271
+ className={cn(
272
+ "w-[calc(50%-1.5rem)] odd:ms-auto even:me-auto even:text-right",
273
+ "even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8",
274
+ "even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:-right-6 even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:left-auto even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:translate-x-1/2",
275
+ "even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:-right-6 even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:left-auto even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:translate-x-1/2",
276
+ classNames?.item,
277
+ )}
278
+ >
279
+ <TimelineHeader className={classNames?.header}>
280
+ <TimelineSeparator className={classNames?.separator} />
281
+ {item.date ? (
282
+ <TimelineDate className={classNames?.date}>
283
+ {item.date}
284
+ </TimelineDate>
285
+ ) : null}
286
+ {item.title ? (
287
+ <TimelineTitle className={classNames?.title}>
288
+ {item.title}
289
+ </TimelineTitle>
290
+ ) : null}
291
+ <TimelineIndicator className={classNames?.indicator}>
292
+ {item.indicator}
293
+ </TimelineIndicator>
294
+ </TimelineHeader>
295
+ {item.content ? (
296
+ <TimelineContent className={classNames?.content}>
297
+ {item.content}
298
+ </TimelineContent>
299
+ ) : null}
300
+ </TimelineItem>
301
+ );
302
+ }
303
+
304
+ if (variant === "date-left") {
305
+ return (
306
+ <TimelineItem
307
+ key={i}
308
+ step={i + 1}
309
+ className={cn(
310
+ "sm:group-data-[orientation=vertical]/timeline:ms-32",
311
+ classNames?.item,
312
+ )}
313
+ >
314
+ <TimelineHeader className={classNames?.header}>
315
+ <TimelineSeparator className={classNames?.separator} />
316
+ {item.date ? (
317
+ <TimelineDate
318
+ className={cn(
319
+ "sm:group-data-[orientation=vertical]/timeline:absolute sm:group-data-[orientation=vertical]/timeline:-left-32 sm:group-data-[orientation=vertical]/timeline:w-20 sm:group-data-[orientation=vertical]/timeline:text-right",
320
+ classNames?.date,
321
+ )}
322
+ >
323
+ {item.date}
324
+ </TimelineDate>
325
+ ) : null}
326
+ {item.title ? (
327
+ <TimelineTitle
328
+ className={cn("sm:-mt-0.5", classNames?.title)}
329
+ >
330
+ {item.title}
331
+ </TimelineTitle>
332
+ ) : null}
333
+ <TimelineIndicator className={classNames?.indicator}>
334
+ {item.indicator}
335
+ </TimelineIndicator>
336
+ </TimelineHeader>
337
+ {item.content ? (
338
+ <TimelineContent className={classNames?.content}>
339
+ {item.content}
340
+ </TimelineContent>
341
+ ) : null}
342
+ </TimelineItem>
343
+ );
344
+ }
345
+
346
+ return (
347
+ <TimelineItem key={i} step={i + 1} className={classNames?.item}>
348
+ <TimelineHeader className={classNames?.header}>
349
+ {item.date ? (
350
+ <TimelineDate className={classNames?.date}>
351
+ {item.date}
352
+ </TimelineDate>
353
+ ) : null}
354
+ {item.title ? (
355
+ <TimelineTitle className={classNames?.title}>
356
+ {item.title}
357
+ </TimelineTitle>
358
+ ) : null}
359
+ </TimelineHeader>
360
+ <TimelineIndicator className={classNames?.indicator}>
361
+ {item.indicator}
362
+ </TimelineIndicator>
363
+ <TimelineSeparator className={classNames?.separator} />
364
+ {item.content ? (
365
+ <TimelineContent className={classNames?.content}>
366
+ {item.content}
367
+ </TimelineContent>
368
+ ) : null}
369
+ </TimelineItem>
370
+ );
371
+ })}
372
+ </TimelineRoot>
146
373
  );
147
- };
374
+ }
@@ -63,6 +63,7 @@ import {
63
63
  const meta: Meta<typeof ToastProvider> = {
64
64
  title: "Components/Toast",
65
65
  component: ToastProvider,
66
+ parameters: { layout: "centered" },
66
67
  };
67
68
 
68
69
  export default meta;
@@ -101,14 +101,16 @@ export type TooltipProps = Omit<RootProps, "children"> &
101
101
  delay?: TriggerProps["delay"];
102
102
  /** Delay in ms before the tooltip closes. @default 0 */
103
103
  closeDelay?: TriggerProps["closeDelay"];
104
- /** Additional classes applied to the tooltip popup. */
104
+ /** Additional classes applied to the tooltip popup (visual root). */
105
105
  className?: string;
106
- /**
107
- * Additional classes applied to the arrow.
108
- * Pass a `text-*` class to change the arrow color when overriding the popup background.
109
- * @example arrowClassName="text-primary"
110
- */
111
- arrowClassName?: string;
106
+ /** Styles applied to each internal slot. */
107
+ classNames?: {
108
+ /**
109
+ * Arrow that points at the trigger. Pass a `text-*` class to change the
110
+ * arrow color when overriding the popup background.
111
+ */
112
+ arrow?: string;
113
+ };
112
114
  };
113
115
 
114
116
  /**
@@ -134,7 +136,7 @@ export function Tooltip({
134
136
  delay,
135
137
  closeDelay,
136
138
  className,
137
- arrowClassName,
139
+ classNames,
138
140
  ...triggerProps
139
141
  }: TooltipProps) {
140
142
  return (
@@ -157,7 +159,7 @@ export function Tooltip({
157
159
  className="z-float"
158
160
  >
159
161
  <TooltipPopup className={className}>
160
- <TooltipArrow className={arrowClassName} />
162
+ <TooltipArrow className={classNames?.arrow} />
161
163
  {content}
162
164
  </TooltipPopup>
163
165
  </TooltipBase.Positioner>
@@ -1,2 +1 @@
1
1
  export * from "./tree";
2
- export * from "./tree-primitives";