feat: add skeleton, slider and sonner

This commit is contained in:
shadcn
2026-01-19 21:18:56 +04:00
parent 572e5d4532
commit e7d802fc07
48 changed files with 407 additions and 587 deletions

View File

@@ -5,11 +5,7 @@ base: base
component: true
---
<ComponentPreview
styleName="base-nova"
name="skeleton-demo"
description="A skeleton component."
/>
<ComponentPreview styleName="base-nova" name="skeleton-demo" />
## Installation
@@ -59,10 +55,26 @@ import { Skeleton } from "@/components/ui/skeleton"
## Examples
### Avatar
<ComponentPreview styleName="base-nova" name="skeleton-avatar" />
### Card
<ComponentPreview
styleName="base-nova"
name="skeleton-card"
description="A card with skeleton showing a loading state."
previewClassName="h-80"
/>
### Text
<ComponentPreview styleName="base-nova" name="skeleton-text" />
### Form
<ComponentPreview styleName="base-nova" name="skeleton-form" />
### Table
<ComponentPreview styleName="base-nova" name="skeleton-table" />

View File

@@ -8,11 +8,7 @@ links:
api: https://base-ui.com/react/components/slider#api-reference
---
<ComponentPreview
styleName="base-nova"
name="slider-demo"
description="A slider component."
/>
<ComponentPreview styleName="base-nova" name="slider-demo" />
## Installation
@@ -65,3 +61,37 @@ import { Slider } from "@/components/ui/slider"
```tsx
<Slider defaultValue={[33]} max={100} step={1} />
```
## Examples
### Range
Use an array with two values for a range slider.
<ComponentPreview styleName="base-nova" name="slider-range" />
### Multiple Thumbs
Use an array with multiple values for multiple thumbs.
<ComponentPreview styleName="base-nova" name="slider-multiple" />
### Vertical
Use `orientation="vertical"` for a vertical slider.
<ComponentPreview styleName="base-nova" name="slider-vertical" />
### Controlled
<ComponentPreview styleName="base-nova" name="slider-controlled" />
### Disabled
Use the `disabled` prop to disable the slider.
<ComponentPreview styleName="base-nova" name="slider-disabled" />
## API Reference
See the [Base UI Slider](https://base-ui.com/react/components/slider#api-reference) documentation.

View File

@@ -33,7 +33,7 @@ npx shadcn@latest add sonner
<Step>Add the Toaster component</Step>
```tsx title="app/layout.tsx" {1,9}
```tsx title="app/layout.tsx" {1,9} showLineNumbers
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
@@ -107,53 +107,20 @@ toast("Event has been created.")
## Examples
### Types
<ComponentPreview styleName="base-nova" name="sonner-types" />
## Changelog
### Description
### 2025-10-13 Icons
<ComponentPreview styleName="base-nova" name="sonner-description" />
We've updated the Sonner component to use icons from `lucide`. Update your `sonner.tsx` file to use the new icons.
### Position
```tsx showLineNumbers title="components/ui/sonner.tsx" {3-9,20-26}
"use client"
Use the `position` prop to change the position of the toast.
import {
CircleCheckIcon,
InfoIcon,
Loader2Icon,
OctagonXIcon,
TriangleAlertIcon,
} from "lucide-react"
import { useTheme } from "next-themes"
import { Toaster as Sonner, ToasterProps } from "sonner"
<ComponentPreview styleName="base-nova" name="sonner-position" />
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
## API Reference
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
icons={{
success: <CircleCheckIcon className="size-4" />,
info: <InfoIcon className="size-4" />,
warning: <TriangleAlertIcon className="size-4" />,
error: <OctagonXIcon className="size-4" />,
loading: <Loader2Icon className="size-4 animate-spin" />,
}}
style={
{
"--normal-bg": "var(--popover)",
"--normal-text": "var(--popover-foreground)",
"--normal-border": "var(--border)",
"--border-radius": "var(--radius)",
} as React.CSSProperties
}
{...props}
/>
)
}
export { Toaster }
```
See the [Sonner API Reference](https://sonner.emilkowal.ski/api) for more information.

View File

@@ -5,11 +5,7 @@ base: radix
component: true
---
<ComponentPreview
styleName="radix-nova"
name="skeleton-demo"
description="A skeleton component."
/>
<ComponentPreview styleName="radix-nova" name="skeleton-demo" />
## Installation
@@ -59,10 +55,26 @@ import { Skeleton } from "@/components/ui/skeleton"
## Examples
### Avatar
<ComponentPreview styleName="radix-nova" name="skeleton-avatar" />
### Card
<ComponentPreview
styleName="radix-nova"
name="skeleton-card"
description="A card with skeleton showing a loading state."
previewClassName="h-80"
/>
### Text
<ComponentPreview styleName="radix-nova" name="skeleton-text" />
### Form
<ComponentPreview styleName="radix-nova" name="skeleton-form" />
### Table
<ComponentPreview styleName="radix-nova" name="skeleton-table" />

View File

@@ -8,11 +8,7 @@ links:
api: https://www.radix-ui.com/docs/primitives/components/slider#api-reference
---
<ComponentPreview
styleName="radix-nova"
name="slider-demo"
description="A slider component."
/>
<ComponentPreview styleName="radix-nova" name="slider-demo" />
## Installation
@@ -65,3 +61,37 @@ import { Slider } from "@/components/ui/slider"
```tsx
<Slider defaultValue={[33]} max={100} step={1} />
```
## Examples
### Range
Use an array with two values for a range slider.
<ComponentPreview styleName="radix-nova" name="slider-range" />
### Multiple Thumbs
Use an array with multiple values for multiple thumbs.
<ComponentPreview styleName="radix-nova" name="slider-multiple" />
### Vertical
Use `orientation="vertical"` for a vertical slider.
<ComponentPreview styleName="radix-nova" name="slider-vertical" />
### Controlled
<ComponentPreview styleName="radix-nova" name="slider-controlled" />
### Disabled
Use the `disabled` prop to disable the slider.
<ComponentPreview styleName="radix-nova" name="slider-disabled" />
## API Reference
See the [Radix UI Slider](https://www.radix-ui.com/docs/primitives/components/slider#api-reference) documentation.

View File

@@ -33,7 +33,7 @@ npx shadcn@latest add sonner
<Step>Add the Toaster component</Step>
```tsx title="app/layout.tsx" {1,9}
```tsx title="app/layout.tsx" {1,9} showLineNumbers
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
@@ -107,53 +107,20 @@ toast("Event has been created.")
## Examples
### Types
<ComponentPreview styleName="radix-nova" name="sonner-types" />
## Changelog
### Description
### 2025-10-13 Icons
<ComponentPreview styleName="radix-nova" name="sonner-description" />
We've updated the Sonner component to use icons from `lucide`. Update your `sonner.tsx` file to use the new icons.
### Position
```tsx showLineNumbers title="components/ui/sonner.tsx" {3-9,20-26}
"use client"
Use the `position` prop to change the position of the toast.
import {
CircleCheckIcon,
InfoIcon,
Loader2Icon,
OctagonXIcon,
TriangleAlertIcon,
} from "lucide-react"
import { useTheme } from "next-themes"
import { Toaster as Sonner, ToasterProps } from "sonner"
<ComponentPreview styleName="radix-nova" name="sonner-position" />
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
## API Reference
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
icons={{
success: <CircleCheckIcon className="size-4" />,
info: <InfoIcon className="size-4" />,
warning: <TriangleAlertIcon className="size-4" />,
error: <OctagonXIcon className="size-4" />,
loading: <Loader2Icon className="size-4 animate-spin" />,
}}
style={
{
"--normal-bg": "var(--popover)",
"--normal-text": "var(--popover-foreground)",
"--normal-border": "var(--border)",
"--border-radius": "var(--radius)",
} as React.CSSProperties
}
{...props}
/>
)
}
export { Toaster }
```
See the [Sonner API Reference](https://sonner.emilkowal.ski/api) for more information.

View File

@@ -3905,19 +3905,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"slider-basic": {
name: "slider-basic",
filePath: "examples/radix/slider-basic.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/slider-basic")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "slider-basic"
return { default: mod.default || mod[exportName] }
}),
},
"slider-controlled": {
name: "slider-controlled",
filePath: "examples/radix/slider-controlled.tsx",
@@ -3957,19 +3944,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"slider-fields": {
name: "slider-fields",
filePath: "examples/radix/slider-fields.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/slider-fields")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "slider-fields"
return { default: mod.default || mod[exportName] }
}),
},
"slider-multiple": {
name: "slider-multiple",
filePath: "examples/radix/slider-multiple.tsx",
@@ -4009,19 +3983,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-basic": {
name: "sonner-basic",
filePath: "examples/radix/sonner-basic.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/sonner-basic")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-basic"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-demo": {
name: "sonner-demo",
filePath: "examples/radix/sonner-demo.tsx",
@@ -4035,6 +3996,32 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-description": {
name: "sonner-description",
filePath: "examples/radix/sonner-description.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/sonner-description")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-description"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-position": {
name: "sonner-position",
filePath: "examples/radix/sonner-position.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/sonner-position")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-position"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-types": {
name: "sonner-types",
filePath: "examples/radix/sonner-types.tsx",
@@ -4048,19 +4035,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-with-description": {
name: "sonner-with-description",
filePath: "examples/radix/sonner-with-description.tsx",
component: React.lazy(async () => {
const mod = await import("./radix/sonner-with-description")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-with-description"
return { default: mod.default || mod[exportName] }
}),
},
"spinner-badge": {
name: "spinner-badge",
filePath: "examples/radix/spinner-badge.tsx",
@@ -9317,19 +9291,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"slider-basic": {
name: "slider-basic",
filePath: "examples/base/slider-basic.tsx",
component: React.lazy(async () => {
const mod = await import("./base/slider-basic")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "slider-basic"
return { default: mod.default || mod[exportName] }
}),
},
"slider-controlled": {
name: "slider-controlled",
filePath: "examples/base/slider-controlled.tsx",
@@ -9369,19 +9330,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"slider-fields": {
name: "slider-fields",
filePath: "examples/base/slider-fields.tsx",
component: React.lazy(async () => {
const mod = await import("./base/slider-fields")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "slider-fields"
return { default: mod.default || mod[exportName] }
}),
},
"slider-multiple": {
name: "slider-multiple",
filePath: "examples/base/slider-multiple.tsx",
@@ -9421,19 +9369,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-basic": {
name: "sonner-basic",
filePath: "examples/base/sonner-basic.tsx",
component: React.lazy(async () => {
const mod = await import("./base/sonner-basic")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-basic"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-demo": {
name: "sonner-demo",
filePath: "examples/base/sonner-demo.tsx",
@@ -9447,6 +9382,32 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-description": {
name: "sonner-description",
filePath: "examples/base/sonner-description.tsx",
component: React.lazy(async () => {
const mod = await import("./base/sonner-description")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-description"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-position": {
name: "sonner-position",
filePath: "examples/base/sonner-position.tsx",
component: React.lazy(async () => {
const mod = await import("./base/sonner-position")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-position"
return { default: mod.default || mod[exportName] }
}),
},
"sonner-types": {
name: "sonner-types",
filePath: "examples/base/sonner-types.tsx",
@@ -9460,19 +9421,6 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
return { default: mod.default || mod[exportName] }
}),
},
"sonner-with-description": {
name: "sonner-with-description",
filePath: "examples/base/sonner-with-description.tsx",
component: React.lazy(async () => {
const mod = await import("./base/sonner-with-description")
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object"
) || "sonner-with-description"
return { default: mod.default || mod[exportName] }
}),
},
"spinner-badge": {
name: "spinner-badge",
filePath: "examples/base/spinner-badge.tsx",

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonAvatar() {
return (
<div className="flex w-full items-center gap-4">
<div className="flex w-fit items-center gap-4">
<Skeleton className="size-10 shrink-0 rounded-full" />
<div className="grid gap-2">
<Skeleton className="h-4 w-[150px]" />

View File

@@ -3,13 +3,13 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonCard() {
return (
<Card className="w-full">
<Card className="w-full max-w-xs">
<CardHeader>
<Skeleton className="h-4 w-2/3" />
<Skeleton className="h-4 w-1/2" />
</CardHeader>
<CardContent>
<Skeleton className="aspect-square w-full" />
<Skeleton className="aspect-video w-full" />
</CardContent>
</Card>
)

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonDemo() {
return (
<div className="flex items-center space-x-4">
<div className="flex items-center gap-4">
<Skeleton className="h-12 w-12 rounded-full" />
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />

View File

@@ -2,16 +2,16 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonForm() {
return (
<div className="flex w-full flex-col gap-7">
<div className="flex w-full max-w-xs flex-col gap-7">
<div className="flex flex-col gap-3">
<Skeleton className="h-4 w-20" />
<Skeleton className="h-10 w-full" />
<Skeleton className="h-8 w-full" />
</div>
<div className="flex flex-col gap-3">
<Skeleton className="h-4 w-24" />
<Skeleton className="h-10 w-full" />
<Skeleton className="h-8 w-full" />
</div>
<Skeleton className="h-9 w-24" />
<Skeleton className="h-8 w-24" />
</div>
)
}

View File

@@ -2,22 +2,14 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonTable() {
return (
<div className="flex w-full flex-col gap-2">
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex w-full max-w-sm flex-col gap-2">
{Array.from({ length: 5 }).map((_, index) => (
<div className="flex gap-4" key={index}>
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
))}
</div>
)
}

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/base/ui/skeleton"
export function SkeletonText() {
return (
<div className="flex w-full flex-col gap-2">
<div className="flex w-full max-w-xs flex-col gap-2">
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-3/4" />

View File

@@ -1,5 +0,0 @@
import { Slider } from "@/examples/base/ui/slider"
export function SliderBasic() {
return <Slider defaultValue={50} max={100} step={1} />
}

View File

@@ -8,7 +8,7 @@ export function SliderControlled() {
const [value, setValue] = React.useState([0.3, 0.7])
return (
<div className="grid w-full gap-3">
<div className="mx-auto grid w-full max-w-xs gap-3">
<div className="flex items-center justify-between gap-2">
<Label htmlFor="slider-demo-temperature">Temperature</Label>
<span className="text-muted-foreground text-sm">

View File

@@ -1,17 +1,12 @@
import { Slider } from "@/examples/base/ui/slider"
import { cn } from "@/lib/utils"
type SliderProps = React.ComponentProps<typeof Slider>
export function SliderDemo({ className, ...props }: SliderProps) {
export function SliderDemo() {
return (
<Slider
defaultValue={[50]}
defaultValue={[75]}
max={100}
step={1}
className={cn("w-[60%]", className)}
{...props}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,5 +1,13 @@
import { Slider } from "@/examples/base/ui/slider"
export function SliderDisabled() {
return <Slider defaultValue={[50]} max={100} step={1} disabled />
return (
<Slider
defaultValue={[50]}
max={100}
step={1}
disabled
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,119 +0,0 @@
"use client"
import * as React from "react"
import { useState } from "react"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/examples/base/ui/field"
import { Slider } from "@/examples/base/ui/slider"
export function SliderFields() {
const [volume, setVolume] = useState([50])
const [brightness, setBrightness] = useState([75])
const [temperature, setTemperature] = useState([0.3, 0.7])
const [priceRange, setPriceRange] = useState([25, 75])
const [colorBalance, setColorBalance] = useState([10, 20, 70])
return (
<FieldGroup>
<Field>
<FieldLabel htmlFor="slider-volume">Volume</FieldLabel>
<Slider
id="slider-volume"
value={volume}
onValueChange={(value) => setVolume(value as number[])}
max={100}
step={1}
/>
</Field>
<Field>
<FieldLabel htmlFor="slider-brightness">Screen Brightness</FieldLabel>
<Slider
id="slider-brightness"
value={brightness}
onValueChange={(value) => setBrightness(value as number[])}
max={100}
step={5}
/>
<FieldDescription>
Current brightness: {brightness[0]}%
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-quality">Video Quality</FieldLabel>
<FieldDescription>Higher quality uses more bandwidth.</FieldDescription>
<Slider
id="slider-quality"
defaultValue={[720]}
max={1080}
min={360}
step={360}
/>
</Field>
<Field>
<FieldLabel htmlFor="slider-temperature">Temperature Range</FieldLabel>
<Slider
id="slider-temperature"
value={temperature}
onValueChange={(value) => setTemperature(value as number[])}
min={0}
max={1}
step={0.1}
/>
<FieldDescription>
Range: {temperature[0].toFixed(1)} - {temperature[1].toFixed(1)}
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-price-range">Price Range</FieldLabel>
<Slider
id="slider-price-range"
value={priceRange}
onValueChange={(value) => setPriceRange(value as number[])}
max={100}
step={5}
/>
<FieldDescription>
${priceRange[0]} - ${priceRange[1]}
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-color-balance">Color Balance</FieldLabel>
<Slider
id="slider-color-balance"
value={colorBalance}
onValueChange={(value) => setColorBalance(value as number[])}
max={100}
step={10}
/>
<FieldDescription>
Red: {colorBalance[0]}%, Green: {colorBalance[1]}%, Blue:{" "}
{colorBalance[2]}%
</FieldDescription>
</Field>
<Field data-invalid>
<FieldLabel htmlFor="slider-invalid">Invalid Slider</FieldLabel>
<Slider
id="slider-invalid"
defaultValue={[30]}
max={100}
aria-invalid
/>
<FieldDescription>This slider has validation errors.</FieldDescription>
</Field>
<Field data-disabled>
<FieldLabel htmlFor="slider-disabled-field">Disabled Slider</FieldLabel>
<Slider
id="slider-disabled-field"
defaultValue={[50]}
max={100}
disabled
/>
<FieldDescription>This slider is currently disabled.</FieldDescription>
</Field>
</FieldGroup>
)
}

View File

@@ -1,5 +1,12 @@
import { Slider } from "@/examples/base/ui/slider"
export function SliderMultiple() {
return <Slider defaultValue={[10, 20, 70]} max={100} step={10} />
return (
<Slider
defaultValue={[10, 20, 70]}
max={100}
step={10}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,5 +1,12 @@
import { Slider } from "@/examples/base/ui/slider"
export function SliderRange() {
return <Slider defaultValue={[25, 50]} max={100} step={5} />
return (
<Slider
defaultValue={[25, 50]}
max={100}
step={5}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -2,7 +2,7 @@ import { Slider } from "@/examples/base/ui/slider"
export function SliderVertical() {
return (
<div className="flex items-center gap-6">
<div className="mx-auto flex w-full max-w-xs items-center justify-center gap-6">
<Slider
defaultValue={[50]}
max={100}

View File

@@ -1,14 +0,0 @@
import { Button } from "@/examples/base/ui/button"
import { toast } from "sonner"
export function SonnerBasic() {
return (
<Button
onClick={() => toast("Event has been created")}
variant="outline"
className="w-fit"
>
Show Toast
</Button>
)
}

View File

@@ -1,7 +1,9 @@
"use client"
import { Button } from "@/examples/base/ui/button"
import { toast } from "sonner"
export function SonnerWithDescription() {
export function SonnerDescription() {
return (
<Button
onClick={() =>

View File

@@ -0,0 +1,59 @@
"use client"
import { Button } from "@/examples/base/ui/button"
import { toast } from "sonner"
export function SonnerPosition() {
return (
<div className="flex flex-wrap justify-center gap-2">
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-left" })
}
>
Top Left
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-center" })
}
>
Top Center
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-right" })
}
>
Top Right
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-left" })
}
>
Bottom Left
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-center" })
}
>
Bottom Center
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-right" })
}
>
Bottom Right
</Button>
</div>
)
}

View File

@@ -24,7 +24,7 @@ function Slider({
return (
<SliderPrimitive.Root
className="data-horizontal:w-full data-vertical:h-full"
className={cn("data-horizontal:w-full data-vertical:h-full", className)}
data-slot="slider"
defaultValue={defaultValue}
value={value}
@@ -33,15 +33,10 @@ function Slider({
thumbAlignment="edge"
{...props}
>
<SliderPrimitive.Control
className={cn(
"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col",
className
)}
>
<SliderPrimitive.Control className="relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col">
<SliderPrimitive.Track
data-slot="slider-track"
className="bg-muted relative overflow-hidden rounded-full select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
className="bg-muted relative grow overflow-hidden rounded-full select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
>
<SliderPrimitive.Indicator
data-slot="slider-range"

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonAvatar() {
return (
<div className="flex w-full items-center gap-4">
<div className="flex w-fit items-center gap-4">
<Skeleton className="size-10 shrink-0 rounded-full" />
<div className="grid gap-2">
<Skeleton className="h-4 w-[150px]" />

View File

@@ -3,13 +3,13 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonCard() {
return (
<Card className="w-full">
<Card className="w-full max-w-xs">
<CardHeader>
<Skeleton className="h-4 w-2/3" />
<Skeleton className="h-4 w-1/2" />
</CardHeader>
<CardContent>
<Skeleton className="aspect-square w-full" />
<Skeleton className="aspect-video w-full" />
</CardContent>
</Card>
)

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonDemo() {
return (
<div className="flex items-center space-x-4">
<div className="flex items-center gap-4">
<Skeleton className="h-12 w-12 rounded-full" />
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />

View File

@@ -2,16 +2,16 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonForm() {
return (
<div className="flex w-full flex-col gap-7">
<div className="flex w-full max-w-xs flex-col gap-7">
<div className="flex flex-col gap-3">
<Skeleton className="h-4 w-20" />
<Skeleton className="h-10 w-full" />
<Skeleton className="h-8 w-full" />
</div>
<div className="flex flex-col gap-3">
<Skeleton className="h-4 w-24" />
<Skeleton className="h-10 w-full" />
<Skeleton className="h-8 w-full" />
</div>
<Skeleton className="h-9 w-24" />
<Skeleton className="h-8 w-24" />
</div>
)
}

View File

@@ -2,22 +2,14 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonTable() {
return (
<div className="flex w-full flex-col gap-2">
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex gap-4">
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
<div className="flex w-full max-w-sm flex-col gap-2">
{Array.from({ length: 5 }).map((_, index) => (
<div className="flex gap-4" key={index}>
<Skeleton className="h-4 flex-1" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-20" />
</div>
))}
</div>
)
}

View File

@@ -2,7 +2,7 @@ import { Skeleton } from "@/examples/radix/ui/skeleton"
export function SkeletonText() {
return (
<div className="flex w-full flex-col gap-2">
<div className="flex w-full max-w-xs flex-col gap-2">
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-3/4" />

View File

@@ -1,5 +0,0 @@
import { Slider } from "@/examples/radix/ui/slider"
export function SliderBasic() {
return <Slider defaultValue={[50]} max={100} step={1} />
}

View File

@@ -8,7 +8,7 @@ export function SliderControlled() {
const [value, setValue] = React.useState([0.3, 0.7])
return (
<div className="grid w-full gap-3">
<div className="mx-auto grid w-full max-w-xs gap-3">
<div className="flex items-center justify-between gap-2">
<Label htmlFor="slider-demo-temperature">Temperature</Label>
<span className="text-muted-foreground text-sm">

View File

@@ -1,17 +1,12 @@
import { Slider } from "@/examples/radix/ui/slider"
import { cn } from "@/lib/utils"
type SliderProps = React.ComponentProps<typeof Slider>
export function SliderDemo({ className, ...props }: SliderProps) {
export function SliderDemo() {
return (
<Slider
defaultValue={[50]}
defaultValue={[75]}
max={100}
step={1}
className={cn("w-[60%]", className)}
{...props}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,5 +1,13 @@
import { Slider } from "@/examples/radix/ui/slider"
export function SliderDisabled() {
return <Slider defaultValue={[50]} max={100} step={1} disabled />
return (
<Slider
defaultValue={[50]}
max={100}
step={1}
disabled
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,119 +0,0 @@
"use client"
import * as React from "react"
import { useState } from "react"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/examples/radix/ui/field"
import { Slider } from "@/examples/radix/ui/slider"
export function SliderFields() {
const [volume, setVolume] = useState([50])
const [brightness, setBrightness] = useState([75])
const [temperature, setTemperature] = useState([0.3, 0.7])
const [priceRange, setPriceRange] = useState([25, 75])
const [colorBalance, setColorBalance] = useState([10, 20, 70])
return (
<FieldGroup>
<Field>
<FieldLabel htmlFor="slider-volume">Volume</FieldLabel>
<Slider
id="slider-volume"
value={volume}
onValueChange={setVolume}
max={100}
step={1}
/>
</Field>
<Field>
<FieldLabel htmlFor="slider-brightness">Screen Brightness</FieldLabel>
<Slider
id="slider-brightness"
value={brightness}
onValueChange={setBrightness}
max={100}
step={5}
/>
<FieldDescription>
Current brightness: {brightness[0]}%
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-quality">Video Quality</FieldLabel>
<FieldDescription>Higher quality uses more bandwidth.</FieldDescription>
<Slider
id="slider-quality"
defaultValue={[720]}
max={1080}
min={360}
step={360}
/>
</Field>
<Field>
<FieldLabel htmlFor="slider-temperature">Temperature Range</FieldLabel>
<Slider
id="slider-temperature"
value={temperature}
onValueChange={setTemperature}
min={0}
max={1}
step={0.1}
/>
<FieldDescription>
Range: {temperature[0].toFixed(1)} - {temperature[1].toFixed(1)}
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-price-range">Price Range</FieldLabel>
<Slider
id="slider-price-range"
value={priceRange}
onValueChange={setPriceRange}
max={100}
step={5}
/>
<FieldDescription>
${priceRange[0]} - ${priceRange[1]}
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="slider-color-balance">Color Balance</FieldLabel>
<Slider
id="slider-color-balance"
value={colorBalance}
onValueChange={setColorBalance}
max={100}
step={10}
/>
<FieldDescription>
Red: {colorBalance[0]}%, Green: {colorBalance[1]}%, Blue:{" "}
{colorBalance[2]}%
</FieldDescription>
</Field>
<Field data-invalid>
<FieldLabel htmlFor="slider-invalid">Invalid Slider</FieldLabel>
<Slider
id="slider-invalid"
defaultValue={[30]}
max={100}
aria-invalid
/>
<FieldDescription>This slider has validation errors.</FieldDescription>
</Field>
<Field data-disabled>
<FieldLabel htmlFor="slider-disabled-field">Disabled Slider</FieldLabel>
<Slider
id="slider-disabled-field"
defaultValue={[50]}
max={100}
disabled
/>
<FieldDescription>This slider is currently disabled.</FieldDescription>
</Field>
</FieldGroup>
)
}

View File

@@ -1,5 +1,12 @@
import { Slider } from "@/examples/radix/ui/slider"
export function SliderMultiple() {
return <Slider defaultValue={[10, 20, 70]} max={100} step={10} />
return (
<Slider
defaultValue={[10, 20, 70]}
max={100}
step={10}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -1,5 +1,12 @@
import { Slider } from "@/examples/radix/ui/slider"
export function SliderRange() {
return <Slider defaultValue={[25, 50]} max={100} step={5} />
return (
<Slider
defaultValue={[25, 50]}
max={100}
step={5}
className="mx-auto w-full max-w-xs"
/>
)
}

View File

@@ -2,7 +2,7 @@ import { Slider } from "@/examples/radix/ui/slider"
export function SliderVertical() {
return (
<div className="flex items-center gap-6">
<div className="mx-auto flex w-full max-w-xs items-center justify-center gap-6">
<Slider
defaultValue={[50]}
max={100}

View File

@@ -1,14 +0,0 @@
import { Button } from "@/examples/radix/ui/button"
import { toast } from "sonner"
export function SonnerBasic() {
return (
<Button
onClick={() => toast("Event has been created")}
variant="outline"
className="w-fit"
>
Show Toast
</Button>
)
}

View File

@@ -1,7 +1,9 @@
"use client"
import { Button } from "@/examples/radix/ui/button"
import { toast } from "sonner"
export function SonnerWithDescription() {
export function SonnerDescription() {
return (
<Button
onClick={() =>

View File

@@ -0,0 +1,59 @@
"use client"
import { Button } from "@/examples/radix/ui/button"
import { toast } from "sonner"
export function SonnerPosition() {
return (
<div className="flex flex-wrap justify-center gap-2">
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-left" })
}
>
Top Left
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-center" })
}
>
Top Center
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "top-right" })
}
>
Top Right
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-left" })
}
>
Bottom Left
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-center" })
}
>
Bottom Center
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", { position: "bottom-right" })
}
>
Bottom Right
</Button>
</div>
)
}

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-lyra/ui/slider.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className=\"data-horizontal:w-full data-vertical:h-full\"\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control\n className={cn(\n \"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\",\n className\n )}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 relative overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-ring ring-ring/50 relative size-3 rounded-none border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-1 focus-visible:ring-1 focus-visible:outline-hidden active:ring-1 block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 relative grow overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-ring ring-ring/50 relative size-3 rounded-none border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-1 focus-visible:ring-1 focus-visible:outline-hidden active:ring-1 block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-maia/ui/slider.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-maia/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className=\"data-horizontal:w-full data-vertical:h-full\"\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control\n className={cn(\n \"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\",\n className\n )}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-4xl data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3 relative overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 size-4 rounded-4xl border bg-white shadow-sm transition-colors hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-maia/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-4xl data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3 relative grow overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 size-4 rounded-4xl border bg-white shadow-sm transition-colors hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-mira/ui/slider.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-mira/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className=\"data-horizontal:w-full data-vertical:h-full\"\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control\n className={cn(\n \"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\",\n className\n )}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-md data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3 relative overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/30 size-4 rounded-md border bg-white shadow-sm transition-colors hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-mira/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-md data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3 relative grow overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/30 size-4 rounded-md border bg-white shadow-sm transition-colors hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-nova/ui/slider.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-nova/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className=\"data-horizontal:w-full data-vertical:h-full\"\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control\n className={cn(\n \"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\",\n className\n )}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-full data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 relative overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-ring ring-ring/50 relative size-3 rounded-full border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-[3px] focus-visible:ring-[3px] focus-visible:outline-hidden active:ring-[3px] block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-nova/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-full data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 relative grow overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-ring ring-ring/50 relative size-3 rounded-full border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-[3px] focus-visible:ring-[3px] focus-visible:outline-hidden active:ring-[3px] block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-vega/ui/slider.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-vega/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className=\"data-horizontal:w-full data-vertical:h-full\"\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control\n className={cn(\n \"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\",\n className\n )}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-full data-horizontal:h-1.5 data-horizontal:w-full data-vertical:h-full data-vertical:w-1.5 relative overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 size-4 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/registry/base-vega/lib/utils\"\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: SliderPrimitive.Root.Props) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n )\n\n return (\n <SliderPrimitive.Root\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n thumbAlignment=\"edge\"\n {...props}\n >\n <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className=\"bg-muted rounded-full data-horizontal:h-1.5 data-horizontal:w-full data-vertical:h-full data-vertical:w-1.5 relative grow overflow-hidden select-none\"\n >\n <SliderPrimitive.Indicator\n data-slot=\"slider-range\"\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 size-4 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n )\n}\n\nexport { Slider }\n",
"type": "registry:ui"
}
],

View File

@@ -25,7 +25,7 @@ function Slider({
return (
<SliderPrimitive.Root
className="data-horizontal:w-full data-vertical:h-full"
className={cn("data-horizontal:w-full data-vertical:h-full", className)}
data-slot="slider"
defaultValue={defaultValue}
value={value}
@@ -34,15 +34,10 @@ function Slider({
thumbAlignment="edge"
{...props}
>
<SliderPrimitive.Control
className={cn(
"cn-slider relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col",
className
)}
>
<SliderPrimitive.Control className="cn-slider relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col">
<SliderPrimitive.Track
data-slot="slider-track"
className="cn-slider-track relative overflow-hidden select-none"
className="cn-slider-track relative grow overflow-hidden select-none"
>
<SliderPrimitive.Indicator
data-slot="slider-range"