@boyernick/standard-ui-react 0.1.1-canary.3 → 0.1.1-canary.34
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/package.json +5 -3
- package/src/accordion.tsx +5 -2
- package/src/alert-dialog.tsx +1 -1
- package/src/attachment.tsx +5 -2
- package/src/autocomplete.tsx +12 -9
- package/src/badge.tsx +73 -9
- package/src/block-editor.tsx +1747 -0
- package/src/brand.tsx +2 -2
- package/src/breadcrumb.tsx +46 -21
- package/src/button.tsx +23 -12
- package/src/calendar.tsx +25 -11
- package/src/card.tsx +57 -14
- package/src/carousel.tsx +339 -15
- package/src/checkbox.tsx +36 -13
- package/src/code-block.tsx +66 -5
- package/src/collapsible.tsx +7 -3
- package/src/combobox.tsx +17 -15
- package/src/command.tsx +41 -14
- package/src/context-menu.tsx +6 -3
- package/src/date-picker.tsx +174 -0
- package/src/dialog.tsx +33 -10
- package/src/empty.tsx +4 -4
- package/src/field.tsx +4 -3
- package/src/filter-group.tsx +143 -0
- package/src/icons.tsx +55 -1
- package/src/illustrations.tsx +219 -141
- package/src/index.ts +263 -18
- package/src/input.tsx +8 -5
- package/src/kbd.tsx +49 -0
- package/src/lib/focus.ts +41 -0
- package/src/lib/motion.ts +16 -1
- package/src/lib/popup.ts +45 -0
- package/src/lifeline/company-icon.tsx +71 -0
- package/src/lifeline/index.ts +42 -0
- package/src/lifeline/lifeline-data.ts +97 -0
- package/src/lifeline/lifeline-desktop.tsx +204 -0
- package/src/lifeline/lifeline-event.tsx +108 -0
- package/src/lifeline/lifeline-fireworks.tsx +302 -0
- package/src/lifeline/lifeline-hover-image.tsx +269 -0
- package/src/lifeline/lifeline-icons.tsx +39 -0
- package/src/lifeline/lifeline-intro-timing.ts +105 -0
- package/src/lifeline/lifeline-labels.tsx +24 -0
- package/src/lifeline/lifeline-layout.ts +1 -0
- package/src/lifeline/lifeline-legend.tsx +31 -0
- package/src/lifeline/lifeline-lightbox.tsx +309 -0
- package/src/lifeline/lifeline-marker.tsx +183 -0
- package/src/lifeline/lifeline-people.tsx +99 -0
- package/src/lifeline/lifeline-photos.tsx +366 -0
- package/src/lifeline/lifeline-shell.tsx +135 -0
- package/src/lifeline/lifeline-utils.ts +83 -0
- package/src/lifeline/lifeline-vertical.tsx +482 -0
- package/src/lifeline/lifeline.tsx +69 -0
- package/src/lifeline/types.ts +112 -0
- package/src/lifeline/use-lifeline-intro.ts +130 -0
- package/src/lifeline/use-lifeline-scroll.ts +1011 -0
- package/src/lifeline/use-lifeline-vertical-scroll.ts +271 -0
- package/src/menu.tsx +7 -4
- package/src/menubar.tsx +9 -2
- package/src/minimap.tsx +296 -0
- package/src/modal.tsx +608 -0
- package/src/navigation-menu.tsx +340 -67
- package/src/number-field.tsx +336 -61
- package/src/otp-field.tsx +4 -3
- package/src/pagination.tsx +262 -42
- package/src/password-protection.tsx +345 -0
- package/src/popover.tsx +3 -1
- package/src/preview-card.tsx +3 -1
- package/src/progress.tsx +5 -0
- package/src/questionnaire.tsx +284 -0
- package/src/radio.tsx +4 -2
- package/src/scroll-area.tsx +4 -1
- package/src/select.tsx +12 -7
- package/src/sidebar.tsx +113 -28
- package/src/slider.tsx +66 -6
- package/src/sounds.tsx +6 -10
- package/src/spinner.tsx +105 -32
- package/src/switch.tsx +4 -1
- package/src/table.tsx +82 -15
- package/src/tabs.tsx +189 -38
- package/src/text-animate.tsx +71 -28
- package/src/textarea.tsx +6 -1
- package/src/timeline.tsx +378 -0
- package/src/toast.tsx +214 -35
- package/src/toggle.tsx +4 -2
- package/src/toolbar.tsx +12 -7
- package/src/tooltip.tsx +43 -3
- package/src/video-player.tsx +396 -127
- package/src/image-modal.tsx +0 -110
- package/src/markdown-editor.tsx +0 -302
package/src/preview-card.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card"
|
|
|
4
4
|
import type { ComponentProps } from "react"
|
|
5
5
|
import { cn } from "./lib/cn"
|
|
6
6
|
import { motion } from "./lib/motion"
|
|
7
|
+
import { popupSurface } from "./lib/popup"
|
|
7
8
|
|
|
8
9
|
export type PreviewCardProps = ComponentProps<typeof BasePreviewCard.Root>
|
|
9
10
|
export type PreviewCardTriggerProps = ComponentProps<
|
|
@@ -67,7 +68,8 @@ export const PreviewCardPopup = ({
|
|
|
67
68
|
}: PreviewCardPopupProps) => (
|
|
68
69
|
<BasePreviewCard.Popup
|
|
69
70
|
className={cn(
|
|
70
|
-
"z-50 w-72 overflow-hidden
|
|
71
|
+
"z-50 w-72 overflow-hidden p-4",
|
|
72
|
+
popupSurface,
|
|
71
73
|
motion.popupAnchor,
|
|
72
74
|
className,
|
|
73
75
|
)}
|
package/src/progress.tsx
CHANGED
|
@@ -53,6 +53,11 @@ export const ProgressIndicator = ({
|
|
|
53
53
|
<BaseProgress.Indicator
|
|
54
54
|
className={cn(
|
|
55
55
|
"h-full rounded-full bg-brand-primary transition-[width] duration-[var(--duration-lg)] ease-enter motion-reduce:transition-none",
|
|
56
|
+
// Base UI flags a null value with data-indeterminate and leaves the
|
|
57
|
+
// indicator full width, so without this the bar reads as complete.
|
|
58
|
+
// A quarter-width stripe crossing the track on the passive curve —
|
|
59
|
+
// ambient, system-initiated movement.
|
|
60
|
+
"data-indeterminate:w-1/4 data-indeterminate:animate-[progress-indeterminate_1.4s_var(--ease-passive)_infinite] motion-reduce:animate-none",
|
|
56
61
|
className,
|
|
57
62
|
)}
|
|
58
63
|
{...props}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Questionnaire as BaseQuestionnaire } from "@shadcn/react/questionnaire"
|
|
4
|
+
import type { VariantProps } from "class-variance-authority"
|
|
5
|
+
import type { ComponentProps } from "react"
|
|
6
|
+
import { buttonVariants } from "./button"
|
|
7
|
+
import { inputVariants } from "./input"
|
|
8
|
+
import { cn } from "./lib/cn"
|
|
9
|
+
import { focusRing, focusRingBorder } from "./lib/focus"
|
|
10
|
+
|
|
11
|
+
type StyledProps<T> = Omit<T, "className"> & { className?: string }
|
|
12
|
+
|
|
13
|
+
export type QuestionnaireProps = StyledProps<
|
|
14
|
+
ComponentProps<typeof BaseQuestionnaire.Root>
|
|
15
|
+
>
|
|
16
|
+
export type QuestionnaireProgressProps = StyledProps<
|
|
17
|
+
ComponentProps<typeof BaseQuestionnaire.Progress>
|
|
18
|
+
>
|
|
19
|
+
export type QuestionnaireItemProps = StyledProps<
|
|
20
|
+
ComponentProps<typeof BaseQuestionnaire.Item>
|
|
21
|
+
>
|
|
22
|
+
export type QuestionnaireTitleProps = StyledProps<
|
|
23
|
+
ComponentProps<typeof BaseQuestionnaire.Title>
|
|
24
|
+
>
|
|
25
|
+
export type QuestionnaireDescriptionProps = StyledProps<
|
|
26
|
+
ComponentProps<typeof BaseQuestionnaire.Description>
|
|
27
|
+
>
|
|
28
|
+
export type QuestionnaireChoicesProps = StyledProps<
|
|
29
|
+
ComponentProps<typeof BaseQuestionnaire.Choices>
|
|
30
|
+
>
|
|
31
|
+
export type QuestionnaireChoiceInputProps = StyledProps<
|
|
32
|
+
ComponentProps<typeof BaseQuestionnaire.ChoiceInput>
|
|
33
|
+
>
|
|
34
|
+
export type QuestionnaireChoiceLabelProps = StyledProps<
|
|
35
|
+
ComponentProps<typeof BaseQuestionnaire.ChoiceLabel>
|
|
36
|
+
>
|
|
37
|
+
export type QuestionnaireChoiceShortcutProps = StyledProps<
|
|
38
|
+
ComponentProps<typeof BaseQuestionnaire.ChoiceShortcut>
|
|
39
|
+
>
|
|
40
|
+
export type QuestionnaireChoiceProps = StyledProps<
|
|
41
|
+
ComponentProps<typeof BaseQuestionnaire.Choice>
|
|
42
|
+
> & {
|
|
43
|
+
inputProps?: QuestionnaireChoiceInputProps
|
|
44
|
+
labelProps?: QuestionnaireChoiceLabelProps
|
|
45
|
+
shortcutProps?: QuestionnaireChoiceShortcutProps
|
|
46
|
+
}
|
|
47
|
+
export type QuestionnaireInputProps = StyledProps<
|
|
48
|
+
Omit<ComponentProps<typeof BaseQuestionnaire.Input>, "size">
|
|
49
|
+
> &
|
|
50
|
+
VariantProps<typeof inputVariants>
|
|
51
|
+
export type QuestionnaireErrorProps = StyledProps<
|
|
52
|
+
ComponentProps<typeof BaseQuestionnaire.Error>
|
|
53
|
+
>
|
|
54
|
+
export type QuestionnaireActionsProps = ComponentProps<"div">
|
|
55
|
+
|
|
56
|
+
type QuestionnaireNavigationProps<T> = StyledProps<
|
|
57
|
+
Omit<T, "size" | "variant">
|
|
58
|
+
> &
|
|
59
|
+
VariantProps<typeof buttonVariants>
|
|
60
|
+
|
|
61
|
+
export type QuestionnairePreviousProps = QuestionnaireNavigationProps<
|
|
62
|
+
ComponentProps<typeof BaseQuestionnaire.Previous>
|
|
63
|
+
>
|
|
64
|
+
export type QuestionnaireSkipProps = QuestionnaireNavigationProps<
|
|
65
|
+
ComponentProps<typeof BaseQuestionnaire.Skip>
|
|
66
|
+
>
|
|
67
|
+
export type QuestionnaireNextProps = QuestionnaireNavigationProps<
|
|
68
|
+
ComponentProps<typeof BaseQuestionnaire.Next>
|
|
69
|
+
>
|
|
70
|
+
export type QuestionnaireSubmitProps = QuestionnaireNavigationProps<
|
|
71
|
+
ComponentProps<typeof BaseQuestionnaire.Submit>
|
|
72
|
+
>
|
|
73
|
+
|
|
74
|
+
export const Questionnaire = ({ className, ...props }: QuestionnaireProps) => (
|
|
75
|
+
<BaseQuestionnaire.Root
|
|
76
|
+
className={cn("flex w-full flex-col gap-6", className)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
export const QuestionnaireProgress = ({
|
|
82
|
+
className,
|
|
83
|
+
...props
|
|
84
|
+
}: QuestionnaireProgressProps) => (
|
|
85
|
+
<BaseQuestionnaire.Progress
|
|
86
|
+
className={cn("text-sm text-fg-secondary tabular-nums", className)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
export const QuestionnaireItem = ({
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}: QuestionnaireItemProps) => (
|
|
95
|
+
<BaseQuestionnaire.Item
|
|
96
|
+
className={cn(
|
|
97
|
+
"m-0 min-w-0 border-0 p-0",
|
|
98
|
+
focusRingBorder,
|
|
99
|
+
focusRing,
|
|
100
|
+
className,
|
|
101
|
+
)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
export const QuestionnaireTitle = ({
|
|
107
|
+
className,
|
|
108
|
+
...props
|
|
109
|
+
}: QuestionnaireTitleProps) => (
|
|
110
|
+
<BaseQuestionnaire.Title
|
|
111
|
+
className={cn("heading-sm text-fg-primary", className)}
|
|
112
|
+
{...props}
|
|
113
|
+
/>
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
export const QuestionnaireDescription = ({
|
|
117
|
+
className,
|
|
118
|
+
...props
|
|
119
|
+
}: QuestionnaireDescriptionProps) => (
|
|
120
|
+
<BaseQuestionnaire.Description
|
|
121
|
+
className={cn("text-sm mt-1 text-fg-secondary", className)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
export const QuestionnaireChoices = ({
|
|
127
|
+
className,
|
|
128
|
+
...props
|
|
129
|
+
}: QuestionnaireChoicesProps) => (
|
|
130
|
+
<BaseQuestionnaire.Choices
|
|
131
|
+
className={cn("mt-5 grid gap-2", className)}
|
|
132
|
+
{...props}
|
|
133
|
+
/>
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
export const QuestionnaireChoiceInput = ({
|
|
137
|
+
className,
|
|
138
|
+
...props
|
|
139
|
+
}: QuestionnaireChoiceInputProps) => (
|
|
140
|
+
<BaseQuestionnaire.ChoiceInput
|
|
141
|
+
className={cn(
|
|
142
|
+
"mt-0.5 size-4 shrink-0 cursor-pointer accent-brand-primary disabled:cursor-not-allowed",
|
|
143
|
+
focusRingBorder,
|
|
144
|
+
focusRing,
|
|
145
|
+
className,
|
|
146
|
+
)}
|
|
147
|
+
{...props}
|
|
148
|
+
/>
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
export const QuestionnaireChoiceLabel = ({
|
|
152
|
+
className,
|
|
153
|
+
...props
|
|
154
|
+
}: QuestionnaireChoiceLabelProps) => (
|
|
155
|
+
<BaseQuestionnaire.ChoiceLabel
|
|
156
|
+
className={cn("text-sm min-w-0 text-fg-primary", className)}
|
|
157
|
+
{...props}
|
|
158
|
+
/>
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
export const QuestionnaireChoiceShortcut = ({
|
|
162
|
+
className,
|
|
163
|
+
...props
|
|
164
|
+
}: QuestionnaireChoiceShortcutProps) => (
|
|
165
|
+
<BaseQuestionnaire.ChoiceShortcut
|
|
166
|
+
className={cn(
|
|
167
|
+
"text-xs flex min-w-5 items-center justify-center rounded border border-border-secondary bg-background-secondary px-1 py-0.5 text-fg-tertiary",
|
|
168
|
+
className,
|
|
169
|
+
)}
|
|
170
|
+
{...props}
|
|
171
|
+
/>
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
export const QuestionnaireChoice = ({
|
|
175
|
+
className,
|
|
176
|
+
children,
|
|
177
|
+
inputProps,
|
|
178
|
+
labelProps,
|
|
179
|
+
shortcutProps,
|
|
180
|
+
...props
|
|
181
|
+
}: QuestionnaireChoiceProps) => (
|
|
182
|
+
<BaseQuestionnaire.Choice
|
|
183
|
+
className={cn(
|
|
184
|
+
"group grid cursor-pointer grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3 rounded-lg border border-border-secondary bg-surface px-3.5 py-3 text-fg-primary outline-none transition-[background-color,border-color,box-shadow] duration-[var(--duration-sm)] ease-enter hover:bg-background-secondary has-[:focus-visible]:border-ring has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-offset-1 has-[:focus-visible]:ring-offset-background-primary has-[:focus-visible]:ring-ring/20 data-checked:border-brand-primary data-checked:bg-background-secondary data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
185
|
+
className,
|
|
186
|
+
)}
|
|
187
|
+
{...props}
|
|
188
|
+
>
|
|
189
|
+
<QuestionnaireChoiceInput {...inputProps} />
|
|
190
|
+
<QuestionnaireChoiceLabel {...labelProps}>
|
|
191
|
+
{children}
|
|
192
|
+
</QuestionnaireChoiceLabel>
|
|
193
|
+
<QuestionnaireChoiceShortcut {...shortcutProps} />
|
|
194
|
+
</BaseQuestionnaire.Choice>
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
export const QuestionnaireInput = ({
|
|
198
|
+
className,
|
|
199
|
+
variant,
|
|
200
|
+
size,
|
|
201
|
+
invalid,
|
|
202
|
+
...props
|
|
203
|
+
}: QuestionnaireInputProps) => (
|
|
204
|
+
<BaseQuestionnaire.Input
|
|
205
|
+
className={cn(inputVariants({ variant, size, invalid }), "mt-5", className)}
|
|
206
|
+
{...props}
|
|
207
|
+
/>
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
export const QuestionnaireError = ({
|
|
211
|
+
className,
|
|
212
|
+
...props
|
|
213
|
+
}: QuestionnaireErrorProps) => (
|
|
214
|
+
<BaseQuestionnaire.Error
|
|
215
|
+
className={cn("text-sm mt-2 text-destructive", className)}
|
|
216
|
+
{...props}
|
|
217
|
+
/>
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
export const QuestionnaireActions = ({
|
|
221
|
+
className,
|
|
222
|
+
...props
|
|
223
|
+
}: QuestionnaireActionsProps) => (
|
|
224
|
+
<div
|
|
225
|
+
className={cn("flex min-h-9 items-center justify-end gap-2", className)}
|
|
226
|
+
{...props}
|
|
227
|
+
/>
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
export const QuestionnairePrevious = ({
|
|
231
|
+
className,
|
|
232
|
+
variant = "outline",
|
|
233
|
+
size,
|
|
234
|
+
...props
|
|
235
|
+
}: QuestionnairePreviousProps) => (
|
|
236
|
+
<BaseQuestionnaire.Previous
|
|
237
|
+
className={cn(buttonVariants({ variant, size }), "mr-auto", className)}
|
|
238
|
+
{...props}
|
|
239
|
+
/>
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
export const QuestionnaireSkip = ({
|
|
243
|
+
className,
|
|
244
|
+
variant = "ghost",
|
|
245
|
+
size,
|
|
246
|
+
...props
|
|
247
|
+
}: QuestionnaireSkipProps) => (
|
|
248
|
+
<BaseQuestionnaire.Skip
|
|
249
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
250
|
+
{...props}
|
|
251
|
+
/>
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
export const QuestionnaireNext = ({
|
|
255
|
+
className,
|
|
256
|
+
variant = "primary",
|
|
257
|
+
size,
|
|
258
|
+
...props
|
|
259
|
+
}: QuestionnaireNextProps) => (
|
|
260
|
+
<BaseQuestionnaire.Next
|
|
261
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
262
|
+
{...props}
|
|
263
|
+
/>
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
export const QuestionnaireSubmit = ({
|
|
267
|
+
className,
|
|
268
|
+
variant = "primary",
|
|
269
|
+
size,
|
|
270
|
+
...props
|
|
271
|
+
}: QuestionnaireSubmitProps) => (
|
|
272
|
+
<BaseQuestionnaire.Submit
|
|
273
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
274
|
+
{...props}
|
|
275
|
+
/>
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
export type {
|
|
279
|
+
QuestionnaireChoiceDefinition,
|
|
280
|
+
QuestionnaireInputType,
|
|
281
|
+
QuestionnaireItemDefinition,
|
|
282
|
+
QuestionnaireItemStatus,
|
|
283
|
+
QuestionnaireShortcutMode,
|
|
284
|
+
} from "@shadcn/react/questionnaire"
|
package/src/radio.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { Radio as BaseRadio } from "@base-ui/react/radio"
|
|
|
4
4
|
import { RadioGroup as BaseRadioGroup } from "@base-ui/react/radio-group"
|
|
5
5
|
import type { ComponentProps } from "react"
|
|
6
6
|
import { cn } from "./lib/cn"
|
|
7
|
+
import { focusRing } from "./lib/focus"
|
|
7
8
|
import { motion } from "./lib/motion"
|
|
8
9
|
|
|
9
10
|
export type RadioGroupProps = ComponentProps<typeof BaseRadioGroup>
|
|
@@ -20,9 +21,10 @@ export const RadioGroup = ({ className, ...props }: RadioGroupProps) => (
|
|
|
20
21
|
export const Radio = ({ className, ...props }: RadioProps) => (
|
|
21
22
|
<BaseRadio.Root
|
|
22
23
|
className={cn(
|
|
23
|
-
"flex size-4 shrink-0 items-center justify-center rounded-full border border-border-secondary bg-surface
|
|
24
|
+
"flex size-4 shrink-0 items-center justify-center rounded-full border border-border-secondary bg-surface",
|
|
24
25
|
motion.colors,
|
|
25
|
-
|
|
26
|
+
focusRing,
|
|
27
|
+
"data-checked:border-brand-primary data-checked:bg-brand-primary data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
26
28
|
className,
|
|
27
29
|
)}
|
|
28
30
|
{...props}
|
package/src/scroll-area.tsx
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area"
|
|
4
4
|
import type { ComponentProps } from "react"
|
|
5
5
|
import { cn } from "./lib/cn"
|
|
6
|
+
import { focusRing, focusRingBorder } from "./lib/focus"
|
|
6
7
|
|
|
7
8
|
export type ScrollAreaProps = ComponentProps<typeof BaseScrollArea.Root>
|
|
8
9
|
export type ScrollAreaViewportProps = ComponentProps<
|
|
@@ -29,7 +30,9 @@ export const ScrollAreaViewport = ({
|
|
|
29
30
|
}: ScrollAreaViewportProps) => (
|
|
30
31
|
<BaseScrollArea.Viewport
|
|
31
32
|
className={cn(
|
|
32
|
-
"size-full rounded-[inherit]
|
|
33
|
+
"size-full rounded-[inherit]",
|
|
34
|
+
focusRingBorder,
|
|
35
|
+
focusRing,
|
|
33
36
|
className,
|
|
34
37
|
)}
|
|
35
38
|
{...props}
|
package/src/select.tsx
CHANGED
|
@@ -4,7 +4,9 @@ import { Select as BaseSelect } from "@base-ui/react/select"
|
|
|
4
4
|
import type { ComponentProps } from "react"
|
|
5
5
|
import { IconChevronDownSmall } from "./icons"
|
|
6
6
|
import { cn } from "./lib/cn"
|
|
7
|
+
import { focusRing, focusRingInvalid } from "./lib/focus"
|
|
7
8
|
import { motion } from "./lib/motion"
|
|
9
|
+
import { popupInset, popupItem, popupLabel, popupSurface } from "./lib/popup"
|
|
8
10
|
|
|
9
11
|
export type SelectProps = ComponentProps<typeof BaseSelect.Root>
|
|
10
12
|
export type SelectTriggerProps = ComponentProps<typeof BaseSelect.Trigger>
|
|
@@ -31,9 +33,11 @@ export const SelectTrigger = ({
|
|
|
31
33
|
}: SelectTriggerProps) => (
|
|
32
34
|
<BaseSelect.Trigger
|
|
33
35
|
className={cn(
|
|
34
|
-
"flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-border-secondary bg-surface px-3 text-sm text-fg-primary inset-shadow-outline-top
|
|
36
|
+
"flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-border-secondary bg-surface px-3 text-sm text-fg-primary inset-shadow-outline-top",
|
|
35
37
|
motion.all,
|
|
36
|
-
|
|
38
|
+
focusRing,
|
|
39
|
+
focusRingInvalid,
|
|
40
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50 data-placeholder:text-fg-quaternary data-popup-open:border-border-secondary",
|
|
37
41
|
className,
|
|
38
42
|
)}
|
|
39
43
|
{...props}
|
|
@@ -71,7 +75,7 @@ export const SelectPortal = (props: SelectPortalProps) => (
|
|
|
71
75
|
|
|
72
76
|
export const SelectPositioner = ({
|
|
73
77
|
alignItemWithTrigger = false,
|
|
74
|
-
sideOffset =
|
|
78
|
+
sideOffset = 6,
|
|
75
79
|
className,
|
|
76
80
|
...props
|
|
77
81
|
}: SelectPositionerProps) => (
|
|
@@ -86,7 +90,8 @@ export const SelectPositioner = ({
|
|
|
86
90
|
export const SelectPopup = ({ className, ...props }: SelectPopupProps) => (
|
|
87
91
|
<BaseSelect.Popup
|
|
88
92
|
className={cn(
|
|
89
|
-
"z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden
|
|
93
|
+
"z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden",
|
|
94
|
+
popupSurface,
|
|
90
95
|
motion.popupAnchor,
|
|
91
96
|
className,
|
|
92
97
|
)}
|
|
@@ -96,7 +101,7 @@ export const SelectPopup = ({ className, ...props }: SelectPopupProps) => (
|
|
|
96
101
|
|
|
97
102
|
export const SelectList = ({ className, ...props }: SelectListProps) => (
|
|
98
103
|
<BaseSelect.List
|
|
99
|
-
className={cn("max-h-[inherit] overflow-y-auto
|
|
104
|
+
className={cn("max-h-[inherit] overflow-y-auto outline-none", popupInset, className)}
|
|
100
105
|
{...props}
|
|
101
106
|
/>
|
|
102
107
|
)
|
|
@@ -104,7 +109,7 @@ export const SelectList = ({ className, ...props }: SelectListProps) => (
|
|
|
104
109
|
export const SelectItem = ({ className, ...props }: SelectItemProps) => (
|
|
105
110
|
<BaseSelect.Item
|
|
106
111
|
className={cn(
|
|
107
|
-
|
|
112
|
+
popupItem,
|
|
108
113
|
motion.colors,
|
|
109
114
|
"data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-background-tertiary data-selected:text-fg-primary",
|
|
110
115
|
className,
|
|
@@ -145,7 +150,7 @@ export const SelectGroupLabel = ({
|
|
|
145
150
|
...props
|
|
146
151
|
}: SelectGroupLabelProps) => (
|
|
147
152
|
<BaseSelect.GroupLabel
|
|
148
|
-
className={cn(
|
|
153
|
+
className={cn(popupLabel, className)}
|
|
149
154
|
{...props}
|
|
150
155
|
/>
|
|
151
156
|
)
|
package/src/sidebar.tsx
CHANGED
|
@@ -1,56 +1,119 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
2
|
+
import type { ComponentProps } from "react"
|
|
3
|
+
import { cn } from "./lib/cn"
|
|
4
|
+
import { focusRing } from "./lib/focus"
|
|
5
|
+
import { motion } from "./lib/motion"
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
const sidebarVariants = cva(
|
|
8
|
+
"flex h-full shrink-0 flex-col overflow-hidden text-fg-primary",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "border-r border-border-primary bg-surface",
|
|
13
|
+
inset: "rounded-lg bg-background-secondary",
|
|
14
|
+
floating:
|
|
15
|
+
"rounded-xl border border-border-primary bg-surface-raised shadow-sm",
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
sm: "w-52",
|
|
19
|
+
md: "w-60",
|
|
20
|
+
lg: "w-72",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "default",
|
|
25
|
+
size: "md",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
)
|
|
15
29
|
|
|
16
|
-
|
|
30
|
+
const sidebarNavItemVariants = cva(
|
|
31
|
+
cn(
|
|
32
|
+
"group/nav-item relative flex w-full cursor-pointer items-center gap-2 border border-transparent text-left text-fg-secondary disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0",
|
|
33
|
+
focusRing,
|
|
34
|
+
),
|
|
35
|
+
{
|
|
36
|
+
variants: {
|
|
37
|
+
variant: {
|
|
38
|
+
default:
|
|
39
|
+
"rounded-md hover:bg-background-tertiary hover:text-fg-primary data-[active]:bg-background-tertiary data-[active]:font-medium data-[active]:text-fg-primary",
|
|
40
|
+
pill: "rounded-full hover:bg-background-tertiary hover:text-fg-primary data-[active]:border-brand-primary-border data-[active]:bg-brand-primary data-[active]:font-medium data-[active]:text-brand-foreground",
|
|
41
|
+
indicator:
|
|
42
|
+
"rounded-md before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent before:content-[''] hover:bg-background-tertiary hover:text-fg-primary data-[active]:bg-background-tertiary data-[active]:font-medium data-[active]:text-fg-primary data-[active]:before:bg-brand-primary",
|
|
43
|
+
},
|
|
44
|
+
size: {
|
|
45
|
+
sm: "h-8 px-2.5 text-xs",
|
|
46
|
+
md: "h-9 px-3 text-sm",
|
|
47
|
+
lg: "h-10 px-3.5 text-sm",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
defaultVariants: {
|
|
51
|
+
variant: "default",
|
|
52
|
+
size: "md",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
export type SidebarProps = Omit<ComponentProps<"aside">, "size"> &
|
|
58
|
+
VariantProps<typeof sidebarVariants>
|
|
59
|
+
export type SidebarHeaderProps = ComponentProps<"div">
|
|
60
|
+
export type SidebarContentProps = ComponentProps<"div">
|
|
61
|
+
export type SidebarFooterProps = ComponentProps<"div">
|
|
62
|
+
export type SidebarNavProps = ComponentProps<"nav">
|
|
63
|
+
export type SidebarNavItemProps = Omit<ComponentProps<"button">, "size"> &
|
|
64
|
+
VariantProps<typeof sidebarNavItemVariants> & {
|
|
65
|
+
active?: boolean
|
|
66
|
+
}
|
|
67
|
+
export type SidebarNavItemLabelProps = ComponentProps<"span">
|
|
68
|
+
export type SidebarNavBadgeProps = ComponentProps<"span">
|
|
69
|
+
export type SidebarGroupProps = ComponentProps<"div">
|
|
70
|
+
export type SidebarGroupLabelProps = ComponentProps<"h3">
|
|
71
|
+
|
|
72
|
+
export const Sidebar = ({
|
|
73
|
+
className,
|
|
74
|
+
variant,
|
|
75
|
+
size,
|
|
76
|
+
...props
|
|
77
|
+
}: SidebarProps) => (
|
|
17
78
|
<aside
|
|
18
|
-
className={cn(
|
|
19
|
-
"flex h-full w-60 shrink-0 flex-col border-r border-border-primary bg-surface",
|
|
20
|
-
className,
|
|
21
|
-
)}
|
|
79
|
+
className={cn(sidebarVariants({ variant, size }), className)}
|
|
22
80
|
{...props}
|
|
23
81
|
/>
|
|
24
|
-
)
|
|
82
|
+
)
|
|
25
83
|
|
|
26
84
|
export const SidebarHeader = ({ className, ...props }: SidebarHeaderProps) => (
|
|
27
85
|
<div
|
|
28
86
|
className={cn("border-b border-border-primary p-4", className)}
|
|
29
87
|
{...props}
|
|
30
88
|
/>
|
|
31
|
-
)
|
|
89
|
+
)
|
|
32
90
|
|
|
33
91
|
export const SidebarContent = ({
|
|
34
92
|
className,
|
|
35
93
|
...props
|
|
36
94
|
}: SidebarContentProps) => (
|
|
37
|
-
<div
|
|
38
|
-
)
|
|
95
|
+
<div
|
|
96
|
+
className={cn("min-h-0 flex-1 overflow-y-auto p-3", className)}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
39
100
|
|
|
40
101
|
export const SidebarFooter = ({ className, ...props }: SidebarFooterProps) => (
|
|
41
102
|
<div
|
|
42
103
|
className={cn("border-t border-border-primary p-3", className)}
|
|
43
104
|
{...props}
|
|
44
105
|
/>
|
|
45
|
-
)
|
|
106
|
+
)
|
|
46
107
|
|
|
47
108
|
export const SidebarNav = ({ className, ...props }: SidebarNavProps) => (
|
|
48
109
|
<nav className={cn("flex flex-col gap-1", className)} {...props} />
|
|
49
|
-
)
|
|
110
|
+
)
|
|
50
111
|
|
|
51
112
|
export const SidebarNavItem = ({
|
|
52
113
|
className,
|
|
53
114
|
active = false,
|
|
115
|
+
variant,
|
|
116
|
+
size,
|
|
54
117
|
type = "button",
|
|
55
118
|
...props
|
|
56
119
|
}: SidebarNavItemProps) => (
|
|
@@ -59,17 +122,37 @@ export const SidebarNavItem = ({
|
|
|
59
122
|
data-active={active || undefined}
|
|
60
123
|
aria-current={active ? "page" : undefined}
|
|
61
124
|
className={cn(
|
|
62
|
-
|
|
125
|
+
sidebarNavItemVariants({ variant, size }),
|
|
63
126
|
motion.colors,
|
|
64
127
|
className,
|
|
65
128
|
)}
|
|
66
129
|
{...props}
|
|
67
130
|
/>
|
|
68
|
-
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
export const SidebarNavItemLabel = ({
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}: SidebarNavItemLabelProps) => (
|
|
137
|
+
<span className={cn("min-w-0 flex-1 truncate", className)} {...props} />
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
export const SidebarNavBadge = ({
|
|
141
|
+
className,
|
|
142
|
+
...props
|
|
143
|
+
}: SidebarNavBadgeProps) => (
|
|
144
|
+
<span
|
|
145
|
+
className={cn(
|
|
146
|
+
"text-2xs-strong ml-auto inline-flex min-w-5 shrink-0 items-center justify-center rounded-full border border-border-primary bg-surface px-1.5 py-0.5 text-fg-secondary",
|
|
147
|
+
className,
|
|
148
|
+
)}
|
|
149
|
+
{...props}
|
|
150
|
+
/>
|
|
151
|
+
)
|
|
69
152
|
|
|
70
153
|
export const SidebarGroup = ({ className, ...props }: SidebarGroupProps) => (
|
|
71
154
|
<div className={cn("flex flex-col gap-1 py-2", className)} {...props} />
|
|
72
|
-
)
|
|
155
|
+
)
|
|
73
156
|
|
|
74
157
|
export const SidebarGroupLabel = ({
|
|
75
158
|
className,
|
|
@@ -79,4 +162,6 @@ export const SidebarGroupLabel = ({
|
|
|
79
162
|
className={cn("px-3 py-1.5 text-xs-strong text-fg-tertiary", className)}
|
|
80
163
|
{...props}
|
|
81
164
|
/>
|
|
82
|
-
)
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
export { sidebarNavItemVariants, sidebarVariants }
|