2021-01-28 19:53:40 +01:00
|
|
|
<script>
|
|
|
|
import Flatpickr from "svelte-flatpickr"
|
2021-02-05 11:53:25 +01:00
|
|
|
import Field from "./Field.svelte"
|
2021-01-28 19:53:40 +01:00
|
|
|
import "flatpickr/dist/flatpickr.css"
|
|
|
|
import "@spectrum-css/inputgroup/dist/index-vars.css"
|
2021-02-10 20:23:53 +01:00
|
|
|
import { generateID } from "../helpers"
|
2021-01-28 19:53:40 +01:00
|
|
|
|
|
|
|
export let field
|
|
|
|
export let label
|
|
|
|
export let placeholder
|
2021-01-29 11:18:41 +01:00
|
|
|
export let enableTime
|
2021-02-17 16:16:44 +01:00
|
|
|
export let disabled = false
|
2021-01-28 19:53:40 +01:00
|
|
|
|
|
|
|
let fieldState
|
|
|
|
let fieldApi
|
2021-01-29 11:18:41 +01:00
|
|
|
let open = false
|
|
|
|
let flatpickr
|
|
|
|
|
2021-02-10 20:23:53 +01:00
|
|
|
$: flatpickrId = `${$fieldState?.id}-${generateID()}-wrapper`
|
2021-01-28 20:41:46 +01:00
|
|
|
$: flatpickrOptions = {
|
2021-02-10 20:23:53 +01:00
|
|
|
element: `#${flatpickrId}`,
|
2021-01-29 11:18:41 +01:00
|
|
|
enableTime: enableTime || false,
|
2021-01-28 20:41:46 +01:00
|
|
|
altInput: true,
|
2021-01-29 11:18:41 +01:00
|
|
|
altFormat: enableTime ? "F j Y, H:i" : "F j, Y",
|
2021-01-28 20:41:46 +01:00
|
|
|
}
|
2021-01-28 19:53:40 +01:00
|
|
|
|
|
|
|
const handleChange = event => {
|
2021-01-29 11:18:41 +01:00
|
|
|
const [dates] = event.detail
|
|
|
|
fieldApi.setValue(dates[0])
|
|
|
|
}
|
|
|
|
|
2021-02-03 12:10:47 +01:00
|
|
|
const clearDateOnBackspace = event => {
|
|
|
|
if (["Backspace", "Clear", "Delete"].includes(event.key)) {
|
|
|
|
fieldApi.setValue(null)
|
|
|
|
flatpickr.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-29 11:18:41 +01:00
|
|
|
const onOpen = () => {
|
|
|
|
open = true
|
2021-02-03 12:10:47 +01:00
|
|
|
document.addEventListener("keyup", clearDateOnBackspace)
|
2021-01-29 11:18:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const onClose = () => {
|
|
|
|
open = false
|
2021-02-03 12:10:47 +01:00
|
|
|
document.removeEventListener("keyup", clearDateOnBackspace)
|
2021-01-29 11:18:41 +01:00
|
|
|
|
|
|
|
// Manually blur all input fields since flatpickr creates a second
|
|
|
|
// duplicate input field.
|
|
|
|
// We need to blur both because the focus styling does not get properly
|
|
|
|
// applied.
|
2021-02-10 20:23:53 +01:00
|
|
|
const els = document.querySelectorAll(`#${flatpickrId} input`)
|
2021-01-29 11:18:41 +01:00
|
|
|
els.forEach(el => el.blur())
|
2021-01-28 19:53:40 +01:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2021-02-17 16:16:44 +01:00
|
|
|
<Field {label} {field} {disabled} type="datetime" bind:fieldState bind:fieldApi>
|
2021-01-28 19:53:40 +01:00
|
|
|
{#if fieldState}
|
|
|
|
<Flatpickr
|
2021-01-29 11:18:41 +01:00
|
|
|
bind:flatpickr
|
|
|
|
value={$fieldState.value}
|
|
|
|
on:open={onOpen}
|
|
|
|
on:close={onClose}
|
2021-01-28 20:41:46 +01:00
|
|
|
options={flatpickrOptions}
|
2021-01-28 19:53:40 +01:00
|
|
|
on:change={handleChange}
|
2021-02-10 20:23:53 +01:00
|
|
|
element={`#${flatpickrId}`}>
|
2021-01-28 19:53:40 +01:00
|
|
|
<div
|
2021-02-10 20:23:53 +01:00
|
|
|
id={flatpickrId}
|
2021-01-28 19:53:40 +01:00
|
|
|
aria-disabled="false"
|
2021-02-01 20:01:43 +01:00
|
|
|
aria-invalid={!$fieldState.valid}
|
2021-02-17 16:16:44 +01:00
|
|
|
class:is-disabled={$fieldState.disabled}
|
2021-02-01 20:01:43 +01:00
|
|
|
class:is-invalid={!$fieldState.valid}
|
2021-01-28 19:53:40 +01:00
|
|
|
class="flatpickr spectrum-InputGroup spectrum-Datepicker"
|
2021-01-29 11:18:41 +01:00
|
|
|
class:is-focused={open}
|
2021-01-28 19:53:40 +01:00
|
|
|
aria-readonly="false"
|
|
|
|
aria-required="false"
|
|
|
|
aria-haspopup="true">
|
2021-02-01 15:10:55 +01:00
|
|
|
<div
|
|
|
|
on:click={flatpickr?.open}
|
2021-02-01 20:01:43 +01:00
|
|
|
class="spectrum-Textfield spectrum-InputGroup-textfield"
|
2021-02-17 16:16:44 +01:00
|
|
|
class:is-disabled={$fieldState.disabled}
|
2021-02-01 20:01:43 +01:00
|
|
|
class:is-invalid={!$fieldState.valid}>
|
|
|
|
{#if !$fieldState.valid}
|
|
|
|
<svg
|
|
|
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
|
|
|
focusable="false"
|
|
|
|
aria-hidden="true">
|
|
|
|
<use xlink:href="#spectrum-icon-18-Alert" />
|
|
|
|
</svg>
|
|
|
|
{/if}
|
2021-01-28 19:53:40 +01:00
|
|
|
<input
|
|
|
|
data-input
|
|
|
|
type="text"
|
2021-02-17 16:16:44 +01:00
|
|
|
disabled={$fieldState.disabled}
|
2021-01-28 19:53:40 +01:00
|
|
|
class="spectrum-Textfield-input spectrum-InputGroup-input"
|
2021-02-01 20:01:43 +01:00
|
|
|
aria-invalid={!$fieldState.valid}
|
2021-01-28 19:53:40 +01:00
|
|
|
{placeholder}
|
2021-02-01 15:10:55 +01:00
|
|
|
id={$fieldState.fieldId}
|
2021-01-28 20:41:46 +01:00
|
|
|
value={$fieldState.value} />
|
2021-01-28 19:53:40 +01:00
|
|
|
</div>
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="spectrum-Picker spectrum-InputGroup-button"
|
2021-01-29 11:18:41 +01:00
|
|
|
tabindex="-1"
|
2021-02-17 16:16:44 +01:00
|
|
|
disabled={$fieldState.disabled}
|
2021-02-01 20:01:43 +01:00
|
|
|
class:is-invalid={!$fieldState.valid}
|
2021-01-29 11:18:41 +01:00
|
|
|
on:click={flatpickr?.open}>
|
2021-01-28 19:53:40 +01:00
|
|
|
<svg
|
|
|
|
class="spectrum-Icon spectrum-Icon--sizeM"
|
|
|
|
focusable="false"
|
|
|
|
aria-hidden="true"
|
|
|
|
aria-label="Calendar">
|
|
|
|
<use xlink:href="#spectrum-icon-18-Calendar" />
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</Flatpickr>
|
2021-02-01 15:10:55 +01:00
|
|
|
{#if open}
|
|
|
|
<div class="overlay" on:mousedown|self={flatpickr?.close} />
|
|
|
|
{/if}
|
2021-01-28 19:53:40 +01:00
|
|
|
{/if}
|
2021-02-05 11:53:25 +01:00
|
|
|
</Field>
|
2021-01-28 19:53:40 +01:00
|
|
|
|
|
|
|
<style>
|
2021-02-01 15:10:55 +01:00
|
|
|
.spectrum-Textfield-input {
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
2021-02-17 16:16:44 +01:00
|
|
|
.spectrum-Textfield:not(.is-disabled):hover {
|
2021-02-01 15:10:55 +01:00
|
|
|
cursor: pointer;
|
|
|
|
}
|
2021-01-28 19:53:40 +01:00
|
|
|
.flatpickr {
|
2021-02-10 20:23:53 +01:00
|
|
|
width: 100%;
|
2021-02-01 20:01:43 +01:00
|
|
|
overflow: hidden;
|
2021-01-28 19:53:40 +01:00
|
|
|
}
|
|
|
|
.flatpickr .spectrum-Textfield {
|
2021-02-10 20:23:53 +01:00
|
|
|
width: 100%;
|
2021-01-28 19:53:40 +01:00
|
|
|
}
|
2021-02-01 15:10:55 +01:00
|
|
|
.overlay {
|
|
|
|
position: fixed;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100vw;
|
|
|
|
height: 100vh;
|
|
|
|
z-index: 999;
|
|
|
|
}
|
2021-01-28 19:53:40 +01:00
|
|
|
</style>
|