DatePicker rework (#737)

* fix(date-picker): append calendar to date picker element #345

Fixes #345

* fix(date-picker): do not import rangePlugin from esm folder

* fix(date-picker): correctly type change event for single/range types

* feat(date-picker): add valueFrom, valueTo for range datepicker

* docs(date-picker): add range type example

* docs(date-picker): extract range example to iframe

* docs(date-picker): extract single type to iframe
This commit is contained in:
Eric Liu 2021-07-08 16:33:03 -07:00 committed by GitHub
commit edefd6429b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 139 additions and 56 deletions

View file

@ -1,6 +1,6 @@
<script>
/**
* @dispatch {string} change
* @event {string | { selectedDates: [dateFrom: Date, dateTo?: Date]; dateStr: string | { from: string; to: string; } }} change
*/
/**
@ -16,10 +16,18 @@
export let value = "";
/**
* Specify the element to append the calendar to
* @type {HTMLElement}
* Specify the date picker start date value (from)
* Only works with the "range" date picker type
* @type {string}
*/
export let appendTo = document.body;
export let valueFrom = "";
/**
* Specify the date picker end date value (to)
* Only works with the "range" date picker type
* @type {string}
*/
export let valueTo = "";
/** Specify the date format */
export let dateFormat = "m/d/Y";
@ -65,18 +73,23 @@
(_) => _.filter(({ labelText }) => !!labelText).length === 0
);
const inputValue = writable(value);
const inputValueFrom = writable(valueFrom);
const inputValueTo = writable(valueTo);
const mode = writable(datePickerType);
const range = derived(mode, (_) => _ === "range");
const hasCalendar = derived(mode, (_) => _ === "single" || _ === "range");
let calendar = undefined;
let datePickerRef = undefined;
let inputRef = undefined;
let inputRefTo = undefined;
let calendar = null;
let datePickerRef = null;
let inputRef = null;
let inputRefTo = null;
setContext("DatePicker", {
range,
inputValue,
inputValueFrom,
inputValueTo,
inputIds,
hasCalendar,
add: (data) => {
inputs.update((_) => [..._, data]);
@ -119,7 +132,7 @@
if ($hasCalendar && !calendar) {
calendar = createCalendar({
options: {
appendTo,
appendTo: datePickerRef,
dateFormat,
defaultDate: $inputValue,
locale,
@ -133,10 +146,16 @@
const detail = { selectedDates: calendar.selectedDates };
if ($range) {
const from = inputRef.value;
const to = inputRefTo.value;
detail.dateStr = {
from: inputRef.value,
to: inputRefTo.value,
};
valueFrom = from;
valueTo = to;
} else {
detail.dateStr = inputRef.value;
}
@ -146,8 +165,15 @@
});
}
if (calendar && !$range) {
calendar.setDate($inputValue);
if (calendar) {
if ($range) {
calendar.setDate([$inputValueFrom, $inputValueTo]);
// workaround to remove the default range plugin separator "to"
inputRef.value = $inputValueFrom;
} else {
calendar.setDate($inputValue);
}
}
});
@ -159,19 +185,17 @@
$: inputValue.set(value);
$: value = $inputValue;
$: inputValueFrom.set(valueFrom);
$: valueFrom = $inputValueFrom;
$: inputValueTo.set(valueTo);
$: valueTo = $inputValueTo;
</script>
<svelte:body
on:click="{({ target }) => {
if (!calendar || !calendar.isOpen) {
return;
}
if (datePickerRef && datePickerRef.contains(target)) {
return;
}
if (!calendar.calendarContainer.contains(target)) {
calendar.close();
}
if (!calendar || !calendar.isOpen) return;
if (datePickerRef && datePickerRef.contains(target)) return;
if (!calendar.calendarContainer.contains(target)) calendar.close();
}}" />
<div

View file

@ -60,11 +60,14 @@
add,
hasCalendar,
declareRef,
inputIds,
updateValue,
blurInput,
openCalendar,
focusCalendar,
inputValue,
inputValueFrom,
inputValueTo,
} = getContext("DatePicker");
add({ id, labelText });
@ -105,7 +108,11 @@
pattern="{pattern}"
disabled="{disabled}"
{...$$restProps}
value="{!$range ? $inputValue : undefined}"
value="{$range
? $inputIds.indexOf(id) === 0
? $inputValueFrom
: $inputValueTo
: $inputValue}"
class:bx--date-picker__input="{true}"
class:bx--date-picker__input--invalid="{invalid}"
class="{size && `bx--date-picker__input--${size}`}"

View file

@ -1,5 +1,5 @@
import flatpickr from "flatpickr";
import rangePlugin from "flatpickr/dist/esm/plugins/rangePlugin";
import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
let l10n;