Merge pull request #63 from metonym/form

feat(components): add StructuredList
This commit is contained in:
Eric Liu 2019-12-21 19:02:47 -08:00 committed by GitHub
commit 06f4262bbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 534 additions and 193 deletions

View file

@ -53,6 +53,14 @@ Currently, the following components are supported:
- SelectItemGroup - SelectItemGroup
- SkeletonPlaceholder - SkeletonPlaceholder
- SkeletonText - SkeletonText
- StructuredList
- StructuredListSkeleton
- StructuredListBody
- StructuredListHead
- StructuredListCell
- StructuredListRow
- StructuredListInput
- StructuredListWrapper
- Tag - Tag
- TagSkeleton - TagSkeleton
- TextArea - TextArea

View file

@ -70,4 +70,4 @@
}</script><style>#root[hidden], }</script><style>#root[hidden],
#docs-root[hidden] { #docs-root[hidden] {
display: none !important; display: none !important;
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="runtime~main.d40bbf37ecf000a7cdc3.bundle.js"></script><script src="vendors~main.d40bbf37ecf000a7cdc3.bundle.js"></script><script src="main.d40bbf37ecf000a7cdc3.bundle.js"></script></body></html> }</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="runtime~main.7c24a16038c00f71acbb.bundle.js"></script><script src="vendors~main.7c24a16038c00f71acbb.bundle.js"></script><script src="main.7c24a16038c00f71acbb.bundle.js"></script></body></html>

View file

@ -17,4 +17,4 @@
}</script><style>#root[hidden], }</script><style>#root[hidden],
#docs-root[hidden] { #docs-root[hidden] {
display: none !important; display: none !important;
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.67b3c42af12dc2b7ac9d.bundle.js"></script><script src="vendors~main.de76cb4d691ff902e1d8.bundle.js"></script><script src="main.d19aceecbf99f4b72fa7.bundle.js"></script></body></html> }</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.67b3c42af12dc2b7ac9d.bundle.js"></script><script src="vendors~main.90220ada78163e544ba9.bundle.js"></script><script src="main.e7e683d3c4fc3d92da31.bundle.js"></script></body></html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"version":3,"file":"main.7c24a16038c00f71acbb.bundle.js","sources":["webpack:///main.7c24a16038c00f71acbb.bundle.js"],"mappings":"AAAA","sourceRoot":""}

View file

@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{415:function(n,o,c){c(416),c(529),n.exports=c(878)},438:function(n,o){},529:function(n,o,c){"use strict";c.r(o);c(530),c(850)}},[[415,1,2]]]);

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version":3,"file":"main.d40bbf37ecf000a7cdc3.bundle.js","sources":["webpack:///main.d40bbf37ecf000a7cdc3.bundle.js"],"mappings":"AAAA","sourceRoot":""}

View file

@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{0:function(n,o,c){c(417),c(529),n.exports=c(878)},1:function(n,o){},529:function(n,o,c){"use strict";c.r(o);c(530),c(850)}},[[0,1,2]]]);

View file

