<!-- // Copyright © 2022, 2023 Hardcore Engineering Inc. // // Licensed under the Eclipse Public License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // limitations under the License. --> <script lang="ts"> import { afterUpdate, createEventDispatcher, onMount } from 'svelte' import { deviceOptionsStore as deviceInfo, Separator, defineSeparators, resizeObserver, Button, ButtonGroup, Scroller, panelSeparators, ButtonItem } from '../../' import IconClose from './icons/Close.svelte' import IconDetails from './icons/Details.svelte' import IconMaxWidth from './icons/MaxWidth.svelte' import IconMinWidth from './icons/MinWidth.svelte' import IconScale from './icons/Scale.svelte' import IconScaleFull from './icons/ScaleFull.svelte' export let innerWidth: number = 0 export let panelWidth: number = 0 export let isHeader: boolean = true export let isAside: boolean = true export let isFullSize: boolean = false export let withoutTitle: boolean = false export let floatAside: boolean = false export let allowClose: boolean = true export let embedded: boolean = false export let useMaxWidth: boolean | undefined = undefined export let customAside: ButtonItem[] | undefined = undefined export let selectedAside: string | boolean = customAside ? customAside[0].id : isAside export function getAside (): string | boolean { if (customAside) return selectedAside return asideShown } export function setAside (id: string | boolean): void { if (typeof id === 'string' && customAside) { const i = customAside.findIndex((as) => as.id === id) if (i === -1) return handleSelectAside({ detail: id }) } else { asideShown = id !== false hideAside = !asideShown if (id === false) selectedAside = false } } const dispatch = createEventDispatcher() let asideFloat: boolean = false let asideShown: boolean = selectedAside !== false let hideAside: boolean = !asideShown let fullSize: boolean = false let oldAside: string | boolean = selectedAside $: if (typeof selectedAside === 'string' && oldAside !== selectedAside) oldAside = selectedAside $: setAside(selectedAside) let oldWidth = '' let hideTimer: any | undefined const checkPanel = (): void => { const k = `${panelWidth}-${asideFloat}` if (oldWidth === k) { return } oldWidth = k if (floatAside) { asideFloat = true } else if (panelWidth <= 900 && !asideFloat) { asideFloat = true if (asideShown) { asideShown = false if (customAside) handleSelectAside({ detail: false }, false) } } else if (panelWidth > 900) { if (asideFloat) asideFloat = false if (!asideShown && !hideAside) { asideShown = true if (customAside) handleSelectAside({ detail: oldAside }, false) } } } afterUpdate(() => { if (hideTimer) { clearTimeout(hideTimer) } hideTimer = setTimeout(() => { checkPanel() }, 500) }) onMount(() => dispatch('open')) defineSeparators('panel-aside', panelSeparators) const handleAside = (): void => { asideShown = !asideShown hideAside = !asideShown } const handleSelectAside = (result: { detail: any }, sw: boolean = true): void => { selectedAside = result.detail if (sw) { asideShown = selectedAside !== false hideAside = !asideShown } dispatch('select', result.detail) } </script> <div class="popupPanel panel" class:embedded use:resizeObserver={(element) => { panelWidth = element.clientWidth checkPanel() }} > <div class="popupPanel-title" class:indent={allowClose}> {#if allowClose} <Button id={'btnPClose'} focusIndex={10001} icon={IconClose} iconProps={{ size: 'medium' }} kind={'icon'} on:click={() => { dispatch('close') }} /> <div class="antiHSpacer x2" /> {/if} <div class="popupPanel-title__content"> {#if !withoutTitle}<slot name="title" />{/if} </div> <slot name="pre-utils" /> <div class="flex-row-center ml-3"> <slot name="utils" /> {#if $$slots.aside && isAside} {#if customAside} <ButtonGroup items={customAside} props={{ kind: 'icon', iconProps: { size: 'medium' } }} bind:selected={selectedAside} on:select={handleSelectAside} /> {:else} <Button id={'btnPAside'} focusIndex={10008} icon={IconDetails} iconProps={{ size: 'medium', filled: asideShown }} kind={'icon'} selected={asideShown} on:click={handleAside} /> {/if} {/if} {#if useMaxWidth !== undefined} <Button focusIndex={10009} icon={useMaxWidth ? IconMaxWidth : IconMinWidth} iconProps={{ size: 'medium' }} kind={'icon'} selected={useMaxWidth} on:click={() => { useMaxWidth = !useMaxWidth dispatch('maxWidth', useMaxWidth) }} /> {/if} {#if isFullSize} <Button focusIndex={100010} icon={fullSize ? IconScale : IconScaleFull} iconProps={{ size: 'medium' }} kind={'icon'} selected={fullSize} on:click={() => { fullSize = !fullSize dispatch('fullsize') }} /> {/if} </div> <slot name="post-utils" /> </div> <div class="popupPanel-body {$deviceInfo.isMobile ? 'mobile' : 'main'}" class:asideShown> {#if $deviceInfo.isMobile} <Scroller horizontal padding={'.5rem .75rem'}> <div class="popupPanel-body__mobile" use:resizeObserver={(element) => { innerWidth = element.clientWidth }} > {#if $$slots.header && isHeader} <div class="popupPanel-body__header mobile bottom-divider" class:max={useMaxWidth}> <slot name="header" /> </div> {/if} <slot /> </div> </Scroller> {:else} <div class="popupPanel-body__main" use:resizeObserver={(element) => { innerWidth = element.clientWidth }} > {#if $$slots.header && isHeader} <div class="popupPanel-body__header-wrapper"> <div class="popupPanel-body__header main" class:max={useMaxWidth}> <slot name="header" /> </div> </div> {/if} <slot /> </div> {/if} {#if $$slots.aside && isAside && asideShown} <Separator name={'panel-aside'} float={asideFloat} index={0} /> <div class="popupPanel-body__aside" class:float={asideFloat} class:shown={asideShown}> <Separator name={'panel-aside'} float={asideFloat ? 'aside' : true} index={0} /> <div class="antiPanel-wrap__content"> <slot name="aside" /> </div> </div> {/if} </div> </div>