feat: add Grid component

This commit is contained in:
Eric Liu 2020-07-21 07:46:54 -07:00
commit f9f58999b2
7 changed files with 341 additions and 0 deletions

58
src/Grid/Column.svelte Normal file
View file

@ -0,0 +1,58 @@
<script>
export let as = false;
/**
* Types for `sm`, `md`, `lg`, `xlg`, `max`:
* true
* Number
* { span: Number | true; offset?: Number }
*/
export let sm = undefined;
export let md = undefined;
export let lg = undefined;
export let xlg = undefined;
export let max = undefined;
const breakpoints = ["sm", "md", "lg", "xlg", "max"];
$: columnClass = [sm, md, lg, xlg, max]
.map((breakpoint, i) => {
const name = breakpoints[i];
if (breakpoint === true) {
return `bx--col-${name}`;
} else if (typeof breakpoint === "number") {
return `bx--col-${name}-${breakpoint}`;
} else if (typeof breakpoint === "object") {
let bp = [];
if (typeof breakpoint.span === "number") {
bp = [...bp, `bx--col-${name}-${breakpoint.span}`];
} else if (breakpoint.span === true) {
bp = [...bp, `bx--col-${name}`];
}
if (typeof breakpoint.offset === "number") {
bp = [...bp, `bx--offset-${name}-${breakpoint.offset}`];
}
return bp.join(" ");
}
})
.filter(Boolean)
.join(" ");
$: props = {
...$$restProps,
class: [$$restProps.class, columnClass, !columnClass && "bx--col"]
.filter(Boolean)
.join(" ")
};
</script>
{#if as}
<slot {props} />
{:else}
<div {...props}>
<slot />
</div>
{/if}

229
src/Grid/Grid.Story.svelte Normal file
View file

@ -0,0 +1,229 @@
<script>
import Grid from "./Grid.svelte";
import Row from "./Row.svelte";
import Column from "./Column.svelte";
</script>
<style>
:global(.grid div) {
outline: 1px solid #e0e0e0;
font-size: 0.75rem;
}
:global(.outside) {
min-height: 2rem;
}
h6 {
margin-top: 2.5rem;
margin-bottom: 0.5rem;
}
</style>
<div class="grid">
<h6>Columns with auto-width</h6>
<Grid>
<Row>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
</Grid>
<h6>Responsive Grid</h6>
<Grid>
<Row>
<Column sm={1} md={4} lg={8}>
<div class="outside">
<div class="inside">sm: 1/4, md: 1/2, lg: 2/3</div>
</div>
</Column>
<Column sm={1} md={2} lg={2}>
<div class="outside">
<div class="inside">sm: 1/4, md: 1/4, lg: 1/6</div>
</div>
</Column>
<Column sm={1} md={1} lg={1}>
<div class="outside">
<div class="inside">sm: 1/4, md: 1/8, lg: 1/12</div>
</div>
</Column>
<Column sm={1} md={1} lg={1}>
<div class="outside">
<div class="inside">sm: 1/4, md: 1/8, lg: 1/12</div>
</div>
</Column>
</Row>
</Grid>
<h6>Columns with Offset</h6>
<Grid>
<Row>
<Column sm={{ span: 1, offset: 3 }}>
<div class="outside">
<div class="inside">Small Screen Offset 3</div>
</div>
</Column>
<Column sm={{ span: 2, offset: 2 }}>
<div class="outside">
<div class="inside">Small Screen Offset 2</div>
</div>
</Column>
<Column sm={{ span: 3, offset: 1 }}>
<div class="outside">
<div class="inside">Small Screen Offset 1</div>
</div>
</Column>
<Column sm={{ span: 4, offset: 0 }}>
<div class="outside">
<div class="inside">Small Screen Offset 0</div>
</div>
</Column>
</Row>
</Grid>
<h6>Condensed Grid</h6>
<Grid condensed>
<Row>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
</Grid>
<h6>Condensed Columns</h6>
<Grid>
<Row>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
<Row condensed>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
<Row>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
</Grid>
<h6>Full Width</h6>
<Grid fullWidth>
<Row>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
<Column>
<div class="outside">
<div class="inside">1/4</div>
</div>
</Column>
</Row>
</Grid>
</div>

6
src/Grid/Grid.stories.js Normal file
View file

@ -0,0 +1,6 @@
import { withKnobs } from "@storybook/addon-knobs";
import Component from "./Grid.Story.svelte";
export default { title: "Grid", decorators: [withKnobs] };
export const Default = () => ({ Component });

25
src/Grid/Grid.svelte Normal file
View file

@ -0,0 +1,25 @@
<script>
export let as = false;
export let condensed = false;
export let fullWidth = false;
$: props = {
...$$restProps,
class: [
$$restProps.class,
"bx--grid",
condensed && "bx--grid--condensed",
fullWidth && "bx--grid--full-width"
]
.filter(Boolean)
.join(" ")
};
</script>
{#if as}
<slot {props} />
{:else}
<div {...props}>
<slot />
</div>
{/if}

19
src/Grid/Row.svelte Normal file
View file

@ -0,0 +1,19 @@
<script>
export let as = false;
export let condensed = false;
$: props = {
...$$restProps,
class: [$$restProps.class, "bx--row", condensed && "bx--row--condensed"]
.filter(Boolean)
.join(" ")
};
</script>
{#if as}
<slot {props} />
{:else}
<div {...props}>
<slot />
</div>
{/if}

3
src/Grid/index.js Normal file
View file

@ -0,0 +1,3 @@
export { default as Grid } from "./Grid.svelte";
export { default as Row } from "./Row.svelte";
export { default as Column } from "./Column.svelte";

View file

@ -37,6 +37,7 @@ export { Form } from "./Form";
export { FormGroup } from "./FormGroup";
export { FormItem } from "./FormItem";
export { FormLabel } from "./FormLabel";
export { Grid, Row, Column } from "./Grid";
export { Icon, IconSkeleton } from "./Icon";
export { InlineLoading } from "./InlineLoading";
export { Link } from "./Link";