@ -1,2 +1,2 @@
!function(modules){function webpackJsonpCallback(data){for(var moduleId,chunkId,chunkIds=data[0],moreModules=data[1],executeModules=data[2],i=0,resolves=[];i<chunkIds.length;i++)chunkId=chunkIds[i],Object.prototype.hasOwnProperty.call(installedChunks,chunkId)&&installedChunks[chunkId]&&resolves.push(installedChunks[chunkId][0]),installedChunks[chunkId]=0;for(moduleId in moreModules)Object.prototype.hasOwnProperty.call(moreModules,moduleId)&&(modules[moduleId]=moreModules[moduleId]);for(parentJsonpFunction&&parentJsonpFunction(data);resolves.length;)resolves.shift()();return deferredModules.push.apply(deferredModules,executeModules||[]),checkDeferredModules()}function checkDeferredModules(){for(var result,i=0;i<deferredModules.length;i++){for(var deferredModule=deferredModules[i],fulfilled=!0,j=1;j<deferredModule.length;j++){var depId=deferredModule[j];0!==installedChunks[depId]&&(fulfilled=!1)}fulfilled&&(deferredModules.splice(i--,1),result=__webpack_require__(__webpack_require__.s=deferredModule[0]))}return result}var installedModules={},installedChunks={1:0},deferredModules=[];function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object"==typeof value&&value&&value.__esModule)return value;var ns=Object.create(null);if(__webpack_require__.r(ns),Object.defineProperty(ns,"default",{enumerable:!0,value:value}),2&mode&&"string"!=typeof value)for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module.default}:function getModuleExports(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="";var jsonpArray=window.webpackJsonp=window.webpackJsonp||[],oldJsonpFunction=jsonpArray.push.bind(jsonpArray);jsonpArray.push=webpackJsonpCallback,jsonpArray=jsonpArray.slice();for(var i=0;i<jsonpArray.length;i++)webpackJsonpCallback(jsonpArray[i]);var parentJsonpFunction=oldJsonpFunction;checkDeferredModules()}([]); !function(modules){function webpackJsonpCallback(data){for(var moduleId,chunkId,chunkIds=data[0],moreModules=data[1],executeModules=data[2],i=0,resolves=[];i<chunkIds.length;i++)chunkId=chunkIds[i],Object.prototype.hasOwnProperty.call(installedChunks,chunkId)&&installedChunks[chunkId]&&resolves.push(installedChunks[chunkId][0]),installedChunks[chunkId]=0;for(moduleId in moreModules)Object.prototype.hasOwnProperty.call(moreModules,moduleId)&&(modules[moduleId]=moreModules[moduleId]);for(parentJsonpFunction&&parentJsonpFunction(data);resolves.length;)resolves.shift()();return deferredModules.push.apply(deferredModules,executeModules||[]),checkDeferredModules()}function checkDeferredModules(){for(var result,i=0;i<deferredModules.length;i++){for(var deferredModule=deferredModules[i],fulfilled=!0,j=1;j<deferredModule.length;j++){var depId=deferredModule[j];0!==installedChunks[depId]&&(fulfilled=!1)}fulfilled&&(deferredModules.splice(i--,1),result=__webpack_require__(__webpack_require__.s=deferredModule[0]))}return result}var installedModules={},installedChunks={1:0},deferredModules=[];function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object"==typeof value&&value&&value.__esModule)return value;var ns=Object.create(null);if(__webpack_require__.r(ns),Object.defineProperty(ns,"default",{enumerable:!0,value:value}),2&mode&&"string"!=typeof value)for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module.default}:function getModuleExports(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="";var jsonpArray=window.webpackJsonp=window.webpackJsonp||[],oldJsonpFunction=jsonpArray.push.bind(jsonpArray);jsonpArray.push=webpackJsonpCallback,jsonpArray=jsonpArray.slice();for(var i=0;i<jsonpArray.length;i++)webpackJsonpCallback(jsonpArray[i]);var parentJsonpFunction=oldJsonpFunction;checkDeferredModules()}([]);
//# sourceMappingURL=runtime~main.d40bbf37ecf000a7cdc3.bundle.js.map //# sourceMappingURL=runtime~main.7c24a16038c00f71acbb.bundle.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"runtime~main.7c24a16038c00f71acbb.bundle.js","sources":["webpack:///runtime~main.7c24a16038c00f71acbb.bundle.js"],"mappings":"AAAA","sourceRoot":""}

View file

