Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Slider component #871

Merged
merged 40 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8dc6694
feat(slider): init with minimum boilerplate
Dogdriip Jul 11, 2022
5b86445
test(slider/storybook): init minimum story
Dogdriip Jul 11, 2022
ad03ef6
feat(slider): construct basic track, range, thumb
Dogdriip Jul 11, 2022
fc2da38
feat(slider): add disabled control
Dogdriip Jul 11, 2022
82e3ce3
feat(slider): use radix-ui
Dogdriip Jul 11, 2022
be93f0b
feat(slider): add thumb hover, focus style
Dogdriip Jul 11, 2022
91af82c
test(slider/storybook): enhance storybook controls
Dogdriip Jul 11, 2022
47f1cd8
feat(slider): add guide
Dogdriip Jul 11, 2022
0deb2e3
chore(deps): move @radix-ui/react-slider into packages/bezier-react
Dogdriip Sep 15, 2022
c524278
Merge branch 'next-v1' into feat/slider
Dogdriip Sep 15, 2022
0ddcc19
docs(silder.types): add jsdoc for SliderOptions
Dogdriip Sep 15, 2022
df8efde
refactor(slider.styled): export calculation of guide position to func…
Dogdriip Sep 15, 2022
d4719ab
refactor(slider): use primitive's asChild prop
Dogdriip Sep 15, 2022
cab922d
feat(slider): supports multiple thumbs
Dogdriip Sep 15, 2022
6dbf0e6
chore: fix stylelint
Dogdriip Sep 15, 2022
cc85f23
feat(slider): add minStepsBetweenThumbs prop, supports multiple thumbs
Dogdriip Sep 16, 2022
5714c95
test(slider.stories): add MultipleThumbs story
Dogdriip Sep 16, 2022
3c8aab3
chore(slider.stories): remove controlled input story
Dogdriip Sep 16, 2022
bea3d26
fix(slider): resolve forwardedRef type to Ref<HTMLElement>
Dogdriip Sep 16, 2022
b294719
chore: reorder export line of Components/Forms/Inputs/Slider
Dogdriip Sep 16, 2022
d45d4ac
test(jest.setup): add ResizeObserver class mock
Dogdriip Sep 16, 2022
6da9192
test(slider): add initial unit test
Dogdriip Sep 16, 2022
2d75e15
docs(jest.setup): add original source link of ResizeObserver mock
Dogdriip Sep 16, 2022
540debc
test(slider): enhance a11y test
Dogdriip Sep 17, 2022
86a3f2f
test(slider): add width test
Dogdriip Sep 17, 2022
a121eec
feat(slider): add onThumbDragStart, onThumbDragEnd props
Dogdriip Sep 17, 2022
2932cf6
test(slider): add test of onThumbDragStart, onThumbDragEnd
Dogdriip Sep 17, 2022
7caef02
feat(slider): add disabled style via useFormFieldProps
Dogdriip Sep 18, 2022
5509d46
chore(slider): revert useFormFieldProps due to custom aria props
Dogdriip Sep 18, 2022
2f3b5bd
test(slider): add disabled style unit test
Dogdriip Sep 18, 2022
42965df
test(slider): add Disabled story, onValueChange action
Dogdriip Sep 18, 2022
2b85ee5
docs(changesets): add changeset
Dogdriip Sep 18, 2022
6548bc5
Merge branch 'next-v1' into feat/slider
Dogdriip Sep 20, 2022
18dec46
feat(slider): add key prop to guide (@inhibitor1217)
Dogdriip Sep 21, 2022
bb12fb8
fix(slider/on-thumb-drag-*): rename to onThumbPointer(Down|Up), handl…
Dogdriip Oct 19, 2022
6591ad6
test(slider): remove event handler unit test
Dogdriip Oct 19, 2022
24047d2
refactor(slider): move into Forms/ (@sungik-choi)
Dogdriip Nov 3, 2022
691d975
chore: fix typo (@sungik-choi)
Dogdriip Nov 3, 2022
bc7e72e
fix(slider.styled): change focus pseudo-selector to focus-visible (@s…
Dogdriip Nov 3, 2022
89c62cf
refactor(slider): fix export to named export
Dogdriip Nov 7, 2022
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
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@
"path": "./node_modules/cz-conventional-changelog"
}
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"dependencies": {
"@radix-ui/react-slider": "0.1.4"
}
Dogdriip marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* External dependencies */
import React from 'react'
import base from 'paths.macro'
import {
type Meta,
type Story,
} from '@storybook/react'

