From 91c61a99a5af86eac0bf330e3426494e7816657a Mon Sep 17 00:00:00 2001 From: "phongit.kha" <153442976+Phongit-Khanthawisood@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:07:08 +0700 Subject: [PATCH] Feature/Slider (#13) * feat: add slider component * feat: add args in slider storybook --- lib/components/Slider/index.stories.tsx | 84 +++++++++++++++++++++++++ lib/components/Slider/index.tsx | 28 +++++++++ package.json | 1 + pnpm-lock.yaml | 35 +++++++++++ 4 files changed, 148 insertions(+) create mode 100644 lib/components/Slider/index.stories.tsx create mode 100644 lib/components/Slider/index.tsx diff --git a/lib/components/Slider/index.stories.tsx b/lib/components/Slider/index.stories.tsx new file mode 100644 index 0000000..d22633e --- /dev/null +++ b/lib/components/Slider/index.stories.tsx @@ -0,0 +1,84 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Slider } from '@/components/Slider' + +type SliderProps = React.ComponentProps + +const meta: Meta = { + title: 'Components/Slider', + component: Slider, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + defaultValue: { + control: { array: { type: 'number' } }, + description: 'The initial value(s) of the slider', + defaultValue: [50], // Default to 50 for the preview + }, + max: { + control: 'number', + description: 'The maximum value for the slider', + defaultValue: 100, // Default maximum value + }, + step: { + control: 'number', + description: 'The step size for the slider', + defaultValue: 1, // Default step size + }, + disabled: { + control: 'boolean', + description: 'Disable the slider', + defaultValue: false, // Slider enabled by default + }, + }, +} + +export default meta + +type Story = StoryObj +// Default Slider Story with args controls +export const Default: Story = { + args: { + defaultValue: [50], // Default starting value + max: 100, // Maximum value of the slider + step: 1, // Step size + disabled: false, // Slider is enabled by default + }, + render: (args: SliderProps) => ( +
+ +
+ ), +} + +// Custom Range Slider Story +export const CustomRange: Story = { + args: { + defaultValue: [30], + max: 200, + step: 10, + disabled: false, + }, + render: (args: SliderProps) => ( +
+ +
+ ), +} + +// Disabled Slider Story +export const Disabled: Story = { + args: { + defaultValue: [70], + max: 100, + step: 1, + disabled: true, + }, + render: (args: SliderProps) => ( +
+ +
+ ), +} diff --git a/lib/components/Slider/index.tsx b/lib/components/Slider/index.tsx new file mode 100644 index 0000000..d873627 --- /dev/null +++ b/lib/components/Slider/index.tsx @@ -0,0 +1,28 @@ +'use client' + +import * as SliderPrimitive from '@radix-ui/react-slider' +import * as React from 'react' + +import { cn } from '@/utils' + +const Slider = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + + +)) +Slider.displayName = SliderPrimitive.Root.displayName + +export { Slider } diff --git a/package.json b/package.json index da706e3..69e69c9 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slider": "^1.2.1", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-tabs": "^1.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21c06b1..539eaa1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: '@radix-ui/react-separator': specifier: ^1.1.0 version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': + specifier: ^1.2.1 + version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.3)(react@18.3.1) @@ -1022,6 +1025,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-slider@1.2.1': + resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.1.0': resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} peerDependencies: @@ -5136,6 +5152,25 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-slot@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1)