mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
finished right panel
This commit is contained in:
parent
75e217c03e
commit
260ec4b04d
7 changed files with 195 additions and 159 deletions
|
@ -0,0 +1,15 @@
|
||||||
|
<script>
|
||||||
|
import TextInput from '../TextInput/TextInput.svelte';
|
||||||
|
import Toggle from '../Toggle/Toggle.svelte';
|
||||||
|
import Button from '../Button/Button.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<label>Test Field</label>
|
||||||
|
<br><br>
|
||||||
|
<TextInput />
|
||||||
|
<br><br>
|
||||||
|
<Toggle labelText='Test toggler' />
|
||||||
|
<br><br>
|
||||||
|
<Button>
|
||||||
|
Test Button
|
||||||
|
</Button>
|
|
@ -4,7 +4,6 @@
|
||||||
import UIShell from './UIShell.svelte';
|
import UIShell from './UIShell.svelte';
|
||||||
import FormTest from './FormTest.svelte';
|
import FormTest from './FormTest.svelte';
|
||||||
import SettingsAdjust20 from 'carbon-icons-svelte/lib/SettingsAdjust20';
|
import SettingsAdjust20 from 'carbon-icons-svelte/lib/SettingsAdjust20';
|
||||||
// import Binoculars20 from 'carbon-icons-svelte/lib/Binoculars20'
|
|
||||||
import { leftPanelActions, leftPanelTypes } from './constants';
|
import { leftPanelActions, leftPanelTypes } from './constants';
|
||||||
import searchStore from './searchStore';
|
import searchStore from './searchStore';
|
||||||
|
|
||||||
|
@ -101,7 +100,7 @@
|
||||||
type: leftPanelTypes.links,
|
type: leftPanelTypes.links,
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
subjet: 'Notification subjet 1',
|
subject: 'Notification subject 1',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
href: '#',
|
href: '#',
|
||||||
|
@ -110,7 +109,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subjet: 'Notification subjet 2',
|
subject: 'Notification subject 2',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
href: '#',
|
href: '#',
|
||||||
|
@ -138,7 +137,7 @@
|
||||||
type: leftPanelTypes.links,
|
type: leftPanelTypes.links,
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
subjet: 'Switcher subjet 1',
|
subject: 'Switcher subject 1',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
href: '#',
|
href: '#',
|
||||||
|
@ -147,7 +146,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subjet: 'Switcher subjet 2',
|
subject: 'Switcher subject 2',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
href: '#',
|
href: '#',
|
||||||
|
@ -168,7 +167,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subjet: 'Switcher subjet 3',
|
subject: 'Switcher subject 3',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
href: '#',
|
href: '#',
|
||||||
|
@ -192,22 +191,6 @@
|
||||||
},
|
},
|
||||||
isVisible: true
|
isVisible: true
|
||||||
}
|
}
|
||||||
// {
|
|
||||||
// action: 'customsearch',
|
|
||||||
// type: leftPanelTypes.search,
|
|
||||||
// icon: [
|
|
||||||
// {
|
|
||||||
// class: undefined,
|
|
||||||
// skeleton: false,
|
|
||||||
// render: Binoculars20,
|
|
||||||
// title: 'binoculars',
|
|
||||||
// tabIndex: 0,
|
|
||||||
// focusable: false,
|
|
||||||
// style: undefined
|
|
||||||
// }
|
|
||||||
// ],
|
|
||||||
// isVisible: true
|
|
||||||
// }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function searchInStore(event) {
|
function searchInStore(event) {
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
<script>
|
<script>
|
||||||
// export let action = undefined;
|
|
||||||
export let type = undefined;
|
export let type = undefined;
|
||||||
export let icon = undefined;
|
export let icon = undefined;
|
||||||
// export let content = undefined;
|
export let content = undefined;
|
||||||
|
export let componentIsActive = undefined;
|
||||||
|
|
||||||
import { cx } from '../../../lib';
|
import { cx } from '../../../lib';
|
||||||
import Icon from '../../Icon/Icon.svelte';
|
import Icon from '../../Icon/Icon.svelte';
|
||||||
// import { leftPanelActions } from '../constants';
|
import { slide } from 'svelte/transition';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button aria-label={type} class={cx('--header__action')} type="button">
|
<style>
|
||||||
|
.component-form {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="right-panel-action-component">
|
||||||
|
<button
|
||||||
|
aria-label={type}
|
||||||
|
class={cx('--header__action', componentIsActive && '--header__action--active')}
|
||||||
|
type="button">
|
||||||
<Icon {...icon} render={icon[0].render} />
|
<Icon {...icon} render={icon[0].render} />
|
||||||
</button>
|
</button>
|
||||||
|
{#if componentIsActive}
|
||||||
|
<div
|
||||||
|
id="right-panel-action-component-form"
|
||||||
|
class={cx('--header-panel', '--header-panel--expanded')}
|
||||||
|
transition:slide={{ duration: 200 }}>
|
||||||
|
<div class="component-form">
|
||||||
|
<svelte:component this={content} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import ActionComponent from './ActionComponent.svelte';
|
import ActionComponent from './ActionComponent.svelte';
|
||||||
import ActionSearch from './ActionSearch.svelte';
|
import ActionSearch from './ActionSearch.svelte';
|
||||||
import { leftPanelTypes } from '../constants';
|
import { leftPanelTypes } from '../constants';
|
||||||
|
import { isChildOf } from '../helpers';
|
||||||
|
|
||||||
let typeComponent = undefined;
|
let typeComponent = undefined;
|
||||||
let componentIsActive = false;
|
let componentIsActive = false;
|
||||||
|
@ -16,12 +17,61 @@
|
||||||
let isSearchFocus = false;
|
let isSearchFocus = false;
|
||||||
|
|
||||||
window.addEventListener('mouseup', ({ target }) => {
|
window.addEventListener('mouseup', ({ target }) => {
|
||||||
checkForClicks(target, typeComponent, leftPanelTypes.component);
|
checkForClicksTypeComponent(target, typeComponent);
|
||||||
checkForClicksTypeSearch(target, typeSearch, leftPanelTypes.search);
|
checkForClicksTypeSearch(target, typeSearch);
|
||||||
checkForClicks(target, typeLink, leftPanelTypes.link);
|
checkForClicksTypeLink(target, typeLink);
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkForClicks(target, component, actionString) {
|
function checkForClicksTypeComponent(target, component) {
|
||||||
|
if (component && target) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
!isChildOf(target, 'right-panel-action-component') ||
|
||||||
|
!isChildOf(target, 'right-panel-action-component-form')
|
||||||
|
) {
|
||||||
|
if (component.contains(target) || target === component) {
|
||||||
|
componentIsActive = !componentIsActive;
|
||||||
|
} else {
|
||||||
|
if (componentIsActive) {
|
||||||
|
componentIsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (componentIsActive) {
|
||||||
|
componentIsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForClicksTypeSearch(target, component, actionString) {
|
||||||
|
if (component && target) {
|
||||||
|
try {
|
||||||
|
if (!isChildOf(target, 'right-panel-action-search')) {
|
||||||
|
if (component.contains(target) || target === component) {
|
||||||
|
searchIsActive = !searchIsActive;
|
||||||
|
} else {
|
||||||
|
if (searchIsActive) {
|
||||||
|
searchIsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!searchIsActive && target.id !== 'right-panel-close-search') {
|
||||||
|
searchIsActive = true;
|
||||||
|
} else if (searchIsActive && isChildOf(target, 'right-panel-close-search')) {
|
||||||
|
searchIsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (searchIsActive) {
|
||||||
|
searchIsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForClicksTypeLink(target, component, actionString) {
|
||||||
try {
|
try {
|
||||||
if (component && target) {
|
if (component && target) {
|
||||||
if (component.contains(target) || target === component) {
|
if (component.contains(target) || target === component) {
|
||||||
|
@ -44,88 +94,6 @@
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkForClicksTypeSearch(target, component, actionString) {
|
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -153,18 +121,15 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{#if action.type === leftPanelTypes.component}
|
|
||||||
{#if action.isVisible}
|
{#if action.isVisible}
|
||||||
|
{#if action.type === leftPanelTypes.component}
|
||||||
<div bind:this={typeComponent}>
|
<div bind:this={typeComponent}>
|
||||||
<ActionComponent
|
<ActionComponent
|
||||||
action={action.action}
|
|
||||||
icon={action.icon ? action.icon : undefined}
|
icon={action.icon ? action.icon : undefined}
|
||||||
content={action.content}
|
content={action.content}
|
||||||
bind:componentIsActive />
|
bind:componentIsActive />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
|
||||||
{:else if action.type === leftPanelTypes.search}
|
{:else if action.type === leftPanelTypes.search}
|
||||||
{#if action.isVisible}
|
|
||||||
<div
|
<div
|
||||||
bind:this={typeSearch}
|
bind:this={typeSearch}
|
||||||
class="search-wrapper"
|
class="search-wrapper"
|
||||||
|
@ -184,12 +149,11 @@
|
||||||
}}
|
}}
|
||||||
on:inputSearch />
|
on:inputSearch />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
|
||||||
{:else if action.type === leftPanelTypes.link || action.type === leftPanelTypes.links}
|
{:else if action.type === leftPanelTypes.link || action.type === leftPanelTypes.links}
|
||||||
{#if action.isVisible}
|
|
||||||
<div bind:this={typeLink}>
|
<div bind:this={typeLink}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
action={action.action}
|
action={action.action}
|
||||||
|
type={action.type}
|
||||||
icon={action.icon ? action.icon : undefined}
|
icon={action.icon ? action.icon : undefined}
|
||||||
content={action.content}
|
content={action.content}
|
||||||
bind:linkIsActive />
|
bind:linkIsActive />
|
||||||
|
|
|
@ -2,14 +2,20 @@
|
||||||
export let action = undefined;
|
export let action = undefined;
|
||||||
export let type = undefined;
|
export let type = undefined;
|
||||||
export let icon = undefined;
|
export let icon = undefined;
|
||||||
// export let content = undefined;
|
export let content = undefined;
|
||||||
export let linkIsActive = undefined;
|
export let linkIsActive = undefined;
|
||||||
|
|
||||||
import { cx } from '../../../lib';
|
import { cx } from '../../../lib';
|
||||||
import Icon from '../../Icon/Icon.svelte';
|
import Icon from '../../Icon/Icon.svelte';
|
||||||
import { leftPanelActions } from '../constants';
|
import { leftPanelActions, leftPanelTypes } from '../constants';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
|
|
||||||
|
let href = undefined;
|
||||||
|
|
||||||
|
if (type === leftPanelTypes.link) {
|
||||||
|
href = content.href;
|
||||||
|
}
|
||||||
|
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
const actionsArray = Object.entries(leftPanelActions);
|
const actionsArray = Object.entries(leftPanelActions);
|
||||||
|
|
||||||
|
@ -25,33 +31,63 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.action-link {
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-divider {
|
||||||
|
color: #c6c6c6;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
border-bottom: 1px solid #525252;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-color: rgb(82, 82, 82);
|
||||||
|
margin: 32px 1rem 8px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1rem;
|
||||||
|
letter-spacing: 0.32px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if type === leftPanelTypes.link}
|
||||||
|
<a
|
||||||
|
aria-label={type}
|
||||||
|
class={cx('--header__action', linkIsActive && '--header__action--active')}
|
||||||
|
class:action-link={true}
|
||||||
|
{href}>
|
||||||
|
<Icon {...icon} render={icon.render} />
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
<button
|
<button
|
||||||
aria-label={type}
|
aria-label={type}
|
||||||
class={cx('--header__action', linkIsActive && '--header__action--active')}
|
class={cx('--header__action', linkIsActive && '--header__action--active')}
|
||||||
type="button">
|
type="button">
|
||||||
<Icon {...icon} render={icon.render} />
|
<Icon {...icon} render={icon.render} />
|
||||||
</button>
|
</button>
|
||||||
{#if linkIsActive}
|
{#if linkIsActive && type === leftPanelTypes.links}
|
||||||
<div class="bx--header-panel bx--header-panel--expanded" transition:slide={{ duration: 200 }}>
|
<div
|
||||||
<ul class="bx--switcher__item">
|
class={cx('--header-panel', '--header-panel--expanded')}
|
||||||
<li class="bx--switcher__item">
|
transition:slide={{ duration: 200 }}>
|
||||||
<a class="bx--switcher__item-link bx--switcher__item-link--selected" href="/">Link</a>
|
<ul class={cx('--switcher__item')}>
|
||||||
|
{#each content as subject}
|
||||||
|
{#if subject.subject}
|
||||||
|
<li class={cx('--switcher__item')} class:subject-divider={true}>
|
||||||
|
<span>{subject.subject}</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="bx--switcher__item">
|
{/if}
|
||||||
<a class="bx--switcher__item-link" href="/">Link</a>
|
{#each subject.items as link}
|
||||||
</li>
|
<li class={cx('--switcher__item')}>
|
||||||
<li class="bx--switcher__item">
|
<a class={cx('--switcher__item-link')} href={link.href}>{link.text}</a>
|
||||||
<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>
|
||||||
|
{/each}
|
||||||
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
|
@ -38,10 +38,6 @@
|
||||||
dispatch('inputSearch', params);
|
dispatch('inputSearch', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearSearch() {
|
|
||||||
searchStore.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
$: if (!searchIsActive) {
|
$: if (!searchIsActive) {
|
||||||
try {
|
try {
|
||||||
inputSearchField.value = '';
|
inputSearchField.value = '';
|
||||||
|
@ -172,7 +168,7 @@
|
||||||
class:btn-clear-hidden={!searchIsActive}
|
class:btn-clear-hidden={!searchIsActive}
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Clear search"
|
aria-label="Clear search"
|
||||||
on:click={clearSearch}>
|
on:click={() => searchStore.clear()}>
|
||||||
<Icon {...closeIcon} render={closeIcon.render} />
|
<Icon {...closeIcon} render={closeIcon.render} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
21
src/components/UIShell/helpers.js
Normal file
21
src/components/UIShell/helpers.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export function isChildOf(target, parentId) {
|
||||||
|
if (target.id) {
|
||||||
|
if (target.id == parentId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.parentNode) {
|
||||||
|
if (target.parentNode.id) {
|
||||||
|
if (target.parentNode.id == parentId) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return isChildOf(target.parentNode, parentId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return isChildOf(target.parentNode, parentId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue