uisehll with nav finished

This commit is contained in:
adan.ulloa 2020-01-06 18:41:10 -06:00
commit 390f950ca5
10 changed files with 578 additions and 128 deletions

View file

@ -1,13 +1,14 @@
<script>
// export let action = undefined;
// export let type = undefined;
<!-- <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';
import { leftPanelActions } from '../constants';
</script>
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<button aria-label={type} class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
</button>
</button> -->

View file

@ -0,0 +1,195 @@
<script>
export let action = undefined;
import { cx } from '../../../lib';
import ActionLink from './ActionLink.svelte';
import ActionComponent from './ActionComponent.svelte';
import ActionSearch from './ActionSearch.svelte';
import { leftPanelTypes, actionSearchWhiteList } from '../constants';
let typeComponent = undefined;
let componentIsActive = false;
let typeSearch = undefined;
let searchIsActive = false;
let typeLink = undefined;
let linkIsActive = false;
let isSearchFocus = false;
window.addEventListener('mouseup', ({ target }) => {
checkForClicks(target, typeComponent, leftPanelTypes.component);
checkForClicksTypeSearch(target, typeSearch, leftPanelTypes.search);
checkForClicks(target, typeLink, leftPanelTypes.link);
});
function checkForClicks(target, component, actionString) {
try {
if (component && target) {
if (component.contains(target) || target === component) {
if (actionString === leftPanelTypes.component) {
componentIsActive = !componentIsActive;
} else if (actionString === leftPanelTypes.link) {
linkIsActive = !linkIsActive;
}
} else {
if (actionString === leftPanelTypes.component) {
if (componentIsActive) {
componentIsActive = false;
}
} else if (actionString === leftPanelTypes.link) {
if (linkIsActive) {
linkIsActive = false;
}
}
}
}
} catch (error) {}
}
function checkForClicksTypeSearch(target, component, actionString) {
let parentFirstLine;
let parentSecondLine;
if (component && target) {
try {
if (
target.id !== 'right-panel-action-search' &&
target.parentNode.id !== 'right-panel-action-search' &&
target.parentNode.parentNode.id !== 'right-panel-action-search'
) {
if (component.contains(target) || target === component) {
if (actionString === leftPanelTypes.component) {
componentIsActive = !componentIsActive;
} else if (actionString === leftPanelTypes.search) {
searchIsActive = !searchIsActive;
} else if (actionString === leftPanelTypes.link) {
linkIsActive = !linkIsActive;
}
} else {
if (actionString === leftPanelTypes.component) {
if (componentIsActive) {
componentIsActive = false;
}
} else if (actionString === leftPanelTypes.search) {
if (searchIsActive) {
searchIsActive = false;
}
} else if (actionString === leftPanelTypes.link) {
if (linkIsActive) {
linkIsActive = false;
}
}
}
} else {
if (actionString === leftPanelTypes.component) {
if (!componentIsActive && target.id !== 'right-panel-close-search') {
componentIsActive = true;
} else if (
componentIsActive &&
(target.id === 'right-panel-close-search' ||
target.parentNode.id === 'right-panel-close-search')
) {
componentIsActive = false;
}
} else if (actionString === leftPanelTypes.search) {
if (!searchIsActive && target.id !== 'right-panel-close-search') {
searchIsActive = true;
} else if (
searchIsActive &&
(target.id === 'right-panel-close-search' ||
target.parentNode.id === 'right-panel-close-search')
) {
searchIsActive = false;
}
} else if (actionString === leftPanelTypes.link) {
if (!linkIsActive && target.id !== 'right-panel-close-search') {
linkIsActive = true;
} else if (
linkIsActive &&
(target.id === 'right-panel-close-search' ||
target.parentNode.id === 'right-panel-close-search')
) {
linkIsActive = false;
}
}
}
} catch (error) {
if (actionString === leftPanelTypes.component) {
if (componentIsActive) {
componentIsActive = false;
}
} else if (actionString === leftPanelTypes.search) {
if (searchIsActive) {
searchIsActive = false;
}
} else if (actionString === leftPanelTypes.link) {
if (linkIsActive) {
linkIsActive = false;
}
}
}
}
}
</script>
<style>
.search-wrapper {
position: relative;
display: flex;
max-width: 28rem;
width: 100%;
margin-left: 0.5rem;
height: 3rem;
background-color: #393939;
color: #fff;
transition: max-width 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
}
.search-wrapper-hidden {
max-width: 3rem;
background-color: #161616;
}
.search-focus {
outline: 2px solid #fff;
outline-offset: -2px;
}
</style>
{#if action.type === leftPanelTypes.component}
<div bind:this={typeComponent}>
<ActionComponent
action={action.action}
icon={action.icon ? action.icon : undefined}
content={action.content}
bind:componentIsActive />
</div>
{:else if action.type === leftPanelTypes.search}
<div
bind:this={typeSearch}
class="search-wrapper"
class:search-wrapper-hidden={!searchIsActive}
class:search-focus={isSearchFocus || searchIsActive}
role="search">
<ActionSearch
action={action.action}
icon={action.icon ? action.icon : undefined}
content={action.content}
bind:searchIsActive
focusInputSearch={() => {
isSearchFocus = true;
}}
focusOutInputSearch={() => {
isSearchFocus = false;
}} />
</div>
{:else if action.type === leftPanelTypes.link || action.type === leftPanelTypes.links}
<div bind:this={typeLink}>
<ActionLink
action={action.action}
icon={action.icon ? action.icon : undefined}
content={action.content}
bind:linkIsActive />
</div>
{/if}

View file

@ -1,38 +1,68 @@
<script>
export let action = undefined;
// export let type = undefined;
// export let icon = undefined;
export let type = undefined;
export let icon = undefined;
// export let content = undefined;
export let linkIsActive = undefined;
// import { onMount } from 'svelte';
import { cx } from '../../../lib';
import AppSwitcher20 from 'carbon-icons-svelte/lib/AppSwitcher20';
import Icon from '../../Icon/Icon.svelte';
import { leftPanelActions } from '../constants';
import { slide } from 'svelte/transition';
console.log(action);
let skeleton = icon ? icon.skeleton : false;
$: switcherIconProps =
action === 'switcher'
? (switcherIconProps = [
{
class: undefined,
skeleton: false,
render: AppSwitcher20,
title: 'Switcher',
tabIndex: 0,
focusable: false,
style: undefined
if (!icon) {
const actionsArray = Object.entries(leftPanelActions);
for (const definedAction of actionsArray) {
for (const content of definedAction) {
if (typeof content === 'object') {
if (content.actionString === action) {
icon = content.iconProps;
}
])
: (switcherIconProps = []);
}
}
}
}
</script>
{#if action === 'switcher'}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...switcherIconProps} render={switcherIconProps[0].render} />
{#if action === leftPanelActions.switcher.actionString}
<button
aria-label={type}
class={cx('--header__action', linkIsActive && '--header__action--active')}
type="button">
<Icon {...icon} render={icon.render} />
</button>
{:else}
<!-- <button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
</button> -->
<button
aria-label={type}
class={cx('--header__action', linkIsActive && '--header__action--active')}
type="button">
<Icon {...icon} render={icon.render} />
</button>
{/if}
{#if linkIsActive}
<div class="bx--header-panel bx--header-panel--expanded" transition:slide="{{duration: 200}}">
<ul class="bx--switcher__item">
<li class="bx--switcher__item">
<a class="bx--switcher__item-link bx--switcher__item-link--selected" href="/">Link</a>
</li>
<li class="bx--switcher__item">
<a class="bx--switcher__item-link" href="/">Link</a>
</li>
<li class="bx--switcher__item">
<a class="bx--switcher__item-link" href="/">Link</a>
</li>
<li class="bx--switcher__item">
<a class="bx--switcher__item-link" href="/">Link</a>
</li>
<li class="bx--switcher__item">
<a class="bx--switcher__item-link" href="/">Link</a>
</li>
<li class="bx--switcher__item">
<a class="bx--switcher__item-link" href="/">Link</a>
</li>
</ul>
</div>
{/if}

View file

@ -1,36 +1,136 @@
<script>
export let action = undefined;
// export let type = undefined;
export let icon = undefined;
// export let content = undefined;
export let searchIsActive = undefined;
// import { onMount } from 'svelte';
import { createEventDispatcher } from 'svelte';
import { cx } from '../../../lib';
import Search20 from 'carbon-icons-svelte/lib/Search20';
import Icon from '../../Icon/Icon.svelte';
import { leftPanelActions, closeIcon } from '../constants';
$: searchIconProps =
action === 'search'
? (searchIconProps = [
{
class: undefined,
skeleton: false,
render: Search20,
title: 'Search',
tabIndex: 0,
focusable: false,
style: undefined
// let searchIconProps = undefined;
let searchTabIndex = 0;
let closeTabIndex = -1;
const dispatch = createEventDispatcher();
if (!icon) {
const actionsArray = Object.entries(leftPanelActions);
for (const definedAction of actionsArray) {
for (const content of definedAction) {
if (typeof content === 'object') {
if (content.actionString === action) {
icon = content.iconProps;
}
])
: (searchIconProps = []);
}
}
}
}
$: if (searchIsActive) {
searchTabIndex = -1;
closeTabIndex = 0;
} else {
searchTabIndex = 0;
closeTabIndex = -1;
}
</script>
{#if action === 'search'}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...searchIconProps} render={searchIconProps[0].render} />
<style>
.search-wrapper {
display: flex;
flex-grow: 1;
border-bottom: 1px solid #393939;
}
.btn-search {
width: 3rem;
height: 100%;
padding: 0;
flex-shrink: 0;
opacity: 1;
transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
}
.btn-search-disabled {
border: none;
pointer-events: none;
}
.input-search {
font-size: 1rem;
font-weight: 400;
line-height: 1.375rem;
letter-spacing: 0;
color: #fff;
caret-color: #fff;
background-color: initial;
border: none;
outline: none;
width: 100%;
height: 3rem;
padding: 0;
transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
}
.input-hidden {
opacity: 0;
pointer-events: none;
}
.btn-clear {
width: 3rem;
height: 100%;
padding: 0;
flex-shrink: 0;
opacity: 1;
transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
}
.btn-clear:hover {
background-color: #4c4c4c;
}
.btn-clear-hidden {
opacity: 0;
}
</style>
<div
id="right-panel-action-search"
class="search-wrapper"
role="combobox"
aria-expanded={searchIsActive}>
<button
tabindex={searchTabIndex}
aria-label={action}
class={cx('--header__action')}
class:btn-search={true}
class:btn-search-disabled={searchIsActive}
on:click={() => dispatch('focusInputSearch')}
type="button">
<Icon {...icon} render={icon.render} />
</button>
{:else}
<button aria-label="Notifications" class={cx('--header__action')} type="button">
<Icon {...icon} render={icon[0].render} />
<input
type="text"
autocomplete="off"
tabindex={closeTabIndex}
class="input-search"
class:input-hidden={!searchIsActive}
placeholder="Search"
on:focus={() => dispatch('focusInputSearch')}
on:focusout={() => dispatch('focusOutInputSearch')} />
<button
id="right-panel-close-search"
tabindex={closeTabIndex}
class={cx('--header__action')}
class:btn-clear={true}
class:btn-clear-hidden={!searchIsActive}
type="button"
aria-label="Clear search">
<Icon {...closeIcon} render={closeIcon.render} />
</button>
{/if}
</div>

View file

@ -1,51 +1,46 @@
<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';
import ActionGeneric from './ActionGeneric.svelte';
import { leftPanelActions } from '../constants';
// let switcherAtLast = [];
// let renderSwitcher = false;
let orderedRightPanel = [];
let customActions = 1;
$: switcherAtLast = rightPanel.map((item, index, array) => {
if (item.action === 'switcher') {
if (index !== rightPanel.length) {
const newItem = array[index];
return newItem;
rightPanel.forEach((item, index) => {
orderedRightPanel[index] = undefined;
if (item.action) {
if (Object.keys(leftPanelActions).indexOf(item.action.charAt(0).toLowerCase() + item.action.slice(1)) === -1) {
orderedRightPanel[customActions] = rightPanel[index];
customActions += 1;
}
} else {
return undefined;
}
});
$: renderSwitcher = switcherAtLast ? true : false;
rightPanel.forEach((item, index) => {
if (item.action) {
if (item.action === leftPanelActions.search.actionString) {
orderedRightPanel[0] = rightPanel[index];
} else if (item.action === leftPanelActions.help.actionString) {
orderedRightPanel[customActions] = rightPanel[index];
} else if (item.action === leftPanelActions.notifications.actionString) {
orderedRightPanel[customActions + 1] = rightPanel[index];
} else if (item.action === leftPanelActions.account.actionString) {
orderedRightPanel[customActions + 2] = rightPanel[index];
} else if (item.action === leftPanelActions.switcher.actionString) {
orderedRightPanel[customActions + 3] = rightPanel[index];
}
}
});
onMount(()=>{
console.log(switcherAtLast);
console.log(renderSwitcher);
})
orderedRightPanel = orderedRightPanel.filter(item => {
return item;
});
</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 orderedRightPanel as action, index}
<ActionGeneric {action} />
{/each}
{#if renderSwitcher}
<ActionLink {...switcherAtLast} />
{/if}
</div>