first commit on the UIShell

This commit is contained in:
adan.ulloa 2020-01-02 12:04:41 -06:00
commit d3c2732c4c
13 changed files with 492 additions and 0 deletions

View file

@ -0,0 +1,3 @@
<script>
</script>

View file

@ -0,0 +1,155 @@
<script>
export let story = undefined;
import UIShell from './UIShell.svelte';
import FormTest from './FormTest.svelte';
import Notification20 from 'carbon-icons-svelte/lib/Notification20';
import UserAvatar20 from 'carbon-icons-svelte/lib/UserAvatar20';
const navMenu = [
{
href: '#',
text: 'Link 1',
subMenu: undefined
},
{
href: '#',
text: 'Link 2',
subMenu: undefined
},
{
href: '#',
text: 'Link 3',
subMenu: undefined
},
{
href: undefined,
text: 'Link 4',
subMenu: [
{
href: '#',
text: 'Sub-link 1'
},
{
href: '#',
text: 'Sub-link 2'
},
{
href: '#',
text: 'Sub-link 3'
}
]
}
];
/*
Format:
action: will be place on the aria-label, use to identify the action from the others.
type: search-> will open an inputText to start a search.
component-> when specifying this property, content will expect a .svelte file.
link-> when specifying this property, content will expect for subject objects that will contain href and link.
icon: you need to specify the properties specified in carbon-icons-svelte components as shown in the example below.
content: what will be shown on the component, could vary the information depending on the type property.
*** actions 'search' and 'switcher' doesnt need to specify type and icon because those are predefined actions in the component.
*/
const rightPanel = [
{
action: 'search'
},
{
action: 'userlogin',
type: 'component',
icon: [
{
class: undefined,
skeleton: false,
render: Notification20,
title: 'Notification20',
tabIndex: 0,
focusable: false,
style: undefined
}
],
content: FormTest
},
{
action: 'switcher',
content: [
{
subjet: 'Switcher theme 1',
items: [
{
href: '#',
text: 'Switcher item 1'
}
]
},
{
subjet: 'Switcher theme 2',
items: [
{
href: '#',
text: 'Switcher item 1'
},
{
href: '#',
text: 'Switcher item 2'
},
{
href: '#',
text: 'Switcher item 3'
},
{
href: '#',
text: 'Switcher item 4'
}
]
},
{
subjet: 'Switcher theme 3',
items: [
{
href: '#',
text: 'Switcher item 1'
},
{
href: '#',
text: 'Switcher item 2'
}
]
}
]
},
{
action: 'userlogin',
type: 'component',
icon: [
{
class: undefined,
skeleton: false,
render: UserAvatar20,
title: 'UserAvatar20',
tabIndex: 0,
focusable: false,
style: undefined
}
],
content: FormTest
}
];
</script>
{#if story === 'with-nav'}
<UIShell {...$$props} {navMenu} />
{:else if story === 'with-actions'}
<UIShell {...$$props} {rightPanel} />
{:else}
<UIShell {...$$props} />
{/if}

View file

@ -0,0 +1,34 @@
import { withKnobs, text } from '@storybook/addon-knobs';
import Component from './UIShell.Story.svelte';
export default { title: 'UIShell', decorators: [withKnobs] };
export const Default = () => ({
Component,
props: {
story: 'default',
href: text('The link href (href)', '#'),
company: text('Company name', 'IBM'),
platformName: text('Platform name', 'Platform Name')
}
});
export const WithNav = () => ({
Component,
props: {
story: 'with-nav',
href: text('The link href (href)', '#'),
company: text('Company name', 'IBM'),
platformName: text('Platform name', 'Platform Name')
}
});
export const WithActions = () => ({
Component,
props: {
story: 'with-actions',
href: text('The link href (href)', '#'),
company: text('Company name', 'IBM'),
platformName: text('Platform name', 'Platform Name')
}
});

View file

@ -0,0 +1,32 @@
<script>
export let uiShellAriaLabel = undefined;
export let href = undefined;
export let company = undefined;
export let platformName = undefined;
export let navMenu = undefined;
export let rightPanel = undefined;
import { cx } from '../../lib';
import UIShellNavWrapper from './UIShellNav/UIShellNavWrapper.svelte';
import UIShellNavItem from './UIShellNav/UIShellNavItem.svelte';
import UIShellRightPanel from './UIShellRightPanel/UIShellRightPanel.svelte';
$: ariaLabel = 'IBM ' + (uiShellAriaLabel || $$props['aria-label'] || platformName);
</script>
<header aria-label={ariaLabel} class={cx('--header')} role="banner">
<a class={cx('--header__name')} {href}>
<span class={cx('--header__name--prefix')}>{company}</span>
&nbsp;{platformName}
</a>
{#if navMenu}
<UIShellNavWrapper ariaLabel>
{#each navMenu as itemMenu}
<UIShellNavItem {...itemMenu} />
{/each}
</UIShellNavWrapper>
{/if}
{#if rightPanel}
<UIShellRightPanel {rightPanel} />
{/if}
</header>

View file

@ -0,0 +1,41 @@
<script>
export let href = undefined;
export let text = undefined;
export let subMenu = undefined;
import { cx } from '../../../lib';
import UIShellSubmenu from './UIShellNavSubmenu.svelte';
</script>
{#if href}
<li>
<a
class={cx('--header__menu-item')}
role="menuitem"
tabindex="0"
on:click
on:mouseover
on:mouseenter
on:mouseleave
on:keyup
on:keydown
on:focus
on:blur
{href}>
<span class={cx('--text-truncate--end')}>{text}</span>
</a>
</li>
{:else}
<UIShellSubmenu
{href}
{text}
{subMenu}
on:click
on:mouseover
on:mouseenter
on:mouseleave
on:keyup
on:keydown
on:focus
on:blur />
{/if}

View file

@ -0,0 +1,73 @@
<script>
export let href = undefined;
export let text = undefined;
export let subMenu = undefined;
export let iconDescription = 'Expand/Collapse';
export let expanded = false;
import ChevronDown16 from 'carbon-icons-svelte/lib/ChevronDown16';
import { cx } from '../../../lib';
let listItemSubMenu = undefined;
window.addEventListener('mouseup', ({ target }) => {
if (target !== listItemSubMenu) {
if (expanded) {
console.log('entered first if');
expanded = false;
}
} else if (listItemSubMenu.contains(target) || target === listItemSubMenu) {
console.log('entered second if');
expanded = !expanded;
}
});
</script>
<li class={cx('--header__submenu')} title={iconDescription}>
<a
bind:this={listItemSubMenu}
aria-haspopup="menu"
aria-expanded={expanded}
class={cx('--header__menu-item', '--header__menu-title')}
role="menuitem"
tabindex="0"
aria-label={text}
href="javascript:void(0)"
on:keydown
on:keydown={({ key }) => {
if (key === 'Enter') {
expanded = !expanded;
}
}}
on:click
on:mouseover
on:mouseenter
on:mouseleave
on:keyup
on:focus
on:blur>
{text}
<ChevronDown16 class={cx('--header__menu-arrow')} aria-label={iconDescription} />
</a>
<ul aria-label={href} class={cx('--header__menu')} role="menu">
{#each subMenu as item}
<li role="none">
<a
href={item.href}
class={cx('--header__menu-item')}
role="menuitem"
tabindex="0"
on:click
on:mouseover
on:mouseenter
on:mouseleave
on:keyup
on:keydown
on:focus
on:blur>
<span class={cx('--text-truncate--end')}>{item.text}</span>
</a>
</li>
{/each}
</ul>
</li>

View file

@ -0,0 +1,11 @@
<script>
export let ariaLabel = undefined;
import { cx } from '../../../lib';
</script>
<nav aria-label={ariaLabel} class={cx('--header__nav')}>
<ul aria-label={ariaLabel} class={cx('--header__menu-bar')} role="menubar">
<slot />
</ul>
</nav>

View file

@ -0,0 +1,13 @@
<script>
// export let action = undefined;
// export let type = undefined;
export let icon = undefined;
// export let content = undefined;
import { cx } from '../../../lib';
import Icon from '../../Icon/Icon.svelte';
</script>
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
</button>

View file

@ -0,0 +1,38 @@
<script>
export let action = undefined;
// export let type = undefined;
// export let icon = undefined;
// export let content = undefined;
// import { onMount } from 'svelte';
import { cx } from '../../../lib';
import AppSwitcher20 from 'carbon-icons-svelte/lib/AppSwitcher20';
import Icon from '../../Icon/Icon.svelte';
console.log(action);
$: switcherIconProps =
action === 'switcher'
? (switcherIconProps = [
{
class: undefined,
skeleton: false,
render: AppSwitcher20,
title: 'Switcher',
tabIndex: 0,
focusable: false,
style: undefined
}
])
: (switcherIconProps = []);
</script>
{#if action === 'switcher'}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...switcherIconProps} render={switcherIconProps[0].render} />
</button>
{:else}
<!-- <button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
</button> -->
{/if}

View file

@ -0,0 +1,36 @@
<script>
export let action = undefined;
// export let type = undefined;
export let icon = undefined;
// export let content = undefined;
// import { onMount } from 'svelte';
import { cx } from '../../../lib';
import Search20 from 'carbon-icons-svelte/lib/Search20';
import Icon from '../../Icon/Icon.svelte';
$: searchIconProps =
action === 'search'
? (searchIconProps = [
{
class: undefined,
skeleton: false,
render: Search20,
title: 'Search',
tabIndex: 0,
focusable: false,
style: undefined
}
])
: (searchIconProps = []);
</script>
{#if action === 'search'}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...searchIconProps} render={searchIconProps[0].render} />
</button>
{:else}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
</button>
{/if}

View file

@ -0,0 +1,51 @@
<script>
export let rightPanel = undefined;
import { onMount } from 'svelte';
import { cx } from '../../../lib';
import ActionSearch from './ActionSearch.svelte';
import ActionComponent from './ActionComponent.svelte';
import ActionLink from './ActionLink.svelte';
// let switcherAtLast = [];
// let renderSwitcher = false;
$: switcherAtLast = rightPanel.map((item, index, array) => {
if (item.action === 'switcher') {
if (index !== rightPanel.length) {
const newItem = array[index];
return newItem;
}
} else {
return undefined;
}
});
$: renderSwitcher = switcherAtLast ? true : false;
onMount(()=>{
console.log(switcherAtLast);
console.log(renderSwitcher);
})
</script>
<div class={cx('--header__global')}>
{#each rightPanel as action, index}
{#if action.action === 'search'}
<ActionSearch {...action} />
{:else if action.action === 'switcher'}
{#if index === rightPanel.length}
<ActionLink {...action} />
{/if}
{:else if action.type === 'search'}
<ActionSearch {...action} />
{:else if action.type === 'component'}
<ActionComponent {...action} />
{:else if action.type === 'link'}
<ActionLink {...action} />
{/if}
{/each}
{#if renderSwitcher}
<ActionLink {...switcherAtLast} />
{/if}
</div>

View file

@ -0,0 +1,3 @@
import UIShell from './UIShell.svelte';
export default UIShell;

View file

@ -82,6 +82,7 @@ import ToggleSmall, { ToggleSmallSkeleton } from './components/ToggleSmall';
import Tooltip from './components/Tooltip'; import Tooltip from './components/Tooltip';
import TooltipDefinition from './components/TooltipDefinition'; import TooltipDefinition from './components/TooltipDefinition';
import TooltipIcon from './components/TooltipIcon'; import TooltipIcon from './components/TooltipIcon';
import UIShell from './components/UIShell';
import UnorderedList from './components/UnorderedList'; import UnorderedList from './components/UnorderedList';
export { export {
@ -193,5 +194,6 @@ export {
Tooltip, Tooltip,
TooltipDefinition, TooltipDefinition,
TooltipIcon, TooltipIcon,
UIShell,
UnorderedList UnorderedList
}; };