@boyernick/standard-ui-react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/package.json +46 -0
- package/src/accordion.tsx +84 -0
- package/src/alert-dialog.tsx +101 -0
- package/src/attachment.tsx +138 -0
- package/src/autocomplete.tsx +281 -0
- package/src/avatar.tsx +56 -0
- package/src/badge.tsx +28 -0
- package/src/brand.tsx +70 -0
- package/src/breadcrumb.tsx +81 -0
- package/src/button.tsx +129 -0
- package/src/calendar.tsx +84 -0
- package/src/card.tsx +54 -0
- package/src/carousel.tsx +253 -0
- package/src/chart.tsx +185 -0
- package/src/checkbox-group.tsx +14 -0
- package/src/checkbox.tsx +31 -0
- package/src/code-block.tsx +124 -0
- package/src/collapsible.tsx +61 -0
- package/src/combobox.tsx +324 -0
- package/src/command.tsx +377 -0
- package/src/context-menu.tsx +250 -0
- package/src/dialog.tsx +78 -0
- package/src/drawer.tsx +156 -0
- package/src/empty.tsx +52 -0
- package/src/field.tsx +75 -0
- package/src/fieldset.tsx +25 -0
- package/src/form.tsx +14 -0
- package/src/icons.tsx +91 -0
- package/src/illustrations.tsx +167 -0
- package/src/image-modal.tsx +110 -0
- package/src/index.ts +833 -0
- package/src/input.tsx +68 -0
- package/src/lib/cn.ts +3 -0
- package/src/lib/motion.ts +23 -0
- package/src/markdown-editor.tsx +302 -0
- package/src/menu.tsx +205 -0
- package/src/menubar.tsx +22 -0
- package/src/meter.tsx +61 -0
- package/src/navigation-menu.tsx +217 -0
- package/src/number-field.tsx +119 -0
- package/src/orb.tsx +33 -0
- package/src/otp-field.tsx +45 -0
- package/src/pagination.tsx +91 -0
- package/src/popover.tsx +92 -0
- package/src/preview-card.tsx +103 -0
- package/src/progress.tsx +60 -0
- package/src/radio.tsx +43 -0
- package/src/scroll-area.tsx +67 -0
- package/src/select.tsx +161 -0
- package/src/separator.tsx +17 -0
- package/src/sidebar.tsx +82 -0
- package/src/skeleton.tsx +32 -0
- package/src/slider.tsx +56 -0
- package/src/sounds.tsx +270 -0
- package/src/spinner.tsx +45 -0
- package/src/switch.tsx +19 -0
- package/src/table.tsx +81 -0
- package/src/tabs.tsx +62 -0
- package/src/text-animate.tsx +155 -0
- package/src/textarea.tsx +58 -0
- package/src/ticker.tsx +74 -0
- package/src/toast.tsx +142 -0
- package/src/toggle.tsx +32 -0
- package/src/toolbar.tsx +75 -0
- package/src/tooltip.tsx +55 -0
- package/src/video-player.tsx +241 -0
package/src/progress.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Progress as BaseProgress } from "@base-ui/react/progress"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type ProgressProps = ComponentProps<typeof BaseProgress.Root>
|
|
8
|
+
export type ProgressLabelProps = ComponentProps<typeof BaseProgress.Label>
|
|
9
|
+
export type ProgressValueProps = ComponentProps<typeof BaseProgress.Value>
|
|
10
|
+
export type ProgressTrackProps = ComponentProps<typeof BaseProgress.Track>
|
|
11
|
+
export type ProgressIndicatorProps = ComponentProps<
|
|
12
|
+
typeof BaseProgress.Indicator
|
|
13
|
+
>
|
|
14
|
+
|
|
15
|
+
export const Progress = ({ className, ...props }: ProgressProps) => (
|
|
16
|
+
<BaseProgress.Root
|
|
17
|
+
className={cn(
|
|
18
|
+
"grid w-full grid-cols-[1fr_auto] items-center gap-x-2 gap-y-2",
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export const ProgressLabel = ({ className, ...props }: ProgressLabelProps) => (
|
|
26
|
+
<BaseProgress.Label
|
|
27
|
+
className={cn("text-sm text-fg-primary", className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const ProgressValue = ({ className, ...props }: ProgressValueProps) => (
|
|
33
|
+
<BaseProgress.Value
|
|
34
|
+
className={cn("text-right text-sm text-fg-secondary tabular-nums", className)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
export const ProgressTrack = ({ className, ...props }: ProgressTrackProps) => (
|
|
40
|
+
<BaseProgress.Track
|
|
41
|
+
className={cn(
|
|
42
|
+
"col-span-2 h-1.5 overflow-hidden rounded-full bg-background-quaternary",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
export const ProgressIndicator = ({
|
|
50
|
+
className,
|
|
51
|
+
...props
|
|
52
|
+
}: ProgressIndicatorProps) => (
|
|
53
|
+
<BaseProgress.Indicator
|
|
54
|
+
className={cn(
|
|
55
|
+
"h-full rounded-full bg-brand-primary transition-[width] duration-300 ease-out motion-reduce:transition-none",
|
|
56
|
+
className,
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
package/src/radio.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Radio as BaseRadio } from "@base-ui/react/radio"
|
|
4
|
+
import { RadioGroup as BaseRadioGroup } from "@base-ui/react/radio-group"
|
|
5
|
+
import type { ComponentProps } from "react"
|
|
6
|
+
import { cn } from "./lib/cn"
|
|
7
|
+
import { motion } from "./lib/motion"
|
|
8
|
+
|
|
9
|
+
export type RadioGroupProps = ComponentProps<typeof BaseRadioGroup>
|
|
10
|
+
export type RadioProps = ComponentProps<typeof BaseRadio.Root>
|
|
11
|
+
export type RadioIndicatorProps = ComponentProps<typeof BaseRadio.Indicator>
|
|
12
|
+
|
|
13
|
+
export const RadioGroup = ({ className, ...props }: RadioGroupProps) => (
|
|
14
|
+
<BaseRadioGroup
|
|
15
|
+
className={cn("flex flex-col gap-2", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
export const Radio = ({ className, ...props }: RadioProps) => (
|
|
21
|
+
<BaseRadio.Root
|
|
22
|
+
className={cn(
|
|
23
|
+
"flex size-4 shrink-0 items-center justify-center rounded-full border border-border-secondary bg-surface outline-none",
|
|
24
|
+
motion.colors,
|
|
25
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-checked:border-brand-primary data-checked:bg-brand-primary data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
26
|
+
className,
|
|
27
|
+
)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const RadioIndicator = ({
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: RadioIndicatorProps) => (
|
|
36
|
+
<BaseRadio.Indicator
|
|
37
|
+
className={cn(
|
|
38
|
+
"size-1.5 rounded-full bg-brand-foreground data-unchecked:hidden",
|
|
39
|
+
className,
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type ScrollAreaProps = ComponentProps<typeof BaseScrollArea.Root>
|
|
8
|
+
export type ScrollAreaViewportProps = ComponentProps<
|
|
9
|
+
typeof BaseScrollArea.Viewport
|
|
10
|
+
>
|
|
11
|
+
export type ScrollAreaContentProps = ComponentProps<
|
|
12
|
+
typeof BaseScrollArea.Content
|
|
13
|
+
>
|
|
14
|
+
export type ScrollAreaScrollbarProps = ComponentProps<
|
|
15
|
+
typeof BaseScrollArea.Scrollbar
|
|
16
|
+
>
|
|
17
|
+
export type ScrollAreaThumbProps = ComponentProps<typeof BaseScrollArea.Thumb>
|
|
18
|
+
|
|
19
|
+
export const ScrollArea = ({ className, ...props }: ScrollAreaProps) => (
|
|
20
|
+
<BaseScrollArea.Root
|
|
21
|
+
className={cn("relative overflow-hidden", className)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
export const ScrollAreaViewport = ({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: ScrollAreaViewportProps) => (
|
|
30
|
+
<BaseScrollArea.Viewport
|
|
31
|
+
className={cn(
|
|
32
|
+
"size-full rounded-[inherit] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20",
|
|
33
|
+
className,
|
|
34
|
+
)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
export const ScrollAreaContent = ({
|
|
40
|
+
className,
|
|
41
|
+
...props
|
|
42
|
+
}: ScrollAreaContentProps) => (
|
|
43
|
+
<BaseScrollArea.Content className={cn(className)} {...props} />
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export const ScrollAreaScrollbar = ({
|
|
47
|
+
className,
|
|
48
|
+
...props
|
|
49
|
+
}: ScrollAreaScrollbarProps) => (
|
|
50
|
+
<BaseScrollArea.Scrollbar
|
|
51
|
+
className={cn(
|
|
52
|
+
"flex touch-none p-0.5 opacity-100 transition-opacity duration-150 ease-out motion-reduce:transition-none data-[orientation=horizontal]:h-2 data-[orientation=vertical]:w-2",
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
export const ScrollAreaThumb = ({
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
}: ScrollAreaThumbProps) => (
|
|
63
|
+
<BaseScrollArea.Thumb
|
|
64
|
+
className={cn("flex-1 rounded-full bg-border-secondary", className)}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
)
|
package/src/select.tsx
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Select as BaseSelect } from "@base-ui/react/select"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { IconChevronDownSmall } from "./icons"
|
|
6
|
+
import { cn } from "./lib/cn"
|
|
7
|
+
import { motion } from "./lib/motion"
|
|
8
|
+
|
|
9
|
+
export type SelectProps = ComponentProps<typeof BaseSelect.Root>
|
|
10
|
+
export type SelectTriggerProps = ComponentProps<typeof BaseSelect.Trigger>
|
|
11
|
+
export type SelectValueProps = ComponentProps<typeof BaseSelect.Value>
|
|
12
|
+
export type SelectIconProps = ComponentProps<typeof BaseSelect.Icon>
|
|
13
|
+
export type SelectPortalProps = ComponentProps<typeof BaseSelect.Portal>
|
|
14
|
+
export type SelectPositionerProps = ComponentProps<typeof BaseSelect.Positioner>
|
|
15
|
+
export type SelectPopupProps = ComponentProps<typeof BaseSelect.Popup>
|
|
16
|
+
export type SelectListProps = ComponentProps<typeof BaseSelect.List>
|
|
17
|
+
export type SelectItemProps = ComponentProps<typeof BaseSelect.Item>
|
|
18
|
+
export type SelectItemTextProps = ComponentProps<typeof BaseSelect.ItemText>
|
|
19
|
+
export type SelectItemIndicatorProps = ComponentProps<
|
|
20
|
+
typeof BaseSelect.ItemIndicator
|
|
21
|
+
>
|
|
22
|
+
export type SelectGroupProps = ComponentProps<typeof BaseSelect.Group>
|
|
23
|
+
export type SelectGroupLabelProps = ComponentProps<typeof BaseSelect.GroupLabel>
|
|
24
|
+
export type SelectSeparatorProps = ComponentProps<typeof BaseSelect.Separator>
|
|
25
|
+
|
|
26
|
+
export const Select = (props: SelectProps) => <BaseSelect.Root {...props} />
|
|
27
|
+
|
|
28
|
+
export const SelectTrigger = ({
|
|
29
|
+
className,
|
|
30
|
+
...props
|
|
31
|
+
}: SelectTriggerProps) => (
|
|
32
|
+
<BaseSelect.Trigger
|
|
33
|
+
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 outline-none",
|
|
35
|
+
motion.all,
|
|
36
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20 data-disabled:cursor-not-allowed data-disabled:opacity-50 data-placeholder:text-fg-quaternary data-popup-open:border-border-secondary data-popup-open:bg-background-tertiary/60",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
export const SelectValue = ({ className, ...props }: SelectValueProps) => (
|
|
44
|
+
<BaseSelect.Value
|
|
45
|
+
className={cn("flex-1 truncate text-left", className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export const SelectIcon = ({
|
|
51
|
+
className,
|
|
52
|
+
children,
|
|
53
|
+
...props
|
|
54
|
+
}: SelectIconProps) => (
|
|
55
|
+
<BaseSelect.Icon
|
|
56
|
+
className={cn(
|
|
57
|
+
"flex shrink-0 text-fg-tertiary",
|
|
58
|
+
motion.transform,
|
|
59
|
+
"data-popup-open:rotate-180",
|
|
60
|
+
className,
|
|
61
|
+
)}
|
|
62
|
+
{...props}
|
|
63
|
+
>
|
|
64
|
+
{children ?? <IconChevronDownSmall size={16} className="size-4" aria-hidden />}
|
|
65
|
+
</BaseSelect.Icon>
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
export const SelectPortal = (props: SelectPortalProps) => (
|
|
69
|
+
<BaseSelect.Portal {...props} />
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
export const SelectPositioner = ({
|
|
73
|
+
alignItemWithTrigger = false,
|
|
74
|
+
sideOffset = 4,
|
|
75
|
+
className,
|
|
76
|
+
...props
|
|
77
|
+
}: SelectPositionerProps) => (
|
|
78
|
+
<BaseSelect.Positioner
|
|
79
|
+
alignItemWithTrigger={alignItemWithTrigger}
|
|
80
|
+
sideOffset={sideOffset}
|
|
81
|
+
className={cn("z-50 outline-none", className)}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
export const SelectPopup = ({ className, ...props }: SelectPopupProps) => (
|
|
87
|
+
<BaseSelect.Popup
|
|
88
|
+
className={cn(
|
|
89
|
+
"z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden rounded-md border border-border-primary bg-surface shadow-md outline-none",
|
|
90
|
+
motion.popupAnchor,
|
|
91
|
+
className,
|
|
92
|
+
)}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
export const SelectList = ({ className, ...props }: SelectListProps) => (
|
|
98
|
+
<BaseSelect.List
|
|
99
|
+
className={cn("max-h-[inherit] overflow-y-auto p-1 outline-none", className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
export const SelectItem = ({ className, ...props }: SelectItemProps) => (
|
|
105
|
+
<BaseSelect.Item
|
|
106
|
+
className={cn(
|
|
107
|
+
"flex min-h-8 cursor-default items-center gap-2 rounded-xs px-2.5 py-1.5 text-sm text-fg-primary outline-none select-none",
|
|
108
|
+
motion.colors,
|
|
109
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-background-tertiary data-selected:text-fg-primary",
|
|
110
|
+
className,
|
|
111
|
+
)}
|
|
112
|
+
{...props}
|
|
113
|
+
/>
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
export const SelectItemText = ({
|
|
117
|
+
className,
|
|
118
|
+
...props
|
|
119
|
+
}: SelectItemTextProps) => (
|
|
120
|
+
<BaseSelect.ItemText
|
|
121
|
+
className={cn("flex-1 truncate", className)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
export const SelectItemIndicator = ({
|
|
127
|
+
className,
|
|
128
|
+
...props
|
|
129
|
+
}: SelectItemIndicatorProps) => (
|
|
130
|
+
<BaseSelect.ItemIndicator
|
|
131
|
+
className={cn(
|
|
132
|
+
"ml-auto flex size-4 shrink-0 items-center justify-center text-fg-primary data-unchecked:hidden",
|
|
133
|
+
className,
|
|
134
|
+
)}
|
|
135
|
+
{...props}
|
|
136
|
+
/>
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
export const SelectGroup = ({ className, ...props }: SelectGroupProps) => (
|
|
140
|
+
<BaseSelect.Group className={cn(className)} {...props} />
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
export const SelectGroupLabel = ({
|
|
144
|
+
className,
|
|
145
|
+
...props
|
|
146
|
+
}: SelectGroupLabelProps) => (
|
|
147
|
+
<BaseSelect.GroupLabel
|
|
148
|
+
className={cn("px-2.5 py-1.5 text-xs text-fg-tertiary", className)}
|
|
149
|
+
{...props}
|
|
150
|
+
/>
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
export const SelectSeparator = ({
|
|
154
|
+
className,
|
|
155
|
+
...props
|
|
156
|
+
}: SelectSeparatorProps) => (
|
|
157
|
+
<BaseSelect.Separator
|
|
158
|
+
className={cn("my-1 h-px bg-border-primary", className)}
|
|
159
|
+
{...props}
|
|
160
|
+
/>
|
|
161
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Separator as BaseSeparator } from "@base-ui/react/separator"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type SeparatorProps = ComponentProps<typeof BaseSeparator>
|
|
8
|
+
|
|
9
|
+
export const Separator = ({ className, ...props }: SeparatorProps) => (
|
|
10
|
+
<BaseSeparator
|
|
11
|
+
className={cn(
|
|
12
|
+
"h-px w-full bg-border-primary data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
package/src/sidebar.tsx
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { cn } from "./lib/cn";
|
|
3
|
+
import { motion } from "./lib/motion";
|
|
4
|
+
|
|
5
|
+
export type SidebarProps = ComponentProps<"aside">;
|
|
6
|
+
export type SidebarHeaderProps = ComponentProps<"div">;
|
|
7
|
+
export type SidebarContentProps = ComponentProps<"div">;
|
|
8
|
+
export type SidebarFooterProps = ComponentProps<"div">;
|
|
9
|
+
export type SidebarNavProps = ComponentProps<"nav">;
|
|
10
|
+
export type SidebarNavItemProps = ComponentProps<"button"> & {
|
|
11
|
+
active?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type SidebarGroupProps = ComponentProps<"div">;
|
|
14
|
+
export type SidebarGroupLabelProps = ComponentProps<"h3">;
|
|
15
|
+
|
|
16
|
+
export const Sidebar = ({ className, ...props }: SidebarProps) => (
|
|
17
|
+
<aside
|
|
18
|
+
className={cn(
|
|
19
|
+
"flex h-full w-60 shrink-0 flex-col border-r border-border-primary bg-surface",
|
|
20
|
+
className,
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export const SidebarHeader = ({ className, ...props }: SidebarHeaderProps) => (
|
|
27
|
+
<div
|
|
28
|
+
className={cn("border-b border-border-primary p-4", className)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const SidebarContent = ({
|
|
34
|
+
className,
|
|
35
|
+
...props
|
|
36
|
+
}: SidebarContentProps) => (
|
|
37
|
+
<div className={cn("flex-1 overflow-y-auto p-3", className)} {...props} />
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export const SidebarFooter = ({ className, ...props }: SidebarFooterProps) => (
|
|
41
|
+
<div
|
|
42
|
+
className={cn("border-t border-border-primary p-3", className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export const SidebarNav = ({ className, ...props }: SidebarNavProps) => (
|
|
48
|
+
<nav className={cn("flex flex-col gap-1", className)} {...props} />
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
export const SidebarNavItem = ({
|
|
52
|
+
className,
|
|
53
|
+
active = false,
|
|
54
|
+
type = "button",
|
|
55
|
+
...props
|
|
56
|
+
}: SidebarNavItemProps) => (
|
|
57
|
+
<button
|
|
58
|
+
type={type}
|
|
59
|
+
data-active={active || undefined}
|
|
60
|
+
aria-current={active ? "page" : undefined}
|
|
61
|
+
className={cn(
|
|
62
|
+
"flex h-9 w-full cursor-pointer items-center gap-2 rounded-md border border-transparent px-3 text-left text-sm text-fg-secondary outline-none hover:bg-background-tertiary hover:text-fg-primary focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-[active]:bg-background-tertiary data-[active]:font-medium data-[active]:text-fg-primary [&_svg]:size-4 [&_svg]:shrink-0",
|
|
63
|
+
motion.colors,
|
|
64
|
+
className,
|
|
65
|
+
)}
|
|
66
|
+
{...props}
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
export const SidebarGroup = ({ className, ...props }: SidebarGroupProps) => (
|
|
71
|
+
<div className={cn("flex flex-col gap-1 py-2", className)} {...props} />
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
export const SidebarGroupLabel = ({
|
|
75
|
+
className,
|
|
76
|
+
...props
|
|
77
|
+
}: SidebarGroupLabelProps) => (
|
|
78
|
+
<h3
|
|
79
|
+
className={cn("px-3 py-1.5 text-xs-strong text-fg-tertiary", className)}
|
|
80
|
+
{...props}
|
|
81
|
+
/>
|
|
82
|
+
);
|
package/src/skeleton.tsx
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
import { cn } from "./lib/cn";
|
|
4
|
+
|
|
5
|
+
const skeletonVariants = cva(
|
|
6
|
+
"animate-pulse bg-background-tertiary motion-reduce:animate-none",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
block: "rounded-md",
|
|
11
|
+
text: "h-4 rounded-sm",
|
|
12
|
+
circle: "rounded-full",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
variant: "block",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export type SkeletonProps = ComponentProps<"div"> &
|
|
22
|
+
VariantProps<typeof skeletonVariants>;
|
|
23
|
+
|
|
24
|
+
export const Skeleton = ({ className, variant, ...props }: SkeletonProps) => (
|
|
25
|
+
<div
|
|
26
|
+
aria-hidden
|
|
27
|
+
className={cn(skeletonVariants({ variant }), className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export { skeletonVariants };
|
package/src/slider.tsx
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Slider as BaseSlider } from "@base-ui/react/slider"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type SliderProps = ComponentProps<typeof BaseSlider.Root>
|
|
8
|
+
export type SliderControlProps = ComponentProps<typeof BaseSlider.Control>
|
|
9
|
+
export type SliderTrackProps = ComponentProps<typeof BaseSlider.Track>
|
|
10
|
+
export type SliderIndicatorProps = ComponentProps<typeof BaseSlider.Indicator>
|
|
11
|
+
export type SliderThumbProps = ComponentProps<typeof BaseSlider.Thumb>
|
|
12
|
+
|
|
13
|
+
export const Slider = (props: SliderProps) => <BaseSlider.Root {...props} />
|
|
14
|
+
|
|
15
|
+
export const SliderControl = ({ className, ...props }: SliderControlProps) => (
|
|
16
|
+
<BaseSlider.Control
|
|
17
|
+
className={cn(
|
|
18
|
+
"flex w-full touch-none items-center py-3 select-none",
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export const SliderTrack = ({ className, ...props }: SliderTrackProps) => (
|
|
26
|
+
<BaseSlider.Track
|
|
27
|
+
className={cn(
|
|
28
|
+
"relative h-1.5 w-full rounded-full bg-background-quaternary",
|
|
29
|
+
className,
|
|
30
|
+
)}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
export const SliderIndicator = ({
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
}: SliderIndicatorProps) => (
|
|
39
|
+
<BaseSlider.Indicator
|
|
40
|
+
className={cn(
|
|
41
|
+
"absolute h-full rounded-full bg-brand-primary transition-[width] duration-150 ease-out motion-reduce:transition-none",
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
export const SliderThumb = ({ className, ...props }: SliderThumbProps) => (
|
|
49
|
+
<BaseSlider.Thumb
|
|
50
|
+
className={cn(
|
|
51
|
+
"size-4 cursor-pointer rounded-full border border-brand-primary-border bg-surface shadow-sm outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
)
|