feat(tile): complete RadioTile

Closes #34

- Add Tile to list of supported components
- Make RadioTile composable as a "child" component
This commit is contained in:
Eric Liu 2019-12-20 09:09:55 -08:00
commit 71ddcfccc0
4 changed files with 64 additions and 30 deletions

View file

@ -1,5 +1,4 @@
<script>
// TODO: compose as "children" components
let className = undefined;
export { className as class };
export let checked = false;
@ -11,25 +10,15 @@
export let light = false;
export let style = undefined;
import { createEventDispatcher } from 'svelte';
import { getContext } from 'svelte';
import CheckmarkFilled16 from 'carbon-icons-svelte/lib/CheckmarkFilled16';
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const { addTile, updateSelected, selected } = getContext('TileGroup');
function handleChange(event) {
dispatch('change', event);
}
function handleKeyDown(event) {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
handleChange(event);
}
dispatch('keydown', event);
}
addTile({ id, value, checked });
$: checked = value === $selected.value;
$: _class = cx(
'--tile',
'--tile--selectable',
@ -43,7 +32,9 @@
type="radio"
class={cx('--tile-input')}
on:change
on:change={handleChange}
on:change={() => {
updateSelected({ id, value });
}}
{id}
{name}
{value}
@ -56,7 +47,12 @@
on:mouseenter
on:mouseleave
on:keydown
on:keydown={handleKeyDown}
on:keydown={event => {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
updateSelected({ id, value });
}
}}
{tabindex}
{style}>
<span class={cx('--tile__checkmark')}>

View file

@ -17,7 +17,7 @@
{ value: 'selected', id: 'tile-3', labelText: 'Selectable Tile' }
];
let selected = radioTiles[1].value;
let defaultSelected = radioTiles[1];
</script>
<Layout>
@ -33,19 +33,9 @@
<SelectableTile {...$$props} id="tile-3" name="tiles">Multi-select Tile</SelectableTile>
</div>
{:else if story === 'selectable'}
<TileGroup legend="Selectable Tile Group">
<TileGroup legend="Selectable Tile Group" bind:defaultSelected>
{#each radioTiles as { value, id, labelText }, i (id)}
<RadioTile
{...$$props}
checked={selected === value}
on:change={() => {
selected = value;
}}
{value}
{id}
{labelText}>
Selectable Tile
</RadioTile>
<RadioTile {...$$props} {value} {id} {labelText}>Selectable Tile</RadioTile>
{/each}
</TileGroup>
{:else if story === 'expandable'}

View file

@ -1,12 +1,50 @@
<script>
let className = undefined;
export { className as class };
export let defaultSelected = { value: undefined };
export let disabled = false;
export let legend = '';
export let style = undefined;
import { createEventDispatcher, setContext } from 'svelte';
import { writable } from 'svelte/store';
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
let tiles = [];
let selected = writable(defaultSelected);
setContext('TileGroup', {
selected,
addTile: tile => {
tiles = [...tiles, tile];
},
updateSelected: tile => {
selected.set(tile);
}
});
$: {
const checkedTiles = tiles.filter(tile => tile.checked);
if (checkedTiles.length > 1) {
console.warn('Multiple RadioTiles cannot be checked.');
if (defaultSelected.value) {
console.warn('Using `defaultSelected`:', defaultSelected);
} else {
console.warn('Using `RadioTile`:', checkedTiles[0]);
selected.set(checkedTiles[0]);
}
} else if (checkedTiles.length === 1) {
selected.set(checkedTiles[0]);
tiles = [];
}
defaultSelected = $selected;
dispatch('select', $selected);
}
const _class = cx('--tile-group', className);
</script>