Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(slider): v1 #1559

Merged
merged 16 commits into from
Jul 12, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Features
- Split action handlers with "OR" condition in accessibility behaviors @sophieH29 ([#1622](https://github.com/stardust-ui/react/pull/1622))
- Add `headerAction` slot to the `Dialog` component @mnajdova ([#1617](https://github.com/stardust-ui/react/pull/1617))
- Add `Slider` component @Bugaa92 ([#1559](https://github.com/stardust-ui/react/pull/1559))

<!--------------------------------[ v0.34.1 ]------------------------------- -->
## [v0.34.1](https://github.com/stardust-ui/react/tree/v0.34.1) (2019-07-11)
Expand Down
29 changes: 29 additions & 0 deletions docs/src/examples/components/Slider/Playground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'
import { useBooleanKnob, useStringKnob } from '@stardust-ui/docs-components'

const SliderPlayground: React.FunctionComponent = () => {
const [min] = useStringKnob({ name: 'min', initialValue: '0' })
const [max] = useStringKnob({ name: 'max', initialValue: '50' })
const [step] = useStringKnob({ name: 'step', initialValue: '1' })
const [value, setValue] = useStringKnob({ name: 'value', initialValue: '10' })

const [disabled] = useBooleanKnob({ name: 'disabled' })
const [fluid] = useBooleanKnob({ name: 'fluid' })
const [vertical] = useBooleanKnob({ name: 'vertical' })

return (
<Slider
disabled={disabled}
fluid={fluid}
min={min}
max={max}
step={step}
value={value}
vertical={vertical}
onChange={(e, data) => setValue(data.value)}
/>
)
}

export default SliderPlayground
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import getScreenerSteps from '../commonScreenerSteps'

const config: ScreenerTestsConfig = {
themes: ['teams', 'teamsDark', 'teamsHighContrast'],
steps: getScreenerSteps(),
}

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'

const SliderExampleRtl = () => <Slider />

export default SliderExampleRtl
12 changes: 12 additions & 0 deletions docs/src/examples/components/Slider/Rtl/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import NonPublicSection from 'docs/src/components/ComponentDoc/NonPublicSection'

const Rtl = () => (
<NonPublicSection title="Rtl">
<ComponentExample examplePath="components/Slider/Rtl/SliderExample.rtl" />
</NonPublicSection>
)

export default Rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'

const SliderExampleDisabledShorthand = () => <Slider disabled />

export default SliderExampleDisabledShorthand
15 changes: 15 additions & 0 deletions docs/src/examples/components/Slider/States/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const States = () => (
<ExampleSection title="States">
<ComponentExample
title="Disabled"
description="A slider can be read-only and unable to change states."
examplePath="components/Slider/States/SliderExampleDisabled"
/>
</ExampleSection>
)

export default States
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import getScreenerSteps from '../commonScreenerSteps'

const config: ScreenerTestsConfig = {
bmdalex marked this conversation as resolved.
Show resolved Hide resolved
themes: ['teams', 'teamsDark', 'teamsHighContrast'],
steps: getScreenerSteps(),
}

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'

const SliderExampleShorthand = () => <Slider />

export default SliderExampleShorthand
16 changes: 16 additions & 0 deletions docs/src/examples/components/Slider/Types/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Types = () => (
<ExampleSection title="Types">
<ComponentExample
title="Default"
description="A default slider."
examplePath="components/Slider/Types/SliderExample"
/>
</ExampleSection>
)

export default Types
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react'
import { Button, Input, Slider, Flex } from '@stardust-ui/react'
import { useBooleanKnob } from '@stardust-ui/docs-components'

interface SliderAction {
type: 'toggle_mute' | 'change_value'
value?: string | number
}

interface SliderState {
mute: boolean
value: string | number
currentValue: string | number
minValue: string | number
}

const stateReducer = (state: SliderState, action: SliderAction) => {
switch (action.type) {
case 'toggle_mute':
const mute = !state.mute
const value = mute ? state.minValue : state.currentValue

if (!mute && value <= state.minValue) return { ...state }
return { ...state, mute, value, currentValue: state.value }

case 'change_value':
return { ...state, mute: action.value <= state.minValue, value: action.value }

default:
throw new Error(`Action ${action.type} is not supported`)
}
}

const SliderExampleActionShorthand = () => {
const [vertical] = useBooleanKnob({ name: 'vertical', initialValue: false })
const { min, max } = { min: 0, max: 100 }

const [state, dispatch] = React.useReducer(stateReducer, {
mute: false,
value: min + (max - min) / 2,
currentValue: min,
minValue: min,
})

const handeChange = React.useCallback(
(e, data) => dispatch({ type: 'change_value', value: data.value }),
[],
)

const commonProps = { vertical, min, max, value: state.value, onChange: handeChange }

return (
<Flex inline hAlign="center" vAlign="center" gap="gap.smaller" column={vertical}>
<Button
text
iconOnly
icon={state.mute ? 'mic-off' : 'mic'}
onClick={() => dispatch({ type: 'toggle_mute' })}
/>
<Slider {...commonProps} />
<Input type="number" input={{ styles: { width: '64px' } }} {...commonProps} />
</Flex>
)
}

export default SliderExampleActionShorthand
32 changes: 32 additions & 0 deletions docs/src/examples/components/Slider/Usage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Usage = () => (
<ExampleSection title="Usage">
<ComponentExample
title="Slider with action element and input"
description={
<div>
<span>This example contains:</span>
<ul>
<li>
a <code>Slider</code> that allows the user to choose a value from within a specific
range of values.
</li>
<li>
a <code>Button</code> that changes its icon and toggles the <code>Slider</code> value
when clicked (between current value and minimum value).
</li>
<li>
an <code>Input</code> that changes and displays the current <code>Slider</code> value.
</li>
</ul>
</div>
}
examplePath="components/Slider/Usage/SliderExampleAction"
/>
</ExampleSection>
)

export default Usage
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'

const SliderExampleFluidShorthand = () => <Slider fluid />

export default SliderExampleFluidShorthand
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'
import { Slider } from '@stardust-ui/react'

const SliderExampleVerticalShorthand = () => <Slider vertical />

export default SliderExampleVerticalShorthand
21 changes: 21 additions & 0 deletions docs/src/examples/components/Slider/Variations/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Variations = () => (
<ExampleSection title="Variations">
<ComponentExample
title="Vertical"
description="A slider can be displayed vertically."
examplePath="components/Slider/Variations/SliderExampleVertical"
/>
<ComponentExample
title="Fluid"
description="A slider can take up the width of its container."
examplePath="components/Slider/Variations/SliderExampleFluid"
/>
</ExampleSection>
)

export default Variations
29 changes: 29 additions & 0 deletions docs/src/examples/components/Slider/commonScreenerSteps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Slider } from '@stardust-ui/react/src'

const selectors = {
input: `.${Slider.slotClassNames.input}`,
}

const focusSliderStep: ScreenerStep = (builder, keys) => builder.keys('body', keys.tab)

const getScreenerSteps = (): ScreenerSteps => [
(builder, keys) => focusSliderStep(builder, keys).snapshot('Focuses the slider'),
(builder, keys) =>
focusSliderStep(builder, keys)
.keys(selectors.input, keys.rightArrow)
.keys(selectors.input, keys.rightArrow)
.keys(selectors.input, keys.rightArrow)
.keys(selectors.input, keys.rightArrow)
.keys(selectors.input, keys.rightArrow)
.snapshot('Navigates to the right with the right arrow key'),
(builder, keys) =>
focusSliderStep(builder, keys)
.keys(selectors.input, keys.upArrow)
.keys(selectors.input, keys.upArrow)
.keys(selectors.input, keys.upArrow)
.keys(selectors.input, keys.upArrow)
.keys(selectors.input, keys.upArrow)
.snapshot('Navigates to the right with the up arrow key'),
]

export default getScreenerSteps
19 changes: 19 additions & 0 deletions docs/src/examples/components/Slider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react'

import Types from './Types'
import States from './States'
import Variations from './Variations'
import Usage from './Usage'
import Rtl from './Rtl'

const SliderExamples = () => (
<>
<Types />
<States />
<Variations />
<Usage />
<Rtl />
</>
)

export default SliderExamples
9 changes: 5 additions & 4 deletions packages/react/src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Icon from '../Icon/Icon'
import Text from '../Text/Text'
import { Accessibility } from '../../lib/accessibility/types'
import { checkboxBehavior } from '../../lib/accessibility'
import { SupportedIntrinsicInputProps } from '../../lib/htmlPropsUtils'

export interface CheckboxProps extends UIComponentProps, ChildrenComponentProps {
/**
Expand All @@ -26,13 +27,13 @@ export interface CheckboxProps extends UIComponentProps, ChildrenComponentProps
accessibility?: Accessibility

/** Initial checked value. */
defaultChecked?: boolean
defaultChecked?: SupportedIntrinsicInputProps['defaultChecked']

/** Whether or not item is checked. */
checked?: boolean
checked?: SupportedIntrinsicInputProps['checked']

/** An item can appear disabled and be unable to change states. */
disabled?: boolean
disabled?: SupportedIntrinsicInputProps['disabled']

/** The item indicator can be user-defined icon. */
icon?: ShorthandValue
Expand Down Expand Up @@ -62,7 +63,7 @@ export interface CheckboxProps extends UIComponentProps, ChildrenComponentProps
}

export interface CheckboxState {
checked: boolean
checked: CheckboxProps['checked']
isFromKeyboard: boolean
}

Expand Down
Loading