|
|
|
@ -2,17 +2,15 @@ |
|
|
|
import "@spectrum-css/picker/dist/index-vars.css" |
|
|
|
import "@spectrum-css/popover/dist/index-vars.css" |
|
|
|
import "@spectrum-css/menu/dist/index-vars.css" |
|
|
|
import { getContext } from "svelte" |
|
|
|
import SpectrumField from "./SpectrumField.svelte" |
|
|
|
|
|
|
|
export let field |
|
|
|
export let label |
|
|
|
export let placeholder |
|
|
|
|
|
|
|
// Register this field with its form |
|
|
|
const { formApi } = getContext("form") ?? {} |
|
|
|
const formField = formApi?.registerField(field) ?? {} |
|
|
|
const { fieldApi, fieldState, fieldSchema } = formField |
|
|
|
let fieldState |
|
|
|
let fieldApi |
|
|
|
let fieldSchema |
|
|
|
|
|
|
|
// Picker state |
|
|
|
let open = false |
|
|
|
@ -20,68 +18,52 @@ |
|
|
|
$: placeholderText = placeholder || "Choose an option" |
|
|
|
$: isNull = $fieldState?.value == null || $fieldState?.value === "" |
|
|
|
|
|
|
|
// Update value on blur only |
|
|
|
const selectOption = value => { |
|
|
|
fieldApi.setValue(value) |
|
|
|
open = false |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<SpectrumField {field} {label}> |
|
|
|
<button |
|
|
|
id={$fieldState.fieldId} |
|
|
|
class="spectrum-Picker" |
|
|
|
class:is-invalid={!$fieldState.valid} |
|
|
|
class:is-open={open} |
|
|
|
aria-haspopup="listbox" |
|
|
|
on:click={() => (open = true)}> |
|
|
|
<span class="spectrum-Picker-label" class:is-placeholder={isNull}> |
|
|
|
{isNull ? placeholderText : $fieldState.value} |
|
|
|
</span> |
|
|
|
{#if !$fieldState.valid} |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon" |
|
|
|
focusable="false" |
|
|
|
aria-hidden="true" |
|
|
|
aria-label="Folder"> |
|
|
|
<use xlink:href="#spectrum-icon-18-Alert" /> |
|
|
|
</svg> |
|
|
|
{/if} |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon" |
|
|
|
focusable="false" |
|
|
|
aria-hidden="true"> |
|
|
|
<use xlink:href="#spectrum-css-icon-Chevron100" /> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
<div |
|
|
|
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover" |
|
|
|
class:is-open={open}> |
|
|
|
<ul class="spectrum-Menu" role="listbox"> |
|
|
|
<li |
|
|
|
class="spectrum-Menu-item" |
|
|
|
class:is-selected={isNull} |
|
|
|
role="option" |
|
|
|
aria-selected="true" |
|
|
|
tabindex="0" |
|
|
|
on:click={() => selectOption(null)}> |
|
|
|
<span class="spectrum-Menu-itemLabel">{placeholderText}</span> |
|
|
|
<SpectrumField {field} {label} bind:fieldState bind:fieldApi bind:fieldSchema> |
|
|
|
{#if fieldState} |
|
|
|
<button |
|
|
|
id={$fieldState.fieldId} |
|
|
|
class="spectrum-Picker" |
|
|
|
class:is-invalid={!$fieldState.valid} |
|
|
|
class:is-open={open} |
|
|
|
aria-haspopup="listbox" |
|
|
|
on:click={() => (open = true)}> |
|
|
|
<span class="spectrum-Picker-label" class:is-placeholder={isNull}> |
|
|
|
{isNull ? placeholderText : $fieldState.value} |
|
|
|
</span> |
|
|
|
{#if !$fieldState.valid} |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" |
|
|
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon" |
|
|
|
focusable="false" |
|
|
|
aria-hidden="true"> |
|
|
|
<use xlink:href="#spectrum-css-icon-Checkmark100" /> |
|
|
|
aria-hidden="true" |
|
|
|
aria-label="Folder"> |
|
|
|
<use xlink:href="#spectrum-icon-18-Alert" /> |
|
|
|
</svg> |
|
|
|
</li> |
|
|
|
{#each options as option} |
|
|
|
{/if} |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon" |
|
|
|
focusable="false" |
|
|
|
aria-hidden="true"> |
|
|
|
<use xlink:href="#spectrum-css-icon-Chevron100" /> |
|
|
|
</svg> |
|
|
|
</button> |
|
|
|
<div |
|
|
|
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover" |
|
|
|
class:is-open={open}> |
|
|
|
<ul class="spectrum-Menu" role="listbox"> |
|
|
|
<li |
|
|
|
class="spectrum-Menu-item" |
|
|
|
class:is-selected={option === $fieldState.value} |
|
|
|
class:is-selected={isNull} |
|
|
|
role="option" |
|
|
|
aria-selected="true" |
|
|
|
tabindex="0" |
|
|
|
on:click={() => selectOption(option)}> |
|
|
|
<span class="spectrum-Menu-itemLabel">{option}</span> |
|
|
|
on:click={() => selectOption(null)}> |
|
|
|
<span class="spectrum-Menu-itemLabel">{placeholderText}</span> |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" |
|
|
|
focusable="false" |
|
|
|
@ -89,7 +71,24 @@ |
|
|
|
<use xlink:href="#spectrum-css-icon-Checkmark100" /> |
|
|
|
</svg> |
|
|
|
</li> |
|
|
|
{/each} |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
{#each options as option} |
|
|
|
<li |
|
|
|
class="spectrum-Menu-item" |
|
|
|
class:is-selected={option === $fieldState.value} |
|
|
|
role="option" |
|
|
|
aria-selected="true" |
|
|
|
tabindex="0" |
|
|
|
on:click={() => selectOption(option)}> |
|
|
|
<span class="spectrum-Menu-itemLabel">{option}</span> |
|
|
|
<svg |
|
|
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" |
|
|
|
focusable="false" |
|
|
|
aria-hidden="true"> |
|
|
|
<use xlink:href="#spectrum-css-icon-Checkmark100" /> |
|
|
|
</svg> |
|
|
|
</li> |
|
|
|
{/each} |
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
{/if} |
|
|
|
</SpectrumField> |
|
|
|
|