diff --git a/README.md b/README.md index 66506219..4edada67 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,10 @@ Currently, the following components are supported: - StructuredListRow - StructuredListInput - StructuredListWrapper +- Tabs + - Tab + - TabContent + - TabsSkeleton - Tag - TagSkeleton - TextArea diff --git a/src/components/Tabs/Tab.svelte b/src/components/Tabs/Tab.svelte new file mode 100644 index 00000000..38480380 --- /dev/null +++ b/src/components/Tabs/Tab.svelte @@ -0,0 +1,69 @@ + + +
  • { + if (!disabled) { + update(id); + } + }} + on:mouseover + on:mouseenter + on:mouseleave + on:keydown={event => { + if (disabled) { + return; + } + if (event.key === 'ArrowRight') { + change(1); + } else if (event.key === 'ArrowLeft') { + change(-1); + } else if (event.key === ' ' || event.key === 'Enter') { + update(id); + } + }} + {role} + {style}> + + {label} + +
  • diff --git a/src/components/Tabs/TabContent.svelte b/src/components/Tabs/TabContent.svelte new file mode 100644 index 00000000..7ed20da9 --- /dev/null +++ b/src/components/Tabs/TabContent.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/components/Tabs/Tabs.Story.svelte b/src/components/Tabs/Tabs.Story.svelte new file mode 100644 index 00000000..a171e3c7 --- /dev/null +++ b/src/components/Tabs/Tabs.Story.svelte @@ -0,0 +1,43 @@ + + + + {#if story === 'skeleton'} + + {:else if story === 'container'} + + + + +
    + Content 1 + Content 2 + Content 3 +
    +
    + {:else} + + + + + +
    + Content 1 + Content 2 + Content 3 + Content 4 +
    +
    + {/if} +
    diff --git a/src/components/Tabs/Tabs.stories.js b/src/components/Tabs/Tabs.stories.js new file mode 100644 index 00000000..1bf413c9 --- /dev/null +++ b/src/components/Tabs/Tabs.stories.js @@ -0,0 +1,45 @@ +import { withKnobs, boolean, number, text } from '@storybook/addon-knobs'; +import Component from './Tabs.Story.svelte'; + +export default { title: 'Tabs', decorators: [withKnobs] }; + +export const Default = () => ({ + Component, + props: { + tabProps: { + disabled: boolean('Disabled (disabled in )', false), + href: text('The href for tab (href in )', '#'), + role: text('ARIA role (role in )', 'presentation'), + tabindex: number('Tab index (tabindex in )', 0) + }, + tabsProps: { + className: 'some-class', + selected: number('The index of the selected tab (selected in )', 1), + triggerHref: text('The href of trigger button for narrow mode (triggerHref in )', '#'), + role: text('ARIA role (role in )', 'navigation'), + iconDescription: text( + 'The description of the trigger icon for narrow mode (iconDescription in )', + 'show menu options' + ), + tabContentClassName: text( + 'The className for the child `` components', + 'tab-content' + ) + } + } +}); + +export const Container = () => ({ + Component, + props: { + story: 'container', + tabProps: { + disabled: boolean('Disabled (disabled in )', false), + href: text('The href for tab (href in )', '#'), + role: text('ARIA role (role in )', 'presentation'), + tabindex: number('Tab index (tabindex in )', 0) + } + } +}); + +export const Skeleton = () => ({ Component, props: { story: 'skeleton' } }); diff --git a/src/components/Tabs/Tabs.svelte b/src/components/Tabs/Tabs.svelte new file mode 100644 index 00000000..b25e0396 --- /dev/null +++ b/src/components/Tabs/Tabs.svelte @@ -0,0 +1,114 @@ + + +
    +
    { + dropdownHidden = !dropdownHidden; + }} + on:keypress + on:keypress={() => { + dropdownHidden = !dropdownHidden; + }}> + { + dropdownHidden = !dropdownHidden; + }}> + {#if currentTab}{currentTab.label}{/if} + +
    +
      + +
    +
    + diff --git a/src/components/Tabs/TabsSkeleton.svelte b/src/components/Tabs/TabsSkeleton.svelte new file mode 100644 index 00000000..b2b02af9 --- /dev/null +++ b/src/components/Tabs/TabsSkeleton.svelte @@ -0,0 +1,25 @@ + + +
    +
    +
     
    + + + +
    +
      + {#each [0, 1, 2, 3] as item, i (item)} +
    • +
       
      +
    • + {/each} +
    +
    diff --git a/src/components/Tabs/index.js b/src/components/Tabs/index.js new file mode 100644 index 00000000..9ff5322a --- /dev/null +++ b/src/components/Tabs/index.js @@ -0,0 +1,6 @@ +import Tabs from './Tabs.svelte'; + +export default Tabs; +export { default as Tab } from './Tab.svelte'; +export { default as TabContent } from './TabContent.svelte'; +export { default as TabsSkeleton } from './TabsSkeleton.svelte'; diff --git a/src/index.js b/src/index.js index f98206b8..7c0d8051 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,7 @@ import { StructuredListInput, StructuredListWrapper } from './components/StructuredList'; +import Tabs, { Tab, TabContent, TabsSkeleton } from './components/Tabs'; import Tag, { TagSkeleton } from './components/Tag'; import TextArea, { TextAreaSkeleton } from './components/TextArea'; import TextInput, { TextInputSkeleton, PasswordInput } from './components/TextInput'; @@ -109,6 +110,10 @@ export { StructuredListRow, StructuredListInput, StructuredListWrapper, + Tabs, + Tab, + TabContent, + TabsSkeleton, Tag, TagSkeleton, TextArea,