platform/packages/ui/src/components/Panel.svelte
Alexander Platov 9c78dc8c9c
Update Panel. Fix editors. (#2450)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
2022-12-20 11:27:02 +07:00

188 lines
5.6 KiB
Svelte

<!--
// Copyright © 2022 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 } from 'svelte'
import { resizeObserver } from '../resize'
import Button from './Button.svelte'
import IconClose from './icons/Close.svelte'
import IconDetails from './icons/Details.svelte'
import IconScale from './icons/Scale.svelte'
import IconScaleFull from './icons/ScaleFull.svelte'
import IconMinWidth from './icons/MinWidth.svelte'
import IconMaxWidth from './icons/MaxWidth.svelte'
import Scroller from './Scroller.svelte'
import { deviceOptionsStore as deviceInfo } from '../../'
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 = false
export let allowClose = true
export let useMaxWidth: boolean | undefined = undefined
const dispatch = createEventDispatcher()
let asideFloat: boolean = false
let asideShown: boolean = true
let fullSize: boolean = false
$: twoRows = $deviceInfo.minWidth
let oldWidth = ''
let hideTimer: number | 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
}
} else if (panelWidth > 900) {
if (asideFloat) {
asideFloat = false
}
if (!asideShown) {
asideShown = true
}
}
}
afterUpdate(() => {
if (hideTimer) {
clearTimeout(hideTimer)
}
hideTimer = setTimeout(() => {
checkPanel()
}, 500)
})
</script>
<div
class="popupPanel"
use:resizeObserver={(element) => {
panelWidth = element.clientWidth
checkPanel()
}}
>
<div class="popupPanel-title__bordered {twoRows && !withoutTitle ? 'flex-col flex-no-shrink' : 'flex-row-center'}">
<div class="popupPanel-title {twoRows && !withoutTitle ? 'row-top' : 'row'}">
{#if allowClose}
<Button
icon={IconClose}
kind={'transparent'}
size={'medium'}
on:click={() => {
dispatch('close')
}}
/>
{/if}
{#if $$slots.navigator}<slot name="navigator" />{/if}
<div class="popupPanel-title__content">
{#if !twoRows && !withoutTitle}<slot name="title" />{/if}
</div>
<div class="buttons-group xsmall-gap">
<slot name="utils" />
{#if isFullSize || useMaxWidth !== undefined || ($$slots.aside && isAside)}
<div class="buttons-divider" />
{/if}
{#if $$slots.aside && isAside}
<Button
icon={IconDetails}
kind={'transparent'}
size={'medium'}
selected={asideShown}
on:click={() => {
asideShown = !asideShown
}}
/>
{/if}
{#if useMaxWidth !== undefined}
<Button
icon={useMaxWidth ? IconMaxWidth : IconMinWidth}
kind={'transparent'}
size={'medium'}
selected={useMaxWidth}
on:click={() => {
useMaxWidth = !useMaxWidth
dispatch('maxWidth', useMaxWidth)
}}
/>
{/if}
{#if isFullSize}
<Button
icon={fullSize ? IconScale : IconScaleFull}
kind={'transparent'}
size={'medium'}
selected={fullSize}
on:click={() => {
fullSize = !fullSize
dispatch('fullsize')
}}
/>
{/if}
</div>
</div>
{#if twoRows && !withoutTitle}
<div class="popupPanel-title row-bottom"><slot name="title" /></div>
{/if}
</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 main bottom-divider" class:max={useMaxWidth}>
<slot name="header" />
</div>
{/if}
<slot />
</div>
{/if}
{#if $$slots.aside && isAside && asideShown}
<div class="popupPanel-body__aside" class:float={asideFloat} class:shown={asideShown}>
<slot name="aside" />
</div>
{/if}
</div>
</div>