diff --git a/packages/react/package.json b/packages/react/package.json
index 0659f24ee..b9165dba4 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -50,6 +50,7 @@
"react-fast-compare": "^3.2.0",
"react-popper": "^2.2.5",
"react-popper-tooltip": "^4.3.0",
+ "react-ranger": "^2.1.0",
"react-transition-group": "^4.4.2",
"styled-system": "^5.1.4",
"tslib": "^2.3.1"
@@ -72,6 +73,7 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@types/jest": "^26.0.24",
+ "@types/react-ranger": "^2.0.1",
"@types/react-transition-group": "^4.4.2",
"@types/styled-components": "^5.1.14",
"babel-loader": "^8.2.2",
diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts
index 472ce8c7e..a5c53a425 100644
--- a/packages/react/src/components/index.ts
+++ b/packages/react/src/components/index.ts
@@ -19,6 +19,7 @@ export * from './panel';
export * from './pill';
export * from './popover';
export * from './side-sheet';
+export * from './slider';
export * from './skeleton';
export * from './table';
export * from './tabs';
diff --git a/packages/react/src/components/slider/README.md b/packages/react/src/components/slider/README.md
new file mode 100644
index 000000000..d0ac0601d
--- /dev/null
+++ b/packages/react/src/components/slider/README.md
@@ -0,0 +1,17 @@
+# Slider
+
+> Slider element.
+
+## Usage
+
+To use this component in your app, import as follows:
+
+```jsx
+import { Slider } from '@aksara-ui/react';
+
+export function Example({ min, max, stepSize }) {
+ const [values, setValues] = React.useState([10]);
+
+ return ;
+};
+```
diff --git a/packages/react/src/components/slider/Slider.stories.tsx b/packages/react/src/components/slider/Slider.stories.tsx
new file mode 100644
index 000000000..f60868582
--- /dev/null
+++ b/packages/react/src/components/slider/Slider.stories.tsx
@@ -0,0 +1,31 @@
+import { Story } from '@storybook/react';
+import * as React from 'react';
+import { Slider, SliderProps } from '.';
+
+export default {
+ title: 'Core/Components/Slider',
+ component: Slider,
+ argTypes: {
+ min: {
+ control: 'number',
+ },
+ max: {
+ control: 'number',
+ },
+ stepSize: {
+ control: 'number',
+ },
+ },
+};
+
+export const Example: Story = ({ values, min, max, stepSize }) => {
+ const [sliderValues, setSliderValues] = React.useState(values);
+
+ return ;
+};
+Example.args = {
+ values: [10],
+ min: 0,
+ max: 100,
+ stepSize: 5,
+};
diff --git a/packages/react/src/components/slider/Slider.tsx b/packages/react/src/components/slider/Slider.tsx
new file mode 100644
index 000000000..b3da8381b
--- /dev/null
+++ b/packages/react/src/components/slider/Slider.tsx
@@ -0,0 +1,48 @@
+import VisuallyHidden from '@reach/visually-hidden';
+import * as React from 'react';
+import { RangerOptions, useRanger } from 'react-ranger';
+import { Box, BoxProps } from '../../layout';
+import { useComponentStyles } from '../../system';
+import { UnstyledButton } from '../button';
+
+export interface SliderProps extends RangerOptions, BoxProps {}
+
+const Slider = React.forwardRef(
+ ({ values, onChange, min = 0, max = 100, stepSize = 5, sx, ...rest }, ref) => {
+ const sliderTrackStyles = useComponentStyles('sliderTrack');
+ const sliderHandleStyles = useComponentStyles('sliderHandle');
+ const { getTrackProps, segments, handles } = useRanger({
+ values,
+ onChange,
+ min,
+ max,
+ stepSize,
+ ...rest,
+ });
+
+ return (
+
+ {segments.map(({ getSegmentProps }, i) => {
+ return (
+
+ );
+ })}
+ {handles.map(({ value, getHandleProps }) => (
+
+ {value}
+
+ ))}
+
+ );
+ }
+);
+
+Slider.displayName = 'InputSlider';
+
+export default Slider;
diff --git a/packages/react/src/components/slider/index.ts b/packages/react/src/components/slider/index.ts
new file mode 100644
index 000000000..bd5997ca0
--- /dev/null
+++ b/packages/react/src/components/slider/index.ts
@@ -0,0 +1,2 @@
+export { default as Slider } from './Slider';
+export * from './Slider';
diff --git a/packages/react/src/theme/componentStyles/index.ts b/packages/react/src/theme/componentStyles/index.ts
index 620896082..ba1e2264f 100644
--- a/packages/react/src/theme/componentStyles/index.ts
+++ b/packages/react/src/theme/componentStyles/index.ts
@@ -7,6 +7,7 @@ import form from './form';
import message from './message';
import navigation from './navigation';
import pill from './pill';
+import slider from './slider';
import typography from './typography';
import tabs from './tabs';
import toast from './toast';
@@ -25,6 +26,7 @@ const componentStyles = {
...message,
...navigation,
...pill,
+ ...slider,
...typography,
...tabs,
...toast,
diff --git a/packages/react/src/theme/componentStyles/slider.ts b/packages/react/src/theme/componentStyles/slider.ts
new file mode 100644
index 000000000..9831637fe
--- /dev/null
+++ b/packages/react/src/theme/componentStyles/slider.ts
@@ -0,0 +1,40 @@
+import { transparentize } from 'polished';
+import { DefaultTheme } from 'styled-components';
+import { ComponentThemeConfig } from '../types';
+
+const sliderTrack: ComponentThemeConfig = {
+ baseStyle: ({ theme }: { theme: DefaultTheme }) => ({
+ height: 8,
+ background: theme.colors.blue01,
+ borderRadius: 8,
+ }),
+};
+
+const sliderHandle: ComponentThemeConfig = {
+ baseStyle: ({ theme }: { theme: DefaultTheme }) => ({
+ width: 16,
+ height: 16,
+ borderRadius: 9999,
+ backgroundColor: theme.colors.blue07,
+ outline: '2px solid',
+ outlineColor: theme.colors.greylight01,
+ cursor: 'unset',
+ '&:hover, &:focus, &:active': {
+ outline: '4px solid',
+ outlineColor: transparentize(0.3, theme.colors.blue03),
+ },
+ '&:hover, &:focus': {
+ backgroundColor: theme.colors.blue08,
+ },
+ '&:active': {
+ backgroundColor: theme.colors.blue09,
+ },
+ }),
+};
+
+const slider = {
+ sliderTrack,
+ sliderHandle,
+};
+
+export default slider;
diff --git a/yarn.lock b/yarn.lock
index cd046644a..730aa34d4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4395,6 +4395,13 @@
dependencies:
"@types/react" "*"
+"@types/react-ranger@^2.0.1":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@types/react-ranger/-/react-ranger-2.0.1.tgz#63f1b7d71b7b3e666a1a62a0482470d965b66aa6"
+ integrity sha512-q+vEB4N38b/x3jpqUns05/7QoggT/A3WKVD7X153InQdlhuwYEZ1KxrlNoJLrMpQvB6sDru8+Gq9bGcndU6yMA==
+ dependencies:
+ "@types/react" "*"
+
"@types/react-syntax-highlighter@11.0.5":
version "11.0.5"
resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz#0d546261b4021e1f9d85b50401c0a42acb106087"
@@ -14017,6 +14024,11 @@ react-popper@^2.2.4, react-popper@^2.2.5:
react-fast-compare "^3.0.1"
warning "^4.0.2"
+react-ranger@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/react-ranger/-/react-ranger-2.1.0.tgz#a9007d67a7871736fffc5fe0d7c54a736771e9a1"
+ integrity sha512-d8ezhyX3v/KlN8SkyoE5e8Dybsdmn94eUAqBDsAPrVhZde8sVt6pLJw4fC784KiMmS4LyAjvtjGxhAEqjjGYgw==
+
react-refresh@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"