mirror of
https://github.com/hcengineering/platform.git
synced 2025-03-31 12:38:27 +00:00
188 lines
5.6 KiB
Svelte
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>
|