@ -1 +0,0 @@
{"version":3,"file":"runtime~main.d40bbf37ecf000a7cdc3.bundle.js","sources":["webpack:///runtime~main.f68146be2ed36b44235a.bundle.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"version":3,"file":"vendors~main.7c24a16038c00f71acbb.bundle.js","sources":["webpack:///vendors~main.7c24a16038c00f71acbb.bundle.js"],"mappings":"AAAA;;;;;AAmqeA;;;;;AAkxHA;;;;;AAkkEA;;;;;;;;;AAukBA;;;AA8odA;;;;;;;;AAg/BA;;;;;;;;AAqEA;;;;;;;;AAkTA;;;;;;;AAyrDA;;;;;;;AAy7CA;;;;;;;AAkhBA;;;;;;;AAfA","sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version":3,"file":"vendors~main.d40bbf37ecf000a7cdc3.bundle.js","sources":["webpack:///vendors~main.a8df32858a00714d3c23.bundle.js"],"mappings":"AAAA;;;;;AAgqeA;;;;;AAkxHA;;;;;AAkkEA;;;;;;;;;AAukBA;;;AA8odA;;;;;;;;AAg/BA;;;;;;;;AAqEA;;;;;;;;AAkTA;;;;;;;AAyrDA;;;;;;;AAy7CA;;;;;;;AAwgBA;;;;;;;AAfA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,42 @@
<script>
let className = undefined;
export { className as class };
export let border = false;
export let rowCount = 5;
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--skeleton',
'--structured-list',
border && '--structured-list--border',
className
);
const rows = Array.from({ length: rowCount - 1 }, (_, i) => i);
</script>
<section on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div class={cx('--structured-list-thead')}>
<div class={cx('--structured-list-row', '--structured-list-row--header-row')}>
<div class={cx('--structured-list-th')}>
<span />
</div>
<div class={cx('--structured-list-th')}>
<span />
</div>
<div class={cx('--structured-list-th')}>
<span />
</div>
</div>
</div>
<div class={cx('--structured-list-tbody')}>
{#each rows as row, i (row)}
<div class={cx('--structured-list-row')}>
<div class={cx('--structured-list-td')} />
<div class={cx('--structured-list-td')} />
<div class={cx('--structured-list-td')} />
</div>
{/each}
</div>
</section>

View file

@ -0,0 +1,90 @@
<script>
export let story = undefined;
import CheckmarkFilled16 from 'carbon-icons-svelte/lib/CheckmarkFilled16';
import Layout from '../../internal/ui/Layout.svelte';
import { cx } from '../../lib';
import StructuredListBody from './StructuredListBody.svelte';
import StructuredListCell from './StructuredListCell.svelte';
import StructuredListHead from './StructuredListHead.svelte';
import StructuredListInput from './StructuredListInput.svelte';
import StructuredListRow from './StructuredListRow.svelte';
import StructuredListWrapper from './StructuredListWrapper.svelte';
import StructuredListSkeleton from './StructuredList.Skeleton.svelte';
</script>
<Layout>
<div>
{#if story === 'skeleton'}
<div style="width: 800px">
<StructuredListSkeleton />
<StructuredListSkeleton border />
</div>
{:else if story === 'selection'}
<StructuredListWrapper selection border defaultSelected="row-1-value">
<StructuredListHead>
<StructuredListRow head>
<StructuredListCell head>ColumnA</StructuredListCell>
<StructuredListCell head>ColumnB</StructuredListCell>
<StructuredListCell head>ColumnC</StructuredListCell>
<StructuredListCell head>{''}</StructuredListCell>
</StructuredListRow>
</StructuredListHead>
<StructuredListBody>
{#each [0, 1, 2, 3] as item, i (item)}
<StructuredListRow label for={`row-${i}`}>
<StructuredListCell>Row {i}</StructuredListCell>
<StructuredListCell>Row {i}</StructuredListCell>
<StructuredListCell>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui magna, finibus id
tortor sed, aliquet bibendum augue. Aenean posuere sem vel euismod dignissim. Nulla
ut cursus dolor. Pellentesque vulputate nisl a porttitor interdum.
</StructuredListCell>
<StructuredListInput
id={`row-${i}`}
value={`row-${i}-value`}
title={`row-${i}-title`}
name={`row-${i}-name`} />
<StructuredListCell>
<CheckmarkFilled16
class={cx('--structured-list-svg')}
aria-label="select an option"
title="select an option" />
</StructuredListCell>
</StructuredListRow>
{/each}
</StructuredListBody>
</StructuredListWrapper>
{:else}
<StructuredListWrapper>
<StructuredListHead>
<StructuredListRow head>
<StructuredListCell head>ColumnA</StructuredListCell>
<StructuredListCell head>ColumnB</StructuredListCell>
<StructuredListCell head>ColumnC</StructuredListCell>
</StructuredListRow>
</StructuredListHead>
<StructuredListBody>
<StructuredListRow>
<StructuredListCell noWrap>Row 1</StructuredListCell>
<StructuredListCell>Row 1</StructuredListCell>
<StructuredListCell>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui magna, finibus id
tortor sed, aliquet bibendum augue. Aenean posuere sem vel euismod dignissim. Nulla ut
cursus dolor. Pellentesque vulputate nisl a porttitor interdum.
</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell noWrap>Row 2</StructuredListCell>
<StructuredListCell>Row 2</StructuredListCell>
<StructuredListCell>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui magna, finibus id
tortor sed, aliquet bibendum augue. Aenean posuere sem vel euismod dignissim. Nulla ut
cursus dolor. Pellentesque vulputate nisl a porttitor interdum.
</StructuredListCell>
</StructuredListRow>
</StructuredListBody>
</StructuredListWrapper>
{/if}
</div>
</Layout>

View file

@ -0,0 +1,10 @@
import { withKnobs, select, boolean, text } from '@storybook/addon-knobs';
import Component from './StructuredList.Story.svelte';
export default { title: 'StructuredList', decorators: [withKnobs] };
export const Default = () => ({ Component });
export const Selection = () => ({ Component, props: { story: 'selection' } });
export const Skeleton = () => ({ Component, props: { story: 'skeleton' } });

View file

@ -0,0 +1,13 @@
<script>
let className = undefined;
export { className as class };
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--structured-list-tbody', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<slot />
</div>

View file

@ -0,0 +1,20 @@
<script>
let className = undefined;
export { className as class };
export let head = false;
export let noWrap = false;
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
head && '--structured-list-th',
!head && '--structured-list-td',
noWrap && '--structured-list-content--nowrap',
className
);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<slot />
</div>

View file

@ -0,0 +1,13 @@
<script>
let className = undefined;
export { className as class };
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--structured-list-thead', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<slot />
</div>

View file

@ -0,0 +1,37 @@
<script>
let className = undefined;
export { className as class };
export let id = Math.random();
export let value = 'value';
export let title = 'title';
export let name = '';
export let checked = false;
export let style = undefined;
import { getContext } from 'svelte';
import { cx } from '../../lib';
const _class = cx('--structured-list-input', className);
const { selected, update } = getContext('StructuredListWrapper');
if (checked) {
update(value);
}
$: checked = $selected === value;
</script>
<input
type="radio"
tabindex="-1"
class={_class}
on:change={() => {
update(value);
}}
{value}
{name}
{title}
{style}
{id}
{checked} />

View file

@ -0,0 +1,36 @@
<script>
let className = undefined;
export { className as class };
export let head = false;
export let label = false;
export let tabindex = '0';
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--structured-list-row',
head && '--structured-list-row--header-row',
className
);
</script>
{#if label}
<label
role="presentation"
on:click
on:mouseover
on:mouseenter
on:mouseleave
on:keydown
class={_class}
for={$$props.for}
{tabindex}
{style}>
<slot />
</label>
{:else}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<slot />
</div>
{/if}

View file

@ -0,0 +1,45 @@
<script>
let className = undefined;
export { className as class };
export let defaultSelected = undefined;
export let border = false;
export let selection = 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(
'--structured-list',
border && '--structured-list--border',
selection && '--structured-list--selection',
className
);
let selected = writable(defaultSelected);
setContext('StructuredListWrapper', {
selected,
update: value => {
selected.set(value);
}
});
$: {
defaultSelected = $selected;
dispatch('change', $selected);
}
</script>
<section
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
aria-label={$$props['aria-label'] || 'Structured list section'}
{style}>
<slot />
</section>

View file

@ -0,0 +1,10 @@
import StructuredList from './StructuredList.svelte';
export default StructuredList;
export { default as StructuredListSkeleton } from './StructuredList.Skeleton.svelte';
export { default as StructuredListBody } from './StructuredListBody.svelte';
export { default as StructuredListHead } from './StructuredListHead.svelte';
export { default as StructuredListCell } from './StructuredListCell.svelte';
export { default as StructuredListRow } from './StructuredListRow.svelte';
export { default as StructuredListInput } from './StructuredListInput.svelte';
export { default as StructuredListWrapper } from './StructuredListWrapper.svelte';

View file

@ -30,6 +30,15 @@ import Search, { SearchSkeleton } from './components/Search';
import Select, { SelectSkeleton, SelectItem, SelectItemGroup } from './components/Select'; import Select, { SelectSkeleton, SelectItem, SelectItemGroup } from './components/Select';
import SkeletonPlaceholder from './components/SkeletonPlaceholder'; import SkeletonPlaceholder from './components/SkeletonPlaceholder';
import SkeletonText from './components/SkeletonText'; import SkeletonText from './components/SkeletonText';
import StructuredList, {
StructuredListSkeleton,
StructuredListBody,
StructuredListHead,
StructuredListCell,
StructuredListRow,
StructuredListInput,
StructuredListWrapper
} from './components/StructuredList';
import Tag, { TagSkeleton } from './components/Tag'; import Tag, { TagSkeleton } from './components/Tag';
import TextArea, { TextAreaSkeleton } from './components/TextArea'; import TextArea, { TextAreaSkeleton } from './components/TextArea';
import TextInput, { TextInputSkeleton, PasswordInput } from './components/TextInput'; import TextInput, { TextInputSkeleton, PasswordInput } from './components/TextInput';
@ -93,6 +102,14 @@ export {
SkeletonPlaceholder, SkeletonPlaceholder,
SkeletonText, SkeletonText,
Switch, Switch,
StructuredList,
StructuredListSkeleton,
StructuredListBody,
StructuredListHead,
StructuredListCell,
StructuredListRow,
StructuredListInput,
StructuredListWrapper,
Tag, Tag,
TagSkeleton, TagSkeleton,
TextArea, TextArea,