Merge pull request #218 from IBM/docs

Support skeleton prop in more components, fix timeout in SSR, develop docs
This commit is contained in:
Eric Liu 2020-07-24 21:30:25 -07:00 committed by GitHub
commit a194e8b7b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1654 additions and 196 deletions

2
docs/.gitignore vendored
View file

@ -4,4 +4,6 @@
/src/node_modules/@sapper/
yarn-error.log
/cypress/screenshots/
/cypress/fixtures/
/__sapper__/
static/style.css

View file

@ -29,6 +29,14 @@ yarn link "carbon-components-svelte"
yarn install
```
Before starting development, you will need to build the Carbon-themed CSS StyleSheet once.
```sh
node scripts/carbon-theme
```
A file containing the four Carbon themes will be outputted to `static/style.css`. Do not check this file into source control.
## Available Scripts
### `yarn dev`

View file

@ -1,5 +1,5 @@
{
"baseUrl": "http://localhost:3000",
"video": false,
"defaultCommandTimeout": 1000
"defaultCommandTimeout": 20
}

View file

@ -3,9 +3,22 @@ describe("Button", () => {
cy.examples("Button");
});
it("renders correctly", () => {
cy.get("button").then(($) => {
expect($.length).to.eql(4);
});
it("clicks", () => {
cy.get(".bx--btn--primary")
.first()
.as("btn")
.contains("Primary button");
cy.get("@btn").trigger("click");
cy.get("@log").should("be.calledWith", "click");
cy.get("@btn").trigger("mouseover");
cy.get("@log").should("be.calledWith", "mouseover");
cy.get("@btn").trigger("mouseenter");
cy.get("@log").should("be.calledWith", "mouseenter");
cy.get("@btn").trigger("mouseleave");
cy.get("@log").should("be.calledWith", "mouseleave");
});
});

View file

@ -1,3 +1,7 @@
Cypress.Commands.add("examples", (component) => {
cy.visit(`/examples/${component}`);
cy.visit(`/examples/${component}`, {
onBeforeLoad(win) {
cy.stub(win.console, "log").as("log");
},
});
});

View file

@ -13,9 +13,14 @@
"sirv": "^1.0.1"
},
"devDependencies": {
"autoprefixer": "^9.8.5",
"carbon-components": "^10.16.0",
"carbon-components-svelte": "../",
"clipboard-copy": "^3.1.0",
"cypress": "^4.10.0",
"node-sass": "^4.14.1",
"npm-run-all": "^4.1.5",
"postcss": "^7.0.32",
"sapper": "^0.27.16",
"shx": "^0.3.2",
"svelte": "^3.24.0",

View file

@ -0,0 +1,55 @@
const fs = require("fs");
const sass = require("node-sass");
const autoprefixer = require("autoprefixer");
const postcss = require("postcss");
const { promisify } = require("util");
const writeFile = promisify(fs.writeFile);
const outFile = "./static/style.css";
async function generateCss() {
sass.render(
{
outFile,
omitSourceMapUrl: true,
data: `
$feature-flags: (
enable-css-custom-properties: true,
grid-columns-16: true,
);
@import "node_modules/carbon-components/scss/globals/scss/_css--helpers.scss";
@import "node_modules/carbon-components/scss/globals/scss/vendor/@carbon/elements/scss/themes/_mixins.scss";
:root[carbon-theme="white"] { @include carbon--theme($carbon--theme--white, true); }
:root { @include carbon--theme($carbon--theme--g10, true); }
:root[carbon-theme="g90"] { @include carbon--theme($carbon--theme--g90, true); }
:root[carbon-theme="g100"] { @include carbon--theme($carbon--theme--g100, true); }
$css--font-face: true;
$css--helpers: true;
$css--body: true;
$css--use-layer: true;
$css--reset: true;
$css--default-type: true;
$css--plex: true;
@import "node_modules/carbon-components/scss/globals/scss/_css--reset.scss";
@import "node_modules/carbon-components/scss/globals/scss/_css--font-face.scss";
@import "node_modules/carbon-components/scss/globals/scss/_css--helpers.scss";
@import "node_modules/carbon-components/scss/globals/scss/_css--body.scss";
@import "node_modules/carbon-components/scss/globals/grid/_grid.scss";
@import "node_modules/carbon-components/scss/globals/scss/styles.scss";`,
},
async (error, result) => {
if (!error) {
const prefixed = await postcss([autoprefixer]).process(result.css, {
from: undefined,
});
await writeFile(outFile, prefixed.css);
}
}
);
}
generateCss();

View file

@ -0,0 +1,13 @@
<script>
export let code = "";
import copy from "clipboard-copy";
import { CodeSnippet } from "carbon-components-svelte";
</script>
<CodeSnippet
{...$$restProps}
{code}
on:click={() => {
copy(code);
}} />

View file

@ -7,8 +7,9 @@
HeaderNav,
HeaderNavItem,
HeaderUtilities,
HeaderActionLink
HeaderActionLink,
} from "carbon-components-svelte";
import Theme from "./Theme.svelte";
</script>
<Header
@ -18,7 +19,7 @@
rel="prefetch"
aria-current={segment === undefined ? 'page' : undefined}>
<SkipToContent />
<HeaderNav>
<!-- <HeaderNav>
<HeaderNavItem
rel="prefetch"
href="about"
@ -29,5 +30,5 @@
href="components"
text="Components"
aria-current={segment === 'components' ? 'page' : undefined} />
</HeaderNav>
</HeaderNav> -->
</Header>

View file

@ -0,0 +1,228 @@
<script>
import * as Carbon from "carbon-components-svelte";
import Add16 from "carbon-icons-svelte/lib/Add16";
let skeleton = false;
let accordionItemOpen = false;
</script>
<style>
:global(.tile-card) {
display: flex;
flex-direction: column;
height: 100%;
min-height: 12rem;
}
.title {
font-size: 0.75rem;
}
.tile-card__preview {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem 0;
}
.tile-card__actions {
display: none;
}
:global(.component-grid) {
margin-top: 1.5rem;
}
:global(.component-grid .scope:first-of-type) {
border-top: 1px solid var(--cds-ui-03);
}
:global(.scope) {
border-left: 1px solid var(--cds-ui-03);
}
:global(.scope > .bx--col) {
border-bottom: 1px solid var(--cds-ui-03);
border-right: 1px solid var(--cds-ui-03);
}
</style>
<Carbon.Row>
<Carbon.Column>
<Carbon.ToggleSmall bind:toggled={skeleton} labelText="Skeleton state" />
</Carbon.Column>
</Carbon.Row>
<div class="component-grid">
<Carbon.Row class="scope">
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Accordion</div>
<div class="tile-card__preview">
<Carbon.Accordion count={3} {skeleton} open={accordionItemOpen}>
<Carbon.AccordionItem title="Title 1" bind:open={accordionItemOpen}>
Content 1
</Carbon.AccordionItem>
<Carbon.AccordionItem title="Title 2">
Content 2
</Carbon.AccordionItem>
<Carbon.AccordionItem title="Title 3">
Content 3
</Carbon.AccordionItem>
</Carbon.Accordion>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Breadcrumb</div>
<div class="tile-card__preview">
<Carbon.Breadcrumb {skeleton}>
<Carbon.BreadcrumbItem href="/">Breadcrumb 1</Carbon.BreadcrumbItem>
<Carbon.BreadcrumbItem href="/">Breadcrumb 2</Carbon.BreadcrumbItem>
<Carbon.BreadcrumbItem href="/">Breadcrumb 3</Carbon.BreadcrumbItem>
</Carbon.Breadcrumb>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
</Carbon.Row>
<Carbon.Row class="scope">
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Primary button</div>
<div class="tile-card__preview">
<Carbon.Button {skeleton}>Primary</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Secondary button</div>
<div class="tile-card__preview">
<Carbon.Button kind="secondary" {skeleton}>Secondary</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Tertiary button</div>
<div class="tile-card__preview">
<Carbon.Button kind="tertiary" {skeleton}>Tertiary</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Ghost button</div>
<div class="tile-card__preview">
<Carbon.Button kind="ghost" {skeleton}>Ghost</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Danger button</div>
<div class="tile-card__preview">
<Carbon.Button kind="danger" {skeleton}>Danger</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
</Carbon.Row>
<Carbon.Row class="scope">
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Primary button with icon</div>
<div class="tile-card__preview">
<Carbon.Button icon={Add16} {skeleton}>With icon</Carbon.Button>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Icon-only buttons</div>
<div class="tile-card__preview">
<Carbon.Button
icon={Add16}
hasIconOnly
iconDescription="Primary"
tooltipPosition="bottom"
tooltipAlignment="center"
{skeleton} />
<Carbon.Button
icon={Add16}
hasIconOnly
kind="secondary"
iconDescription="Secondary"
tooltipPosition="bottom"
tooltipAlignment="center"
{skeleton} />
<Carbon.Button
icon={Add16}
hasIconOnly
kind="tertiary"
iconDescription="Tertiary"
tooltipPosition="bottom"
tooltipAlignment="center"
{skeleton} />
<Carbon.Button
icon={Add16}
hasIconOnly
kind="ghost"
iconDescription="Ghost"
tooltipPosition="bottom"
tooltipAlignment="center"
{skeleton} />
<Carbon.Button
icon={Add16}
hasIconOnly
kind="danger"
iconDescription="Danger"
tooltipPosition="bottom"
tooltipAlignment="center"
{skeleton} />
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
</Carbon.Row>
<Carbon.Row class="scope">
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Checkbox</div>
<div class="tile-card__preview">
<fieldset class="bx--fieldset">
<legend class="bx--label">Checkbox heading</legend>
<Carbon.Checkbox {skeleton} labelText="Checkbox label" />
<Carbon.Checkbox {skeleton} labelText="Checkbox label" />
<Carbon.Checkbox {skeleton} labelText="Checkbox label" />
</fieldset>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
<Carbon.Column noGutter>
<Carbon.Tile class="tile-card">
<div class="title">Code Snippet</div>
<div class="tile-card__preview">
<Carbon.CodeSnippet type="single" light {skeleton}>
{`body { margin: 0; padding: 0; }`}
</Carbon.CodeSnippet>
</div>
<div class="tile-card__actions">Actions</div>
</Carbon.Tile>
</Carbon.Column>
</Carbon.Row>
</div>

View file

@ -0,0 +1,29 @@
<script>
import { onMount } from "svelte";
import { Select, SelectItem } from "carbon-components-svelte";
let theme = undefined;
onMount(() => {
theme = localStorage.getItem("theme") || "g10";
});
$: if (theme) {
localStorage.setItem("theme", theme);
document.documentElement.setAttribute("carbon-theme", theme);
}
</script>
<style>
:global(.bx--select-input) {
width: auto;
min-width: 0;
}
</style>
<Select inline labelText="Theme" bind:selected={theme}>
<SelectItem value="white" text="White" />
<SelectItem value="g10" text="Gray 10" />
<SelectItem value="g90" text="Gray 90" />
<SelectItem value="g100" text="Gray 100" />
</Select>

View file

@ -1,14 +1,111 @@
<script>
export let segment = undefined;
import { Content } from "carbon-components-svelte";
import {
Grid,
Row,
Column,
Breadcrumb,
BreadcrumbItem,
Content,
SideNav,
SideNavItems,
SideNavMenu,
SideNavMenuItem,
SideNavLink,
} from "carbon-components-svelte";
import GlobalHeader from "../components/GlobalHeader.svelte";
import Theme from "../components/Theme.svelte";
import { afterUpdate, setContext } from "svelte";
import { writable } from "svelte/store";
const tail = writable(undefined);
let prevSegment = undefined;
const urlIds = {
about: "About",
components: "Components",
"getting-started": "Getting Started",
};
setContext("navigation", {
tail,
setTail: (value) => {
tail.set(value);
},
});
afterUpdate(() => {
if (prevSegment !== segment) {
if (prevSegment !== undefined) {
tail.set(undefined);
}
prevSegment = segment;
}
});
</script>
<style>
:global(.bx--row h1) {
margin-bottom: 2.5rem;
}
:global(.bx--row p) {
margin-bottom: 1.5rem;
}
</style>
{#if segment !== 'examples'}
<GlobalHeader {segment} />
<SideNav isOpen={true}>
<SideNavItems>
<SideNavLink
text="Getting Started"
href="getting-started"
rel="prefetch"
isSelected={segment === 'getting-started'} />
<SideNavMenu
text="Components"
expanded={segment === 'components'}
isSelected={segment === 'components' && !$tail}>
<SideNavMenuItem
text="Index"
href="components"
rel="prefetch"
isSelected={segment === 'components' && $tail && $tail.slug === 'index'} />
<SideNavMenuItem
text="Button"
href="components/button"
rel="prefetch"
isSelected={segment === 'components' && $tail && $tail.slug === 'button'} />
</SideNavMenu>
</SideNavItems>
</SideNav>
<Content>
<slot />
<Grid>
<Row>
<Column
style="display: flex; align-items: center; justify-content:
space-between;">
<Breadcrumb>
<BreadcrumbItem href="." isCurrentPage={!$tail && !segment}>
Home
</BreadcrumbItem>
{#if segment && $tail}
<BreadcrumbItem href={segment} isCurrentPage={!$tail}>
{urlIds[segment]}
</BreadcrumbItem>
{/if}
</Breadcrumb>
<div>
<Theme />
</div>
</Column>
</Row>
<slot />
</Grid>
</Content>
{:else}
<slot />

View file

@ -1,6 +0,0 @@
<h1>About</h1>
<p>
<code>carbon-components-svelte</code>
is the Svelte implementation of the Carbon Design System
</p>

View file

@ -2,8 +2,8 @@ import components from "./_components.js";
const componentsMap = new Map();
components.forEach((post) => {
componentsMap.set(post.slug, JSON.stringify(post));
components.forEach(($) => {
componentsMap.set($.slug, JSON.stringify($));
});
export function get(req, res, next) {

View file

@ -14,25 +14,117 @@
<script>
export let data = {};
import { onMount } from "svelte";
import { onMount, getContext } from "svelte";
import {
Grid,
Row,
Column,
CodeSnippet,
FormGroup,
RadioButtonGroup,
RadioButton,
} from "carbon-components-svelte";
import copy from "clipboard-copy";
const ctx = getContext("navigation");
let component = undefined;
let defaultProps = {};
$: props = data.props || {};
$: {
if (data.props) {
Object.keys(data.props).forEach((prop) => {
if (!(prop in defaultProps)) {
defaultProps = {
...defaultProps,
[prop]: data.props[prop].default,
};
}
});
}
}
onMount(async () => {
ctx.setTail(data);
try {
component = await import(`../examples/${data.title}.svelte`);
} catch (e) {
console.log(e);
console.error(e);
}
return () => {
ctx.setTail(undefined);
};
});
</script>
<style>
.preview {
width: 100%;
min-height: 8rem;
margin-bottom: 2.5rem;
padding: 1rem;
white-space: nowrap;
overflow-x: auto;
background-color: var(--cds-ui-01);
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
}
:global(.preview h4) {
margin-bottom: 0.75rem;
font-size: 1rem;
color: var(--cds-text-02);
}
:global(.preview > div) {
margin-bottom: 2.5rem;
}
</style>
<svelte:head>
<title>{data.title}</title>
</svelte:head>
<h1>{data.title}</h1>
<Row>
<Column>
<h1>{data.title}</h1>
</Column>
</Row>
{#if component}
<svelte:component this={component.default} />
{/if}
<Row noGutter>
<div class="preview">
{#if component}
<svelte:component this={component.default} {...defaultProps} />
{/if}
</div>
</Row>
<Row>
<Column md={3} lg={4}>
{#each Object.keys(props) as key}
{#if Array.isArray(props[key].values)}
<FormGroup legendText={key}>
<RadioButtonGroup
selected={props[key].default}
on:change={({ detail }) => {
defaultProps = { ...defaultProps, [key]: detail };
}}>
{#each props[key].values as value}
<RadioButton {value} id={value} labelText={value} />
{/each}
</RadioButtonGroup>
</FormGroup>
{/if}
{/each}
</Column>
<Column md={5}>
<CodeSnippet
type="multi"
code={data.source}
on:click={() => {
copy(data.source);
}} />
</Column>
</Row>

View file

@ -1,6 +1,19 @@
import fs from "fs";
import path from "path";
const components = [
{
title: "Button",
source: fs.readFileSync(
path.resolve(process.cwd(), "./src/routes/examples/Button.svelte"),
"utf8"
),
props: {
size: {
values: ["default", "field", "small"],
default: "default",
},
},
},
].map((post) => ({
...post,

View file

@ -1,27 +1,55 @@
<script context="module">
export function preload() {
return this.fetch("components.json")
.then(r => r.json())
.then(data => ({ data }));
.then((r) => r.json())
.then((data) => ({ data }));
}
</script>
<script>
export let data = [];
import { UnorderedList, ListItem, Link } from "carbon-components-svelte";
import { getContext, onMount } from "svelte";
import {
Row,
Column,
UnorderedList,
ListItem,
Link,
} from "carbon-components-svelte";
const ctx = getContext("navigation");
let tail = undefined;
const unsubscribe = ctx.tail.subscribe((value) => {
tail = value;
});
onMount(() => {
if (tail) {
ctx.setTail(undefined);
}
return () => {
unsubscribe();
};
});
</script>
<svelte:head>
<title>Components</title>
</svelte:head>
<h1>Components</h1>
<UnorderedList>
{#each data as data, i (data.title)}
<ListItem>
<Link rel="prefetch" href="components/{data.slug}">{data.title}</Link>
</ListItem>
{/each}
</UnorderedList>
<Row>
<Column>
<h1>Components</h1>
<UnorderedList>
{#each data as data, i (data.title)}
<ListItem>
<Link rel="prefetch" href="components/{data.slug}">{data.title}</Link>
</ListItem>
{/each}
</UnorderedList>
</Column>
</Row>

View file

@ -1,8 +1,86 @@
<script>
import { Button } from "carbon-components-svelte";
import Add16 from "carbon-icons-svelte/lib/Add16";
</script>
<Button kind="primary">Primary button</Button>
<Button kind="secondary">Secondary button</Button>
<Button kind="tertiary">Tertiary button</Button>
<Button kind="ghost">Ghost button</Button>
<div>
<h4>Buttons</h4>
<Button
{...$$props}
kind="primary"
on:click={() => console.log('click')}
on:mouseover={() => console.log('mouseover')}
on:mouseenter={() => console.log('mouseenter')}
on:mouseleave={() => console.log('mouseleave')}>
Primary button
</Button>
<Button {...$$props} kind="secondary">Secondary button</Button>
<Button {...$$props} kind="tertiary">Tertiary button</Button>
<Button {...$$props} kind="ghost">Ghost button</Button>
<Button {...$$props} kind="danger">Danger button</Button>
</div>
<div>
<h4>Buttons with Icons</h4>
<Button {...$$props} kind="primary" icon={Add16}>Primary</Button>
<Button {...$$props} kind="secondary" icon={Add16}>Secondary</Button>
<Button {...$$props} kind="tertiary" icon={Add16}>Tertiary</Button>
<Button {...$$props} kind="ghost" icon={Add16}>Ghost</Button>
<Button {...$$props} kind="danger" icon={Add16}>Danger</Button>
</div>
<div>
<h4>Icon-only Buttons</h4>
<Button
{...$$props}
kind="primary"
hasIconOnly
icon={Add16}
iconDescription="Primary"
tooltipPosition="bottom"
tooltipAlignment="center" />
<Button
{...$$props}
kind="secondary"
hasIconOnly
icon={Add16}
iconDescription="Secondary"
tooltipPosition="bottom"
tooltipAlignment="center" />
<Button
{...$$props}
kind="tertiary"
hasIconOnly
icon={Add16}
iconDescription="Tertiary"
tooltipPosition="bottom"
tooltipAlignment="center" />
<Button
{...$$props}
kind="ghost"
hasIconOnly
icon={Add16}
iconDescription="Ghost"
tooltipPosition="bottom"
tooltipAlignment="center" />
<Button
{...$$props}
kind="danger"
hasIconOnly
icon={Add16}
iconDescription="Danger"
tooltipPosition="bottom"
tooltipAlignment="center" />
</div>

View file

@ -1 +0,0 @@
<slot />

View file

@ -0,0 +1,53 @@
<script>
import { Tabs, Tab, TabContent, Row, Column } from "carbon-components-svelte";
import CopyableCodeSnippet from "../../components/CopyableCodeSnippet.svelte";
</script>
<style>
.content {
margin-left: -1rem;
margin-top: -1rem;
}
</style>
<svelte:head>
<title>Getting Started</title>
</svelte:head>
<Row>
<Column>
<h1>Getting Started</h1>
<p>
<CopyableCodeSnippet type="inline" code="carbon-components-svelte" />
can be installed as a development dependency.
</p>
<p>
<Tabs type="container">
<Tab label="Yarn" />
<Tab label="NPM" />
<div slot="content" class="content">
<TabContent>
<CopyableCodeSnippet
code={`yarn add -D carbon-components-svelte`} />
</TabContent>
<TabContent>
<CopyableCodeSnippet code={`npm -i -D carbon-components-svelte`} />
</TabContent>
</div>
</Tabs>
</p>
</Column>
</Row>
<!--
<div style="margin-left: -1rem; margin-right: -1rem;">
<Tabs type="container">
<Tab label="Rapid Prototyping" />
<Tab label="Single-Page Application (SPA)" />
<Tab label="Server-side Rendered (SSR)" />
<div slot="content" class="content">
<TabContent>1</TabContent>
<TabContent>2</TabContent>
<TabContent>3</TabContent>
</div>
</Tabs>
</div>
-->

View file

@ -1,10 +1,13 @@
<script>
import components from "./components/_components";
import { Link } from "carbon-components-svelte";
import Portfolio from "../components/Portfolio.svelte";
</script>
<h1>Welcome</h1>
<style>
h1 {
margin-bottom: 1rem;
}
</style>
{#each components as component}
<Link href="examples/{component.title}">{component.title}</Link>
{/each}
<h1>Component Grid</h1>
<Portfolio />

View file

@ -9,10 +9,7 @@
<link rel="manifest" href="manifest.json" crossorigin="use-credentials" />
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://unpkg.com/carbon-components/css/carbon-components.min.css"
/>
<link rel="stylesheet" href="style.css" />
<title>Carbon Components Svelte</title>
%sapper.styles% %sapper.head%

View file

@ -21,7 +21,12 @@ module.exports = {
test: /\.(svelte|html)$/,
use: {
loader: "svelte-loader",
options: { dev, hydratable: true, hotReload: false },
options: {
dev,
immutable: true,
hydratable: true,
hotReload: false,
},
},
},
],

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,12 @@
</script>
{#if skeleton}
<AccordionSkeleton {...$$restProps} />
<AccordionSkeleton
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave />
{:else}
<ul
class:bx--accordion={true}

View file

@ -1,17 +1,29 @@
<script>
export let noTrailingSlash = false;
export let skeleton = false;
import BreadcrumbSkeleton from "./Breadcrumb.Skeleton.svelte";
</script>
<nav
aria-label="Breadcrumb"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
<ol
class:bx--breadcrumb={true}
class:bx--breadcrumb--no-trailing-slash={noTrailingSlash}>
<slot />
</ol>
</nav>
{#if skeleton}
<BreadcrumbSkeleton
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave />
{:else}
<nav
aria-label="Breadcrumb"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
<ol
class:bx--breadcrumb={true}
class:bx--breadcrumb--no-trailing-slash={noTrailingSlash}>
<slot />
</ol>
</nav>
{/if}

View file

@ -1,5 +1,6 @@
<script>
export let as = undefined;
export let skeleton = false;
export let disabled = false;
export let href = undefined;
export let icon = undefined;
@ -14,6 +15,7 @@
export let ref = null;
import { getContext } from "svelte";
import ButtonSkeleton from "./Button.Skeleton.svelte";
const ctx = getContext("ComposedModal");
@ -40,54 +42,66 @@
hasIconOnly &&
tooltipAlignment &&
`bx--tooltip--align-${tooltipAlignment}`,
$$restProps.class
$$restProps.class,
]
.filter(Boolean)
.join(" ")
.join(" "),
};
</script>
{#if as}
<slot props={buttonProps} />
{:else if href && !disabled}
<!-- svelte-ignore a11y-missing-attribute -->
<a
bind:this={ref}
{...buttonProps}
{#if skeleton}
<ButtonSkeleton
{href}
small={size === 'small'}
{...$$restProps}
style={hasIconOnly && 'width: 3rem;'}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly}
<span class:bx--assistive-text={true}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class="bx--btn__icon"
aria-label={iconDescription} />
{/if}
</a>
on:mouseleave />
{:else}
<button
bind:this={ref}
{...buttonProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly}
<span class:bx--assistive-text={true}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class="bx--btn__icon"
aria-label={iconDescription} />
{/if}
</button>
{#if as}
<slot props={buttonProps} />
{:else if href && !disabled}
<!-- svelte-ignore a11y-missing-attribute -->
<a
bind:this={ref}
{...buttonProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly}
<span class:bx--assistive-text={true}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class="bx--btn__icon"
aria-label={iconDescription} />
{/if}
</a>
{:else}
<button
bind:this={ref}
{...buttonProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly}
<span class:bx--assistive-text={true}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class="bx--btn__icon"
aria-label={iconDescription} />
{/if}
</button>
{/if}
{/if}

View file

@ -1,4 +1,5 @@
<script>
export let skeleton = false;
export let indeterminate = false;
export let readonly = false;
export let checked = false;
@ -11,39 +12,49 @@
export let ref = null;
import { createEventDispatcher } from "svelte";
import CheckboxSkeleton from "./Checkbox.Skeleton.svelte";
const dispatch = createEventDispatcher();
$: dispatch("check", checked);
</script>
<div
class:bx--form-item={true}
class:bx--checkbox-wrapper={true}
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
<input
bind:this={ref}
type="checkbox"
{checked}
{disabled}
{id}
{indeterminate}
{name}
{readonly}
class:bx--checkbox={true}
on:change
on:change={() => {
checked = !checked;
}} />
<label class:bx--checkbox-label={true} for={id} {title}>
<span
class:bx--checkbox-label-text={true}
class:bx--visually-hidden={hideLabel}>
{labelText}
</span>
</label>
</div>
{#if skeleton}
<CheckboxSkeleton
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave />
{:else}
<div
class:bx--form-item={true}
class:bx--checkbox-wrapper={true}
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
<input
bind:this={ref}
type="checkbox"
{checked}
{disabled}
{id}
{indeterminate}
{name}
{readonly}
class:bx--checkbox={true}
on:change
on:change={() => {
checked = !checked;
}} />
<label class:bx--checkbox-label={true} for={id} {title}>
<span
class:bx--checkbox-label-text={true}
class:bx--visually-hidden={hideLabel}>
{labelText}
</span>
</label>
</div>
{/if}

View file

@ -1,6 +1,7 @@
<script>
export let type = "single"; // "single" | "inline" | "multi"
export let code = undefined;
export let expanded = false;
export let light = false;
export let skeleton = false;
export let copyButtonDescription = undefined;
@ -9,6 +10,7 @@
export let feedbackTimeout = 2000;
export let showLessText = "Show less";
export let showMoreText = "Show more";
export let showMoreLess = false;
export let id = "ccs-" + Math.random().toString(36);
export let ref = null;
@ -19,8 +21,6 @@
import { CopyButton } from "../CopyButton";
import CodeSnippetSkeleton from "./CodeSnippet.Skeleton.svelte";
$: showMoreLess = false;
$: expanded = false;
$: expandText = expanded ? showLessText : showMoreText;
afterUpdate(() => {
@ -31,7 +31,13 @@
</script>
{#if skeleton}
<CodeSnippetSkeleton {type} {...$$restProps} />
<CodeSnippetSkeleton
{type}
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave />
{:else}
{#if type === 'inline'}
<Copy

View file

@ -3,15 +3,17 @@
export let feedbackTimeout = 2000;
export let ref = null;
import { onDestroy } from "svelte";
import { onMount } from "svelte";
$: animation = undefined;
$: timeoutId = undefined;
$: showFeedback = timeoutId !== undefined;
let animation = undefined;
let timeout = undefined;
onDestroy(() => {
window.clearTimeout(timeoutId);
timeoutId = undefined;
$: showFeedback = timeout !== undefined;
onMount(() => {
return () => {
clearTimeout(timeout);
};
});
</script>
@ -29,7 +31,7 @@
on:click={() => {
if (animation === 'fade-in') return;
animation = 'fade-in';
timeoutId = setTimeout(() => {
timeout = setTimeout(() => {
animation = 'fade-out';
}, feedbackTimeout);
}}

View file

@ -4,27 +4,28 @@
export let iconDescription = undefined;
export let successDelay = 1500;
import { createEventDispatcher, afterUpdate, onDestroy } from "svelte";
import { createEventDispatcher, afterUpdate, onMount } from "svelte";
import CheckmarkFilled16 from "carbon-icons-svelte/lib/CheckmarkFilled16";
import Error20 from "carbon-icons-svelte/lib/Error20";
import { Loading } from "../Loading";
const dispatch = createEventDispatcher();
$: timeoutId = undefined;
let timeout = undefined;
onMount(() => {
return () => {
clearTimeout(timeout);
};
});
afterUpdate(() => {
if (status === "finished") {
timeoutId = window.setTimeout(() => {
timeout = setTimeout(() => {
dispatch("success");
}, successDelay);
}
});
onDestroy(() => {
window.clearTimeout(timeoutId);
timeoutId = undefined;
});
</script>
<div

View file

@ -17,19 +17,18 @@
const dispatch = createEventDispatcher();
$: open = true;
$: timeoutId = undefined;
let open = true;
let timeoutId = undefined;
onMount(() => {
if (timeout) {
timeoutId = window.setTimeout(() => {
timeoutId = setTimeout(() => {
open = false;
}, timeout);
}
return () => {
window.clearTimeout(timeoutId);
timeoutId = undefined;
clearTimeout(timeoutId);
};
});
</script>

View file

@ -15,11 +15,13 @@
class:bx--side-nav__link--current={isSelected}
{...$$restProps}
on:click>
<div class:bx--side-nav__icon={true} class:bx--side-nav__icon--small={true}>
{#if icon}
{#if icon}
<div
class:bx--side-nav__icon={true}
class:bx--side-nav__icon--small={true}>
<Icon {...icon} />
{/if}
</div>
</div>
{/if}
<span class:bx--side-nav__link-text={true}>{text}</span>
</a>
</li>

View file

@ -7,7 +7,7 @@
import { Icon } from "../../Icon";
</script>
<li class:bx--side-nav__item={true} class:bx--side-nav__item--icon={true}>
<li class:bx--side-nav__item={true} class:bx--side-nav__item--icon={icon}>
<button
type="button"
aria-haspopup="true"
@ -18,11 +18,11 @@
on:click={() => {
expanded = !expanded;
}}>
<div class:bx--side-nav__icon={true}>
{#if icon}
{#if icon}
<div class:bx--side-nav__icon={true}>
<Icon {...icon} />
{/if}
</div>
</div>
{/if}
<span class:bx--side-nav__submenu-title={true}>{text}</span>
<div
class:bx--side-nav__icon={true}