Files

140 lines
3.8 KiB
Svelte
Raw Permalink Normal View History

<script>
import {createEventDispatcher, getContext, hasContext} from "svelte";
import {writable} from "svelte/store";
import {fade} from "svelte/transition";
import {link} from "svelte-spa-router";
import {defined_settings, strings} from "../js/stores";
import PanelContainer from "./PanelContainer.svelte";
import PanelRow from "./PanelRow.svelte";
import DefinedInWPConfig from "./DefinedInWPConfig.svelte";
import ToggleSwitch from "./ToggleSwitch.svelte";
import HelpButton from "./HelpButton.svelte";
import Button from "./Button.svelte";
const classes = $$props.class ? $$props.class : "";
const dispatch = createEventDispatcher();
export let ref = {};
export let name = "";
export let heading = "";
export let defined = false;
export let multi = false;
export let flyout = false;
export let toggleName = "";
export let toggle = false;
export let refresh = false;
export let refreshText = $strings.refresh_title;
export let refreshDesc = refreshText;
export let refreshing = false;
export let helpKey = "";
export let helpURL = "";
export let helpDesc = $strings.help_desc;
// We can display storage provider info on the right-hand side of the panel's header.
// In the future, if anything else needs to be displayed in the same position we
// should create a named slot or assignable component. CSS changes would be required.
export let storageProvider = null;
// Parent page may want to be locked.
let settingsLocked = writable( false );
if ( hasContext( "settingsLocked" ) ) {
settingsLocked = getContext( "settingsLocked" );
}
$: locked = $settingsLocked;
$: toggleDisabled = $defined_settings.includes( toggleName ) || locked;
/**
* If appropriate, clicking the header toggles to toggle switch.
*/
function headingClickHandler() {
if ( toggleName && !toggleDisabled ) {
toggle = !toggle;
}
}
/**
* Catch escape key and emit a custom cancel event.
*
* @param {KeyboardEvent} event
*/
function handleKeyup( event ) {
if ( event.key === "Escape" ) {
event.preventDefault();
dispatch( "cancel" );
}
}
</script>
<!-- TODO: Fix a11y. -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="panel {name}"
class:multi
class:flyout
class:locked
transition:fade={{duration: flyout ? 200 : 0}}
bind:this={ref}
on:focusout
on:mouseenter
on:mouseleave
on:mousedown
on:click
on:keyup={handleKeyup}
>
{#if !multi && heading}
<div class="heading">
<h2>{heading}</h2>
{#if helpURL}
<HelpButton url={helpURL} desc={helpDesc}/>
{:else if helpKey}
<HelpButton key={helpKey} desc={helpDesc}/>
{/if}
<DefinedInWPConfig {defined}/>
</div>
{/if}
<PanelContainer class={classes}>
{#if multi && heading}
<PanelRow header>
{#if toggleName}
<ToggleSwitch name={toggleName} bind:checked={toggle} disabled={toggleDisabled}>
{heading}
</ToggleSwitch>
<!-- TODO: Fix a11y. -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<h3 on:click={headingClickHandler} class="toggler" class:toggleDisabled>{heading}</h3>
{:else}
<h3>{heading}</h3>
{/if}
<DefinedInWPConfig {defined}/>
{#if refresh}
<Button refresh {refreshing} title={refreshDesc} on:click={() => dispatch("refresh")}>{@html refreshText}</Button>
{/if}
{#if storageProvider}
<div class="provider">
<a href="/storage/provider" use:link class="link">
<img src={storageProvider.link_icon} alt={storageProvider.icon_desc}>
{storageProvider.provider_service_name}
</a>
</div>
{/if}
{#if helpURL}
<HelpButton url={helpURL} desc={helpDesc}/>
{:else if helpKey}
<HelpButton key={helpKey} desc={helpDesc}/>
{/if}
</PanelRow>
{/if}
<slot/>
</PanelContainer>
</div>
<style>
.toggler:not(.toggleDisabled) {
cursor: pointer;
}
</style>