/* Internal dependencies */
import {
getTitle,
} from 'Utils/storyUtils'
import Slider from './Slider'
import type SliderProps from './Slider.types'

export default {
title: getTitle(base),
component: Slider,
argTypes: {
width: {
control: {
type: 'text',
},
},
disabled: {
control: {
type: 'boolean',
},
},
min: {
control: {
type: 'number',
},
},
max: {
control: {
type: 'number',
},
},
step: {
control: {
type: 'number',
},
},
},
} as Meta

const Template: Story<SliderProps> = (args) => <Slider {...args} />

export const Primary = Template.bind({})
Primary.args = {
width: '36',
defaultValue: [5],
disabled: false,
min: 0,
max: 10,
step: 1,
}

export const Uncontrolled = Template.bind({})
Uncontrolled.args = {
width: '285',
defaultValue: [5],
disabled: false,
min: 0,
max: 10,
step: 1,
}

export const Controlled = Template.bind({})
Controlled.args = {
width: '285',
defaultValue: [5],
value: [5],
disabled: false,
min: 0,
max: 10,
step: 1,
}

export const WithGuide = Template.bind({})
WithGuide.args = {
width: '285',
defaultValue: [5],
guide: [0, 1, 2, 3, 4, 5, 10],
disabled: false,
min: 0,
max: 10,
step: 1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* External dependencies */
import {
Root as RootPrimitive,
Track as TrackPrimitive,
Range as RangePrimitive,
Thumb as ThumbPrimitive,
} from '@radix-ui/react-slider'

/* Internal dependencies */
import { styled } from 'Foundation'
import { toLength } from 'Utils/styleUtils'
import { focusedInputWrapperStyle } from 'Components/Forms/Inputs/mixins'
Copy link
Contributor

Choose a reason for hiding this comment

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

만약 포커스 디자인이 TextField, TextArea, Select 외에도 범용적으로 사용된다면 Forms/ 디렉토리 하위로 이동해야할 거 같네요 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mixins 안에 focusedInputWrapperStyle, erroredInputWrapperStyle 이 두 개는 input 외에도 다른 컴포넌트에 사용할 수 있을 것 같아서, 후속 PR에서 input에 사용되는 믹스인과 그렇지 않은 것을 분리하고 적용해야 할 것 같습니다.

import type SliderProps from './Slider.types'

const SLIDER_TRACK_RANGE_HEIGHT = 6
const SLIDER_THUMB_SIZE = 20

interface SliderRootProps extends SliderProps {
width: NonNullable<SliderProps['width']>
}

export const SliderRoot = styled(RootPrimitive)<SliderRootProps>`
position: relative;
display: flex;
align-items: center;
user-select: none;
touch-action: none;

width: ${({ width }) => toLength(width, '36px')};
height: ${SLIDER_THUMB_SIZE}px;

${({ interpolation }) => interpolation}
`

interface SliderTrackProps extends SliderProps {}

export const SliderTrack = styled(TrackPrimitive)<SliderTrackProps>`
position: relative;
flex: 1;
height: ${SLIDER_TRACK_RANGE_HEIGHT}px;

${({ foundation }) => foundation?.rounding?.round3}
background-color: ${({ foundation }) => foundation?.theme?.['bg-black-dark']};

${({ interpolation }) => interpolation}
`

interface SliderRangeProps extends SliderProps {}

export const SliderRange = styled(RangePrimitive)<SliderRangeProps>`
position: absolute;
height: 100%;

${({ foundation }) => foundation?.rounding?.round3}
background-color: ${({ foundation }) => foundation?.theme?.['bgtxt-green-normal']};

${({ interpolation }) => interpolation}
`

interface SliderGuideProps extends SliderProps {
min: NonNullable<SliderProps['min']>
max: NonNullable<SliderProps['max']>
guideValue: number
}

export const SliderGuide = styled.div<SliderGuideProps>`
position: absolute;
bottom: calc(8px + (8px / 2) + 3px);
// TODO (@aru): FIXME
left: calc(${({ min, max, guideValue }) => (guideValue / (max - min)) * 100}% - 1px + ${({ min, max, guideValue }) => (((((max + min) / 2) - guideValue)) * (SLIDER_THUMB_SIZE / ((max - min))))}px);

width: 2px;
height: 8px;

${({ foundation }) => foundation?.rounding?.round1}
background-color: ${({ foundation }) => foundation?.theme?.['bg-black-light']};

${({ interpolation }) => interpolation}
`

interface SliderThumbProps extends SliderProps {}

export const SliderThumb = styled(ThumbPrimitive)<SliderThumbProps>`
all: unset;
display: block;

width: ${SLIDER_THUMB_SIZE}px;
height: ${SLIDER_THUMB_SIZE}px;

${({ foundation }) => foundation?.rounding?.round12}
${({ foundation }) => foundation?.elevation?.ev2()}
background-color: ${({ foundation }) => foundation?.theme?.['bgtxt-absolute-white-dark']};

&:hover {
${({ foundation }) => foundation?.elevation?.ev3()}
background-color: ${({ foundation }) => foundation?.theme?.['bgtxt-absolute-white-dark']};
}
&:focus {
${focusedInputWrapperStyle}
}
Dogdriip marked this conversation as resolved.
Show resolved Hide resolved

${({ foundation }) => foundation?.transition?.getTransitionsCSS(['box-shadow'])}
${({ interpolation }) => interpolation}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* External dependencies */
import React, { forwardRef } from 'react'

/* Internal dependencies */
import SliderProps from './Slider.types'
import * as Styled from './Slider.styled'

function Slider(
{
width = 36,
guide = [5],
// TODO (@aru): Tooltip
// showTooltip = true,
defaultValue = [5],
value,
disabled = false,
min = 0,
max = 10,
step = 1,
onValueChange,
...rest
}: SliderProps,
forwardedRef: React.Ref<any>, // TODO: resolve any
) {
return (
<Styled.SliderRoot
width={width}
defaultValue={defaultValue}
value={value}
disabled={disabled}
min={min}
max={max}
step={step}
onValueChange={onValueChange}
ref={forwardedRef}
{...rest}
>
<Styled.SliderTrack>
<Styled.SliderRange />
</Styled.SliderTrack>
{ guide?.map((guideValue) => (
<Styled.SliderGuide
min={min}
max={max}
guideValue={guideValue}
/>
)) }
<Styled.SliderThumb />
</Styled.SliderRoot>
)
}

export default forwardRef(Slider)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* External dependencies */
import type { SliderProps as SliderPrimitiveProps } from '@radix-ui/react-slider'

/* Internal dependencies */
import type { BezierComponentProps } from 'Types/ComponentProps'

interface SliderOptions {
// TODO (@aru): add jsdoc
width?: number | string
guide?: number[]
showTooltip?: boolean
}

export default interface SliderProps extends
BezierComponentProps,
SliderPrimitiveProps,
SliderOptions {}
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO: hasError, readOnly prop 지원되면 좋을 것 같습니다. (FormComponentProps)

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* Internal dependencies */
import Slider from './Slider'
import type SliderProps from './Slider.types'

export {
Slider,
type SliderProps,
}
7 changes: 7 additions & 0 deletions packages/bezier-react/src/foundation/Rounding/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const DefaultRoundStyle = css`
`

export enum RoundAbsoluteNumber {
R1 = 1,
R3 = 3,
R4 = 4,
R6 = 6,
Expand All @@ -17,6 +18,11 @@ export enum RoundAbsoluteNumber {
R32 = 32,
}

const round1 = css`
${DefaultRoundStyle};
border-radius: ${RoundAbsoluteNumber.R1}px;
`

const round3 = css`
${DefaultRoundStyle};
border-radius: ${RoundAbsoluteNumber.R3}px;
Expand Down Expand Up @@ -59,6 +65,7 @@ const round32 = css`

export const Rounding = {
DefaultRoundStyle,
round1,
round3,
round4,
round6,
Expand Down
1 change: 1 addition & 0 deletions packages/bezier-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from 'Components/Forms/Inputs/mixins'
export * from 'Components/Forms/Inputs/Select'
export * from 'Components/Forms/Inputs/TextArea'
export * from 'Components/Forms/Inputs/TextField'
export * from 'Components/Forms/Inputs/Slider'
export * from 'Components/Forms/Radio'
export * from 'Components/Forms/SegmentedControl'
export * from 'Components/Forms/Switch'
Expand Down
Loading