mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 18:31:06 +00:00
chore: lift components folder
This commit is contained in:
parent
76df51674d
commit
2200b29b92
301 changed files with 57 additions and 76 deletions
27
src/Tile/ClickableTile.svelte
Normal file
27
src/Tile/ClickableTile.svelte
Normal file
|
@ -0,0 +1,27 @@
|
|||
<script>
|
||||
export let clicked = false;
|
||||
export let light = false;
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a
|
||||
class:bx--tile={true}
|
||||
class:bx--tile--clickable={true}
|
||||
class:bx--tile--is-clicked={clicked}
|
||||
class:bx--tile--light={light}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:click={() => {
|
||||
clicked = !clicked;
|
||||
}}
|
||||
on:keydown
|
||||
on:keydown={({ key }) => {
|
||||
if (key === ' ' || key === 'Enter') {
|
||||
clicked = !clicked;
|
||||
}
|
||||
}}
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave>
|
||||
<slot />
|
||||
</a>
|
83
src/Tile/ExpandableTile.svelte
Normal file
83
src/Tile/ExpandableTile.svelte
Normal file
|
@ -0,0 +1,83 @@
|
|||
<script>
|
||||
export let expanded = false;
|
||||
export let light = false;
|
||||
export let tileMaxHeight = 0;
|
||||
export let tilePadding = 0;
|
||||
export let tileCollapsedIconText = "Interact to expand Tile";
|
||||
export let tileExpandedIconText = "Interact to collapse Tile";
|
||||
export let tabindex = "0";
|
||||
export let id = "ccs-" + Math.random().toString(36);
|
||||
export let ref = null;
|
||||
|
||||
import { afterUpdate } from "svelte";
|
||||
import ChevronDown16 from "carbon-icons-svelte/lib/ChevronDown16";
|
||||
|
||||
let refContent = null;
|
||||
let refAbove = null;
|
||||
|
||||
afterUpdate(() => {
|
||||
if (tileMaxHeight === 0) {
|
||||
tileMaxHeight = refAbove.getBoundingClientRect().height;
|
||||
}
|
||||
|
||||
const style = getComputedStyle(ref);
|
||||
|
||||
tilePadding =
|
||||
parseInt(style.getPropertyValue("padding-top"), 10) +
|
||||
parseInt(style.getPropertyValue("padding-bottom"), 10);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={ref}
|
||||
{id}
|
||||
{tabindex}
|
||||
class:bx--tile={true}
|
||||
class:bx--tile--expandable={true}
|
||||
class:bx--tile--is-expanded={expanded}
|
||||
class:bx--tile--light={light}
|
||||
{...$$restProps}
|
||||
style={expanded ? $$restProps.style : `${$$restProps.style}; max-height: ${tileMaxHeight + tilePadding}px`}
|
||||
on:click
|
||||
on:click={() => {
|
||||
expanded = !expanded;
|
||||
}}
|
||||
on:keypress
|
||||
on:keypress={e => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
expanded = !expanded;
|
||||
}
|
||||
}}
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave>
|
||||
<div bind:this={refContent}>
|
||||
<div bind:this={refAbove} class:bx--tile-content={true}>
|
||||
<span
|
||||
class:bx--tile-content__above-the-fold={true}
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave>
|
||||
<slot name="above" />
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
aria-expanded={expanded}
|
||||
aria-label={expanded ? tileExpandedIconText : tileCollapsedIconText}
|
||||
class:bx--tile__chevron={true}>
|
||||
<ChevronDown16 />
|
||||
</button>
|
||||
<div class:bx--tile-content={true}>
|
||||
<span
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
class:bx--tile-content__below-the-fold={true}>
|
||||
<slot name="below" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
56
src/Tile/RadioTile.svelte
Normal file
56
src/Tile/RadioTile.svelte
Normal file
|
@ -0,0 +1,56 @@
|
|||
<script>
|
||||
export let checked = false;
|
||||
export let light = false;
|
||||
export let value = "";
|
||||
export let tabindex = "0";
|
||||
export let iconDescription = "Tile checkmark";
|
||||
export let id = "ccs-" + Math.random().toString(36);
|
||||
export let name = "";
|
||||
|
||||
import { getContext } from "svelte";
|
||||
import CheckmarkFilled16 from "carbon-icons-svelte/lib/CheckmarkFilled16";
|
||||
|
||||
const { add, update, selectedValue } = getContext("TileGroup");
|
||||
|
||||
add({ value, checked });
|
||||
|
||||
$: checked = value === $selectedValue;
|
||||
</script>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
{id}
|
||||
{name}
|
||||
{value}
|
||||
{checked}
|
||||
class:bx--tile-input={true}
|
||||
on:change
|
||||
on:change={() => {
|
||||
update(value);
|
||||
}} />
|
||||
<label
|
||||
for={id}
|
||||
{tabindex}
|
||||
class:bx--tile={true}
|
||||
class:bx--tile--selectable={true}
|
||||
class:bx--tile--is-selected={checked}
|
||||
class:bx--tile--light={light}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:keydown
|
||||
on:keydown={e => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
update(value);
|
||||
}
|
||||
}}>
|
||||
<span class:bx--tile__checkmark={true}>
|
||||
<CheckmarkFilled16 aria-label={iconDescription} title={iconDescription} />
|
||||
</span>
|
||||
<span class:bx--tile-content={true}>
|
||||
<slot />
|
||||
</span>
|
||||
</label>
|
58
src/Tile/SelectableTile.svelte
Normal file
58
src/Tile/SelectableTile.svelte
Normal file
|
@ -0,0 +1,58 @@
|
|||
<script>
|
||||
export let selected = false;
|
||||
export let light = false;
|
||||
export let title = "title";
|
||||
export let value = "value";
|
||||
export let tabindex = "0";
|
||||
export let iconDescription = "Tile checkmark";
|
||||
export let id = "ccs-" + Math.random().toString(36);
|
||||
export let name = "";
|
||||
export let ref = null;
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import CheckmarkFilled16 from "carbon-icons-svelte/lib/CheckmarkFilled16";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: dispatch(selected ? "select" : "deselect", id);
|
||||
</script>
|
||||
|
||||
<input
|
||||
bind:this={ref}
|
||||
type="checkbox"
|
||||
tabindex="-1"
|
||||
class:bx--tile-input={true}
|
||||
checked={selected}
|
||||
{id}
|
||||
{value}
|
||||
{name}
|
||||
{title} />
|
||||
<label
|
||||
for={id}
|
||||
{tabindex}
|
||||
class:bx--tile={true}
|
||||
class:bx--tile--selectable={true}
|
||||
class:bx--tile--is-selected={selected}
|
||||
class:bx--tile--light={light}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:click|preventDefault={() => {
|
||||
selected = !selected;
|
||||
}}
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:keydown
|
||||
on:keydown={e => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
selected = !selected;
|
||||
}
|
||||
}}>
|
||||
<span class:bx--tile__checkmark={true}>
|
||||
<CheckmarkFilled16 aria-label={iconDescription} title={iconDescription} />
|
||||
</span>
|
||||
<span class:bx--tile-content={true}>
|
||||
<slot />
|
||||
</span>
|
||||
</label>
|
64
src/Tile/Tile.Story.svelte
Normal file
64
src/Tile/Tile.Story.svelte
Normal file
|
@ -0,0 +1,64 @@
|
|||
<script>
|
||||
export let story = undefined;
|
||||
|
||||
import ClickableTile from "./ClickableTile.svelte";
|
||||
import ExpandableTile from "./ExpandableTile.svelte";
|
||||
import RadioTile from "./RadioTile.svelte";
|
||||
import SelectableTile from "./SelectableTile.svelte";
|
||||
import Tile from "./Tile.svelte";
|
||||
import TileGroup from "./TileGroup.svelte";
|
||||
|
||||
const radioTiles = [
|
||||
{ value: "standard", id: "tile-1", labelText: "Selectable Tile" },
|
||||
{ value: "default-selected", id: "tile-2", labelText: "Selectable Tile" },
|
||||
{ value: "selected", id: "tile-3", labelText: "Selectable Tile" }
|
||||
];
|
||||
|
||||
$: selected = radioTiles[1].value;
|
||||
$: selectedTile1 = false;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if story === 'filter'}
|
||||
<Tile {...$$props} />
|
||||
{:else if story === 'clickable'}
|
||||
<ClickableTile {...$$props}>Clickable Tile</ClickableTile>
|
||||
{:else if story === 'multi-select'}
|
||||
<div role="group" aria-label="selectable tiles">
|
||||
<SelectableTile
|
||||
{...$$props}
|
||||
id="tile-1"
|
||||
name="tiles"
|
||||
bind:selected={selectedTile1}
|
||||
on:select={({ detail }) => {
|
||||
console.log('on:select', detail);
|
||||
}}
|
||||
on:deselect={({ detail }) => {
|
||||
console.log('on:deselect', detail);
|
||||
}}>
|
||||
Multi-select Tile
|
||||
</SelectableTile>
|
||||
<SelectableTile {...$$props} id="tile-2" name="tiles">
|
||||
Multi-select Tile
|
||||
</SelectableTile>
|
||||
<SelectableTile {...$$props} id="tile-3" name="tiles">
|
||||
Multi-select Tile
|
||||
</SelectableTile>
|
||||
</div>
|
||||
{:else if story === 'selectable'}
|
||||
<TileGroup legend="Selectable Tile Group" bind:selected>
|
||||
{#each radioTiles as { value, id, labelText }, i (id)}
|
||||
<RadioTile {...$$props} {value} {id} {labelText}>
|
||||
Selectable Tile
|
||||
</RadioTile>
|
||||
{/each}
|
||||
</TileGroup>
|
||||
{:else if story === 'expandable'}
|
||||
<ExpandableTile {...$$props}>
|
||||
<div slot="above" style="height: 200px">Above the fold content here</div>
|
||||
<div slot="below" style="height: 400px">Below the fold content here</div>
|
||||
</ExpandableTile>
|
||||
{:else}
|
||||
<Tile {...$$props}>Default Tile</Tile>
|
||||
{/if}
|
||||
</div>
|
57
src/Tile/Tile.stories.js
Normal file
57
src/Tile/Tile.stories.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { withKnobs, number, boolean, text } from "@storybook/addon-knobs";
|
||||
import Component from "./Tile.Story.svelte";
|
||||
|
||||
export default { title: "Tile", decorators: [withKnobs] };
|
||||
|
||||
export const Default = () => ({
|
||||
Component,
|
||||
props: { light: boolean("Light variant (light)", false) },
|
||||
});
|
||||
|
||||
export const Clickable = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: "clickable",
|
||||
href: text("Href for clickable UI (href)", "javascript:void(0)"),
|
||||
light: boolean("Light variant (light)", false),
|
||||
},
|
||||
});
|
||||
|
||||
export const MultiSelect = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: "multi-select",
|
||||
selected: boolean("Selected (selected)", false),
|
||||
light: boolean("Light variant (light)", false),
|
||||
},
|
||||
});
|
||||
|
||||
MultiSelect.story = { name: "Multi-select" };
|
||||
|
||||
export const Selectable = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: "selectable",
|
||||
name: text("Form item name (name in <RadioTile>)", "tiles"),
|
||||
light: boolean("Light variant (light)", false),
|
||||
},
|
||||
});
|
||||
|
||||
export const Expandable = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: "expandable",
|
||||
tabindex: text("Tab index (tabindex)", "0"),
|
||||
expanded: boolean("Expanded (expanded)", false),
|
||||
tileMaxHeight: number("Max height (tileMaxHeight)", 0),
|
||||
tileCollapsedIconText: text(
|
||||
"Collapsed icon text (tileCollapsedIconText)",
|
||||
"Interact to Expand tile"
|
||||
),
|
||||
tileExpandedIconText: text(
|
||||
"Collapsed icon text (tileExpandedIconText)",
|
||||
"Interact to Collapse tile"
|
||||
),
|
||||
light: boolean("Light variant (light)", false),
|
||||
},
|
||||
});
|
14
src/Tile/Tile.svelte
Normal file
14
src/Tile/Tile.svelte
Normal file
|
@ -0,0 +1,14 @@
|
|||
<script>
|
||||
export let light = false;
|
||||
</script>
|
||||
|
||||
<div
|
||||
class:bx--tile={true}
|
||||
class:bx--tile--light={light}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave>
|
||||
<slot />
|
||||
</div>
|
35
src/Tile/TileGroup.svelte
Normal file
35
src/Tile/TileGroup.svelte
Normal file
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export let selected = undefined;
|
||||
export let disabled = false;
|
||||
export let legend = "";
|
||||
|
||||
import { createEventDispatcher, setContext } from "svelte";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const selectedValue = writable(selected);
|
||||
|
||||
setContext("TileGroup", {
|
||||
selectedValue,
|
||||
add: ({ checked, value }) => {
|
||||
if (checked) {
|
||||
selectedValue.set(value);
|
||||
}
|
||||
},
|
||||
update: value => {
|
||||
selectedValue.set(value);
|
||||
}
|
||||
});
|
||||
|
||||
$: selected = $selectedValue;
|
||||
$: dispatch("select", $selectedValue);
|
||||
</script>
|
||||
|
||||
<fieldset {disabled} class:bx--tile-group={true} {...$$restProps}>
|
||||
{#if legend}
|
||||
<legend class:bx--label={true}>{legend}</legend>
|
||||
{/if}
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
</fieldset>
|
6
src/Tile/index.js
Normal file
6
src/Tile/index.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
export { default as Tile } from "./Tile.svelte";
|
||||
export { default as ClickableTile } from "./ClickableTile.svelte";
|
||||
export { default as ExpandableTile } from "./ExpandableTile.svelte";
|
||||
export { default as SelectableTile } from "./SelectableTile.svelte";
|
||||
export { default as RadioTile } from "./RadioTile.svelte";
|
||||
export { default as TileGroup } from "./TileGroup.svelte";
|
Loading…
Add table
Add a link
Reference in a new issue