Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions components/ui/Slider/Slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use client";
import { forwardRef, useMemo } from "react";
import * as SliderPrimitive from "@radix-ui/react-slider";
import { cn } from "@/lib/utils";
import { cva } from "class-variance-authority";

const sliderVariants = cva("relative w-full grow", {
variants: {
variant: {
default: "h-5.5",
thin: "h-4",
},
},
defaultVariants: {
variant: "default",
},
});

interface SliderProps
extends React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> {
variant?: "default" | "thin";
}

const Slider = forwardRef<
React.ComponentRef<typeof SliderPrimitive.Root>,
SliderProps
>(
(
{
variant = "default",
className,
defaultValue,
value,
min = 0,
max = 100,
...props
},
ref
) => {
const _values = useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max]
);

return (
<div className="space-y-2">
<div className="relative">
<SliderPrimitive.Root
ref={ref}
defaultValue={defaultValue}
value={value}
min={min}
max={max}
className={cn(
"relative flex w-full touch-none select-none items-center data-[disabled]:opacity-50",
className
)}
{...props}
>
<SliderPrimitive.Track
className={cn(
sliderVariants({ variant }),
"overflow-hidden border-2 border-black bg-white shadow-[4px_4px_0_0_rgba(0,0,0,1)]"
)}
>
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
{_values.map((_, index) => (
<SliderPrimitive.Thumb
key={index}
className={cn(
"block transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50",
variant === "default"
? "h-5 w-5 border-2 border-black bg-white"
: "h-4 w-4 border-2 border-black bg-white"
)}
>
<div className="absolute inset-0 -translate-x-[2px] -translate-y-[2px] border-2 border-black transition-transform hover:-translate-y-1 active:translate-y-0 bg-white group-data-[disabled]:pointer-events-none">
<div className="absolute inset-x-0 -top-1 h-[2px] bg-black/10" />
<div className="absolute inset-x-0 -bottom-1 h-[2px] bg-black/10" />
</div>
</SliderPrimitive.Thumb>
))}
</SliderPrimitive.Root>
</div>
</div>
);
}
);

Slider.displayName = "Slider";

export { Slider };
1 change: 1 addition & 0 deletions components/ui/Slider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Slider"
1 change: 1 addition & 0 deletions components/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export * from "./Badge";
export * from "./Tab";
export * from "./Dialog";
export * from "./Menu";
export * from "./Slider";
export * from "./Progress";
19 changes: 19 additions & 0 deletions config/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export const componentConfig: {
name: "text",
filePath: "components/ui/Text.tsx",
},
slider: {
name: "slider",
dependencies: ["@radix-ui/react-slider"],
filePath: "components/ui/Slider.tsx",
}
Comment on lines +82 to +86
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the file path for the slider component.

The file path in the configuration doesn't match the actual implementation path. The slider component is implemented in "components/ui/Slider/Slider.tsx" but referenced as "components/ui/Slider.tsx".

  slider: {
    name: "slider",
    dependencies: ["@radix-ui/react-slider"],
-    filePath: "components/ui/Slider.tsx",
+    filePath: "components/ui/Slider/Slider.tsx",
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
slider: {
name: "slider",
dependencies: ["@radix-ui/react-slider"],
filePath: "components/ui/Slider.tsx",
}
slider: {
name: "slider",
dependencies: ["@radix-ui/react-slider"],
filePath: "components/ui/Slider/Slider.tsx",
}

},
examples: {
"accordion-style-default": {
Expand Down Expand Up @@ -326,5 +331,19 @@ export const componentConfig: {
() => import("@/preview/components/dialog-style-with-form")
),
},
"slider-style-default":{
name: "slider-style-default",
filePath: "preview/components/slider-style-default.tsx",
preview: lazy(
() => import("@/preview/components/slider-style-default")
),
},
"slider-style-thin":{
name:"slider-style-thin",
filePath: "preview/components/slider-style-thin.tsx",
preview: lazy(
() => import("@/preview/components/slider-style-thin")
),
},
},
};
54 changes: 54 additions & 0 deletions content/docs/components/slider.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: Slider
description: A customizable slider component with two variants.
lastUpdated: 25 Mar, 2025
links:
api_reference: https://www.radix-ui.com/docs/primitives/components/slider#api-reference
source: https://github.com/Logging-Stuff/RetroUI/blob/main/components/ui/Slider.tsx
---

<ComponentShowcase name="slider-style-default" />
<br />
<br />

## Installation

<ComponentInstall>
<ComponentInstall.Cli>
```sh
npx shadcn@latest add "https://retroui.dev/r/slider.json"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the CLI installation URL.

The CLI installation command references a URL to a JSON file that might not exist yet for this new component. Please verify that this URL will be valid when the PR is merged.


🏁 Script executed:

#!/bin/bash
# Check if the slider.json file exists or is planned to be created
curl -s -o /dev/null -w "%{http_code}" https://retroui.dev/r/slider.json

Length of output: 78


Action Required: Fix the CLI installation URL for slider.json

The verification shows that the URL https://retroui.dev/r/slider.json currently returns a 404 error, meaning the JSON file is not found. Please update the URL to the correct endpoint or ensure the JSON file is created and accessible by the time this PR is merged.

  • File: content/docs/components/slider.mdx
  • Location: Line 19
  • Snippet:
        npx shadcn@latest add "https://retroui.dev/r/slider.json"

```
</ComponentInstall.Cli>
<ComponentInstall.Manual>

#### 1. Install dependencies:

```sh
npm install @radix-ui/react-slider
```

<br />

#### 2. Copy the code 👇 into your project:

<ComponentSource name="slider" />

</ComponentInstall.Manual>
</ComponentInstall>

<br />
<br />

## Examples

### Default

<ComponentShowcase name="slider-style-default" />
<br />
<br />

### Thin

<ComponentShowcase name="slider-style-thin" />
<br />
<br />
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@radix-ui/react-progress": "^1.1.2",
"@radix-ui/react-radio-group": "^1.2.3",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-slider": "^1.2.3",
"@radix-ui/react-switch": "^1.1.3",
"@radix-ui/react-visually-hidden": "^1.1.0",
"class-variance-authority": "^0.7.0",
Expand Down
35 changes: 35 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions preview/components/slider-style-default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Slider } from "@/components/ui"
import { Label } from "@/components/ui"

export default function SliderDefault() {
return (
<div className="p-6 max-w-md mx-auto">
<div className="mb-6">
<Label
htmlFor="default-slider"
className="block text-sm font-medium mb-2"
>
Slider control
</Label>
<Slider
defaultValue={[50]}
min={0}
max={100}
step={1}
variant="default"
aria-label="Slider Control"
/>
</div>
</div>
);
}
25 changes: 25 additions & 0 deletions preview/components/slider-style-thin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Slider } from "@/components/ui";
import { Label } from "@/components/ui"

export default function SliderDefault() {
return (
<div className="p-6 max-w-md mx-auto">
<div className="mb-6">
<Label
htmlFor="default-slider"
className="block text-sm font-medium mb-2"
>
Volume Control
</Label>
<Slider
defaultValue={[45]}
min={0}
max={100}
step={1}
variant="thin"
aria-label="Volume Control"
/>
</div>
</div>
);
}