feat(components): add RadioButtonGroup

Closes #25
This commit is contained in:
Eric Liu 2019-12-21 17:16:15 -08:00
commit 4f73b8b71a
9 changed files with 128 additions and 11 deletions

View file

@ -44,6 +44,7 @@ Currently, the following components are supported:
- ProgressStep - ProgressStep
- RadioButton - RadioButton
- RadioButtonSkeleton - RadioButtonSkeleton
- RadioButtonGroup
- Search - Search
- SearchSkeleton - SearchSkeleton
- SkeletonPlaceholder - SkeletonPlaceholder

View file

@ -1,14 +1,14 @@
<script> <script>
let className = undefined; let className = undefined;
export { className as class }; export { className as class };
export let props = {}; export let style = undefined;
import { cx } from '../../lib'; import { cx } from '../../lib';
const _class = cx('--radio-button-wrapper', className); const _class = cx('--radio-button-wrapper', className);
</script> </script>
<div {...props} class={_class}> <div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div class={cx('--radio-button', '--skeleton')} /> <div class={cx('--radio-button', '--skeleton')} />
<span class={cx('--radio-button__label', '--skeleton')} /> <span class={cx('--radio-button__label', '--skeleton')} />
</div> </div>

View file

@ -8,11 +8,8 @@
</script> </script>
<Layout> <Layout>
{#if story === 'skeleton'} {#if story === 'skeleton'}
<div>
<RadioButtonSkeleton /> <RadioButtonSkeleton />
</div>
{:else} {:else}
<RadioButton {...$$props} id="radio-1" /> <RadioButton {...$$props} id="radio-1" />
{/if} {/if}

View file

@ -9,26 +9,38 @@
export let hideLabel = false; export let hideLabel = false;
export let labelPosition = 'right'; export let labelPosition = 'right';
export let name = ''; export let name = '';
export let props = {}; export let style = undefined;
import { getContext } from 'svelte';
import { writable } from 'svelte/store';
import { cx } from '../../lib'; import { cx } from '../../lib';
const ctx = getContext('RadioButtonGroup');
const _class = cx( const _class = cx(
'--radio-button-wrapper', '--radio-button-wrapper',
labelPosition !== 'right' && `--radio-button-wrapper--label-${labelPosition}`, labelPosition !== 'right' && `--radio-button-wrapper--label-${labelPosition}`,
className className
); );
const _innerLabelClass = cx(hideLabel && '--visually-hidden'); const _innerLabelClass = cx(hideLabel && '--visually-hidden');
let selected = ctx ? ctx.selected : writable(checked ? value : undefined);
if (ctx) {
ctx.add({ id, checked, disabled, value });
}
$: checked = $selected === value;
</script> </script>
<div class={_class}> <div class={_class} {style}>
<input <input
{...props}
type="radio" type="radio"
class={cx('--radio-button')} class={cx('--radio-button')}
on:change on:change
on:change={event => { on:change={() => {
value = event.target.value; if (ctx) {
ctx.update(value);
}
}} }}
{id} {id}
{name} {name}

View file

@ -0,0 +1,16 @@
<script>
import Layout from '../../internal/ui/Layout.svelte';
import RadioButtonGroup from './RadioButtonGroup.svelte';
import RadioButton from '../RadioButton';
import { FormGroup } from '../Form';
</script>
<Layout>
<FormGroup legendText="Radio Button heading">
<RadioButtonGroup {...$$props.group} defaultSelected="default-selected" legend="Group Legend">
<RadioButton {...$$props.radio} value="standard" id="radio-1" />
<RadioButton {...$$props.radio} value="default-selected" id="radio-2" />
<RadioButton {...$$props.radio} value="disabled" id="radio-3" />
</RadioButtonGroup>
</FormGroup>
</Layout>

View file

@ -0,0 +1,40 @@
import { withKnobs, text, select, boolean } from '@storybook/addon-knobs';
import Component from './RadioButtonGroup.Story.svelte';
export default { title: 'RadioButtonGroup', decorators: [withKnobs] };
const values = {
standard: 'standard',
'default-selected': 'default-selected',
disabled: 'disabled'
};
const orientations = {
'Horizontal (horizontal)': 'horizontal',
'Vertical (vertical)': 'vertical'
};
const labelPositions = {
'Left (left)': 'left',
'Right (right)': 'right'
};
export const Default = () => ({
Component,
props: {
group: {
name: text('The form control name (name in <RadioButtonGroup>)', 'radio-button-group'),
valueSelected: select(
'Value of the selected button (valueSelected in <RadioButtonGroup>)',
values,
'default-selected'
),
orientation: select('Radio button orientation (orientation)', orientations, 'horizontal'),
labelPosition: select('Label position (labelPosition)', labelPositions, 'right')
},
radio: {
disabled: boolean('Disabled (disabled in <RadioButton>)', false),
labelText: text('Label text (labelText in <RadioButton>)', 'Radio button label')
}
}
});

View file

@ -0,0 +1,46 @@
<script>
let className = undefined;
export { className as class };
export let orientation = 'horizontal';
export let labelPosition = 'right';
export let defaultSelected = undefined;
export let disabled = false;
export let style = undefined;
import { createEventDispatcher, setContext } from 'svelte';
import { writable } from 'svelte/store';
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx(
'--radio-button-group',
orientation === 'vertical' && `--radio-button-group--${orientation}`,
labelPosition && `--radio-button-group--label-${labelPosition}`,
className
);
let selected = writable(defaultSelected);
setContext('RadioButtonGroup', {
selected,
add: ({ checked, value }) => {
if (checked) {
selected.set(value);
}
},
update: value => {
selected.set(value);
}
});
$: {
defaultSelected = $selected;
dispatch('change', $selected);
}
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item')} {style}>
<div class={_class} {disabled}>
<slot />
</div>
</div>

View file

@ -0,0 +1,3 @@
import RadioButtonGroup from './RadioButtonGroup.svelte';
export default RadioButtonGroup;

View file

@ -25,6 +25,7 @@ import ProgressIndicator, {
ProgressStep ProgressStep
} from './components/ProgressIndicator'; } from './components/ProgressIndicator';
import RadioButton, { RadioButtonSkeleton } from './components/RadioButton'; import RadioButton, { RadioButtonSkeleton } from './components/RadioButton';
import RadioButtonGroup from './components/RadioButtonGroup';
import Search, { SearchSkeleton } from './components/Search'; import Search, { SearchSkeleton } from './components/Search';
import SkeletonPlaceholder from './components/SkeletonPlaceholder'; import SkeletonPlaceholder from './components/SkeletonPlaceholder';
import SkeletonText from './components/SkeletonText'; import SkeletonText from './components/SkeletonText';
@ -80,6 +81,7 @@ export {
ProgressStep, ProgressStep,
RadioButton, RadioButton,
RadioButtonSkeleton, RadioButtonSkeleton,
RadioButtonGroup,
Search, Search,
SearchSkeleton, SearchSkeleton,
SelectableTile, SelectableTile,