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 package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"jsdom": "^26.0.0",
"postcss": "^8.5.1",
"prettier": "^3.4.2",
"resize-observer-polyfill": "^1.5.1",
"semantic-release": "^24.2.1",
"storybook": "^8.5.2",
"tailwindcss": "^3.4.17",
Expand All @@ -68,6 +69,7 @@
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-scroll-area": "^1.2.9",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-slider": "^1.3.5",
"@radix-ui/react-slot": "^1.1.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down
79 changes: 79 additions & 0 deletions src/components/__snapshots__/slider.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Slider component > renders correctly 1`] = `
<div>
<span
aria-disabled="false"
class="group relative flex w-full touch-none select-none items-center aria-disabled:cursor-not-allowed"
data-orientation="horizontal"
dir="ltr"
style="--radix-slider-thumb-transform: translateX(-50%);"
>
<span
class="relative h-2 w-full grow overflow-hidden rounded-full bg-gray-500/50"
data-orientation="horizontal"
>
<span
class="absolute h-full bg-dodger-blue group-aria-disabled:bg-gray-500"
data-orientation="horizontal"
style="left: 0%; right: 50%;"
/>
</span>
<span
style="transform: var(--radix-slider-thumb-transform); position: absolute; left: calc(50% + 0px);"
>
<span
aria-orientation="horizontal"
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="50"
class="block h-5 w-5 rounded-full border-2 border-dodger-blue bg-white ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-dodger-blue focus-visible:ring-offset-2 disabled:pointer-events-none group-aria-disabled:border-gray-500"
data-orientation="horizontal"
data-radix-collection-item=""
role="slider"
style=""
tabindex="0"
/>
</span>
</span>
</div>
`;

exports[`Slider component > renders correctly while disabled 1`] = `
<div>
<span
aria-disabled="false"
class="group relative flex w-full touch-none select-none items-center aria-disabled:cursor-not-allowed"
data-orientation="horizontal"
dir="ltr"
style="--radix-slider-thumb-transform: translateX(-50%);"
>
<span
class="relative h-2 w-full grow overflow-hidden rounded-full bg-gray-500/50"
data-orientation="horizontal"
>
<span
class="absolute h-full bg-dodger-blue group-aria-disabled:bg-gray-500"
data-orientation="horizontal"
style="left: 0%; right: 50%;"
/>
</span>
<span
style="transform: var(--radix-slider-thumb-transform); position: absolute; left: calc(50% + 0px);"
>
<span
aria-orientation="horizontal"
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="50"
class="block h-5 w-5 rounded-full border-2 border-dodger-blue bg-white ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-dodger-blue focus-visible:ring-offset-2 disabled:pointer-events-none group-aria-disabled:border-gray-500"
data-orientation="horizontal"
data-radix-collection-item=""
role="slider"
style=""
tabindex="0"
/>
</span>
</span>
</div>
`;
19 changes: 19 additions & 0 deletions src/components/slider.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { render } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { Slider } from "./slider";

describe("Slider component", () => {
it("renders correctly", () => {
const { container } = render(
<Slider defaultValue={[50]} max={100} step={1} />
);
expect(container).toMatchSnapshot();
});

it("renders correctly while disabled", () => {
const { container } = render(
<Slider defaultValue={[50]} max={100} step={1} />
);
expect(container).toMatchSnapshot();
});
});
32 changes: 32 additions & 0 deletions src/components/slider.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Slider } from "./slider";

const meta = {
title: "Slider",
component: Slider,
parameters: {
layout: "centered",
},
} satisfies Meta<typeof Slider>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
defaultValue: [50],
max: 100,
step: 1,
className: "w-[300px]",
},
};

export const Disabled: Story = {
args: {
defaultValue: [50],
max: 100,
step: 1,
className: "w-[300px]",
disabled: true,
},
};
28 changes: 28 additions & 0 deletions src/components/slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client";

import * as SliderPrimitive from "@radix-ui/react-slider";
import * as React from "react";

import { cn } from "@/lib/utils";

const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn(
"group relative flex w-full touch-none select-none items-center aria-disabled:cursor-not-allowed",
className
)}
{...props}
>
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-gray-500/50">
<SliderPrimitive.Range className="absolute h-full bg-dodger-blue group-aria-disabled:bg-gray-500" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-dodger-blue bg-white ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-dodger-blue focus-visible:ring-offset-2 disabled:pointer-events-none group-aria-disabled:border-gray-500" />
</SliderPrimitive.Root>
));
Slider.displayName = SliderPrimitive.Root.displayName;

export { Slider };
2 changes: 2 additions & 0 deletions test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import ResizeObserver from "resize-observer-polyfill";
window.ResizeObserver = ResizeObserver;
1 change: 1 addition & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export default defineConfig({
test: {
include: ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"],
environment: "jsdom",
setupFiles: ["./test-setup.ts"],
},
});