@schedule-x/date-picker
Advanced tools
Comparing version 0.1.0-alpha.1 to 0.1.0-alpha.2
@@ -49,5 +49,5 @@ 'use strict'; | ||
}; | ||
const toLocalizedDate = (date, locale) => { | ||
const toLocalizedDateString = (date, locale) => { | ||
return date.toLocaleString(locale, { | ||
month: 'long', | ||
month: 'numeric', | ||
day: 'numeric', | ||
@@ -63,3 +63,3 @@ year: 'numeric', | ||
var chevronIcon$1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#DED8E1\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img$1 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='%23DED8E1' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -69,7 +69,8 @@ function AppInput() { | ||
const getLocalizedDate = (dateString) => { | ||
return toLocalizedDate(toJSDate(dateString), $app.config.locale); | ||
if (dateString === '') | ||
return $app.translate('MM/DD/YYYY'); | ||
return toLocalizedDateString(toJSDate(dateString), $app.config.locale); | ||
}; | ||
const [displayedValue, setDisplayedValue] = h$2(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
p$2(() => { | ||
setDisplayedValue(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
$app.datePickerState.inputDisplayedValue.value = getLocalizedDate($app.datePickerState.selectedDate.value); | ||
}, [$app.datePickerState.selectedDate.value]); | ||
@@ -83,3 +84,25 @@ const [wrapperClasses, setWrapperClasses] = h$2([]); | ||
}, [$app.datePickerState.isOpen.value]); | ||
return (o$2(preact.Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: "Date" }), o$2("input", { value: displayedValue, "data-testid": "date-picker-input", readonly: true, class: "sx__date-input", onClick: () => $app.datePickerState.toggle(), type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: chevronIcon$1, alt: "" })] }) })); | ||
const handleKeyUp = (event) => { | ||
if (event.key === 'Enter') | ||
handleInputValue(event); | ||
}; | ||
const handleInputValue = (event) => { | ||
event.stopPropagation(); // prevent date picker from closing | ||
try { | ||
$app.datePickerState.inputDisplayedValue.value = event.target.value; | ||
$app.datePickerState.close(); | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}; | ||
p$2(() => { | ||
document.addEventListener('change', handleInputValue); // Preact onChange triggers on every input | ||
return () => document.removeEventListener('change', handleInputValue); | ||
}); | ||
const handleClick = (event) => { | ||
handleInputValue(event); | ||
$app.datePickerState.open(); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: $app.translate('Date') }), o$2("input", { value: $app.datePickerState.inputDisplayedValue.value, "data-testid": "date-picker-input", class: "sx__date-input", onClick: handleClick, onKeyUp: handleKeyUp, type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: img$1, alt: "" })] }) })); | ||
} | ||
@@ -115,3 +138,3 @@ | ||
const toDateString = (date) => { | ||
const toDateString$1 = (date) => { | ||
return `${date.getFullYear()}-${doubleDigit(date.getMonth() + 1)}-${doubleDigit(date.getDate())}`; | ||
@@ -123,3 +146,3 @@ }; | ||
const toDateTimeString = (date) => { | ||
return `${toDateString(date)} ${toTimeString(date)}`; | ||
return `${toDateString$1(date)} ${toTimeString(date)}`; | ||
}; | ||
@@ -135,3 +158,3 @@ | ||
} | ||
return toDateString(jsDate); | ||
return toDateString$1(jsDate); | ||
}; | ||
@@ -157,3 +180,3 @@ | ||
var chevronIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#000\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -182,3 +205,7 @@ function MonthViewHeader({ setYearsView }) { | ||
}, [$app.datePickerState.datePickerDate.value]); | ||
return (o$2(preact.Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: chevronIcon, alt: "previous month" }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: () => setYearsView(), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: chevronIcon, alt: "next month" }) })] }) })); | ||
const handleOpenYearsView = (e) => { | ||
e.stopPropagation(); | ||
setYearsView(); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: img, alt: $app.translate('Previous month') }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: (event) => handleOpenYearsView(event), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: img, alt: $app.translate('Next month') }) })] }) })); | ||
} | ||
@@ -188,3 +215,3 @@ | ||
const $app = q$1(AppContext); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.selectedDate.value)); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.datePickerDate.value)); | ||
const dayNames = getOneLetterDayNames(aWeek, $app.config.locale); | ||
@@ -200,2 +227,6 @@ return (o$2("div", { class: "sx__date-picker__day-names", children: dayNames.map((dayName) => (o$2("span", { "data-testid": "day-name", class: "sx__date-picker__day-name", children: dayName }))) })); | ||
}; | ||
const isSameMonth = (date1, date2) => { | ||
return (date1.getMonth() === date2.getMonth() && | ||
date1.getFullYear() === date2.getFullYear()); | ||
}; | ||
@@ -208,4 +239,6 @@ function MonthViewWeek({ week }) { | ||
classes.push('sx__date-picker__day--today'); | ||
if (toDateString(day) === $app.datePickerState.selectedDate.value) | ||
if (toDateString$1(day) === $app.datePickerState.selectedDate.value) | ||
classes.push('sx__date-picker__day--selected'); | ||
if (!isSameMonth(day, toJSDate($app.datePickerState.datePickerDate.value))) | ||
classes.push('is-leading-or-trailing'); | ||
return { | ||
@@ -217,7 +250,7 @@ day, | ||
const isDateSelectable = (date) => { | ||
const dateString = toDateString(date); | ||
const dateString = toDateString$1(date); | ||
return dateString >= $app.config.min && dateString <= $app.config.max; | ||
}; | ||
const selectDate = (date) => { | ||
$app.datePickerState.selectedDate.value = toDateString(date); | ||
$app.datePickerState.selectedDate.value = toDateString$1(date); | ||
$app.datePickerState.close(); | ||
@@ -244,3 +277,7 @@ }; | ||
const yearWithDates = $app.timeUnitsImpl.getMonthsFor(year); | ||
return (o$2(preact.Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: () => setYearAndMonth(year, month.getMonth()), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
const handleClickOnMonth = (event, month) => { | ||
event.stopPropagation(); | ||
setYearAndMonth(year, month.getMonth()); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: (event) => handleClickOnMonth(event, month), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
} | ||
@@ -255,3 +292,3 @@ | ||
const setNewDatePickerDate = (year, month) => { | ||
$app.datePickerState.datePickerDate.value = toDateString(new Date(year, month, 1)); | ||
$app.datePickerState.datePickerDate.value = toDateString$1(new Date(year, month, 1)); | ||
setMonthView(); | ||
@@ -272,5 +309,17 @@ }; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
function AppPopup() { | ||
const $app = q$1(AppContext); | ||
const [datePickerView, setDatePickerView] = h$2(DatePickerView.MONTH_DAYS); | ||
return (o$2(preact.Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: "sx__date-picker-popup", children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
const popupClasses = [POPUP_CLASS_NAME, $app.config.placement]; | ||
const clickOutsideListener = (event) => { | ||
const target = event.target; | ||
if (!target.closest(`.${POPUP_CLASS_NAME}`)) | ||
$app.datePickerState.close(); | ||
}; | ||
p$2(() => { | ||
document.addEventListener('click', clickOutsideListener); | ||
return () => document.removeEventListener('click', clickOutsideListener); | ||
}, []); | ||
return (o$2(preact.Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
} | ||
@@ -302,2 +351,8 @@ | ||
} | ||
get value() { | ||
return this.$app.datePickerState.selectedDate.value; | ||
} | ||
set value(value) { | ||
this.$app.datePickerState.selectedDate.value = value; | ||
} | ||
} | ||
@@ -440,12 +495,111 @@ | ||
const createDatePickerState = (selectedDateParam) => { | ||
const initialSelectedDate = selectedDateParam || | ||
(() => { | ||
const { year, month, date } = new ExtendedDateImpl(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()); | ||
return `${year}-${doubleDigit(month + 1)}-${doubleDigit(date)}`; | ||
})(); | ||
var DateFormatDelimiter; | ||
(function (DateFormatDelimiter) { | ||
DateFormatDelimiter["SLASH"] = "/"; | ||
DateFormatDelimiter["DASH"] = "-"; | ||
DateFormatDelimiter["PERIOD"] = "."; | ||
})(DateFormatDelimiter || (DateFormatDelimiter = {})); | ||
var DateFormatOrder; | ||
(function (DateFormatOrder) { | ||
DateFormatOrder["DMY"] = "DMY"; | ||
DateFormatOrder["MDY"] = "MDY"; | ||
DateFormatOrder["YMD"] = "YMD"; | ||
})(DateFormatOrder || (DateFormatOrder = {})); | ||
const formatRules = { | ||
slashMDY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.MDY, | ||
}, | ||
slashDMY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
periodDMY: { | ||
delimiter: DateFormatDelimiter.PERIOD, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
dashYMD: { | ||
delimiter: DateFormatDelimiter.DASH, | ||
order: DateFormatOrder.YMD, | ||
}, | ||
}; | ||
const dateFormatLocalizedRules = new Map([ | ||
['en-US', formatRules.slashMDY], | ||
['en-GB', formatRules.slashDMY], | ||
['de-DE', formatRules.periodDMY], | ||
['sv-SE', formatRules.dashYMD], | ||
]); | ||
class LocaleNotSupportedError extends Error { | ||
constructor(locale) { | ||
super(`Locale not supported: ${locale}`); | ||
} | ||
} | ||
class InvalidDateFormatError extends Error { | ||
constructor(dateFormat, locale) { | ||
super(`Invalid date format: ${dateFormat} for locale: ${locale}`); | ||
} | ||
} | ||
const _getMatchesOrThrow = (format, matcher, locale) => { | ||
const matches = format.match(matcher); | ||
if (!matches) | ||
throw new InvalidDateFormatError(format, locale); | ||
return matches; | ||
}; | ||
const toDateString = (format, locale) => { | ||
const internationalFormat = /^\d{4}-\d{2}-\d{2}$/; | ||
if (internationalFormat.test(format)) | ||
return format; // allow international format regardless of locale | ||
const localeDateFormatRule = dateFormatLocalizedRules.get(locale); | ||
if (!localeDateFormatRule) | ||
throw new LocaleNotSupportedError(locale); | ||
const { order, delimiter } = localeDateFormatRule; | ||
const pattern224Slashed = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/; | ||
const pattern224Dotted = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/; | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.MDY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, month, day, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.PERIOD) { | ||
const matches = _getMatchesOrThrow(format, pattern224Dotted, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
throw new InvalidDateFormatError(format, locale); | ||
}; | ||
const createDatePickerState = (config, selectedDateParam) => { | ||
const currentDayDateString = toDateString$1(new Date()); | ||
const initialSelectedDate = typeof selectedDateParam === 'string' | ||
? selectedDateParam | ||
: currentDayDateString; | ||
const isOpen = u(false); | ||
const datePickerView = u(DatePickerView.MONTH_DAYS); | ||
const selectedDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate || currentDayDateString); | ||
const inputDisplayedValue = u(selectedDateParam || ''); | ||
b(() => { | ||
try { | ||
const newValue = toDateString(inputDisplayedValue.value, config.locale); | ||
selectedDate.value = newValue; | ||
datePickerDate.value = newValue; | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}); | ||
b(() => { | ||
var _a; | ||
if ((_a = config.listeners) === null || _a === void 0 ? void 0 : _a.onChange) | ||
config.listeners.onChange(selectedDate.value); | ||
}); | ||
return { | ||
@@ -456,2 +610,3 @@ isOpen, | ||
datePickerDate, | ||
inputDisplayedValue, | ||
open: () => (isOpen.value = true), | ||
@@ -465,3 +620,3 @@ close: () => (isOpen.value = false), | ||
class DatePickerAppSingletonImpl { | ||
constructor(datePickerState, config, timeUnitsImpl) { | ||
constructor(datePickerState, config, timeUnitsImpl, translate) { | ||
Object.defineProperty(this, "datePickerState", { | ||
@@ -485,2 +640,8 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: translate | ||
}); | ||
} | ||
@@ -509,5 +670,11 @@ } | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl); | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl, this.translate); | ||
} | ||
@@ -526,6 +693,18 @@ withDatePickerState(datePickerState) { | ||
} | ||
withTranslate(translate) { | ||
this.translate = translate; | ||
return this; | ||
} | ||
} | ||
var Placement; | ||
(function (Placement) { | ||
Placement["TOP_START"] = "top-start"; | ||
Placement["TOP_END"] = "top-end"; | ||
Placement["BOTTOM_START"] = "bottom-start"; | ||
Placement["BOTTOM_END"] = "bottom-end"; | ||
})(Placement || (Placement = {})); | ||
class ConfigImpl { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString(new Date(1970, 0, 1)), max = toDateString(new Date(new Date().getFullYear() + 1, 11, 31))) { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString$1(new Date(1970, 0, 1)), max = toDateString$1(new Date(new Date().getFullYear() + 1, 11, 31)), placement = Placement.BOTTOM_START, listeners = {}) { | ||
Object.defineProperty(this, "locale", { | ||
@@ -555,2 +734,14 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: placement | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: listeners | ||
}); | ||
} | ||
@@ -585,5 +776,17 @@ } | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max); | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max, this.placement, this.listeners); | ||
} | ||
@@ -606,5 +809,56 @@ withLocale(locale) { | ||
} | ||
withPlacement(placement) { | ||
this.placement = placement; | ||
return this; | ||
} | ||
withListeners(listeners) { | ||
this.listeners = listeners; | ||
return this; | ||
} | ||
} | ||
const createDatePicker = (config, el) => { | ||
const datePickerDeDE = { | ||
Date: 'Datum', | ||
'MM/DD/YYYY': 'TT.MM.JJJJ', | ||
'Next month': 'Nächster Monat', | ||
'Previous month': 'Vorheriger Monat', | ||
}; | ||
const deDE = { | ||
...datePickerDeDE, | ||
}; | ||
const datePickerEnUS = { | ||
Date: 'Date', | ||
'MM/DD/YYYY': 'MM/DD/YYYY', | ||
'Next month': 'Next month', | ||
'Previous month': 'Previous month', | ||
}; | ||
const enUS = { | ||
...datePickerEnUS, | ||
}; | ||
class InvalidLocaleError extends Error { | ||
constructor(locale) { | ||
super(`Invalid locale: ${locale}`); | ||
} | ||
} | ||
const translate = (locale, languages) => (key) => { | ||
if (!/^[a-z]{2}-[A-Z]{2}$/.test(locale)) | ||
throw new InvalidLocaleError(locale); | ||
const deHyphenatedLocale = locale.replace('-', ''); | ||
const language = languages[deHyphenatedLocale]; | ||
if (!language) | ||
return key; | ||
return language[key] || key; | ||
}; | ||
const translations = { | ||
deDE, | ||
enUS, | ||
}; | ||
const createAppSingleton = (config = {}) => { | ||
const configInternal = new ConfigBuilder() | ||
@@ -615,2 +869,4 @@ .withFirstDayOfWeek(config.firstDayOfWeek) | ||
.withMax(config.max) | ||
.withPlacement(config.placement) | ||
.withListeners(config.listeners) | ||
.build(); | ||
@@ -620,7 +876,11 @@ const timeUnitsImpl = new TimeUnitsBuilder() | ||
.build(); | ||
const $app = new DatePickerAppSingletonBuilder() | ||
return new DatePickerAppSingletonBuilder() | ||
.withConfig(configInternal) | ||
.withDatePickerState(createDatePickerState()) | ||
.withDatePickerState(createDatePickerState(configInternal, config.selectedDate)) | ||
.withTimeUnitsImpl(timeUnitsImpl) | ||
.withTranslate(translate(configInternal.locale, translations)) | ||
.build(); | ||
}; | ||
const createDatePicker = (el, config) => { | ||
const $app = createAppSingleton(config); | ||
return new DatePickerApp($app, el); | ||
@@ -634,2 +894,1 @@ }; | ||
exports.createDatePickerInternal = createDatePickerInternal; | ||
//# sourceMappingURL=core.cjs.js.map |
327
dist/core.js
@@ -45,5 +45,5 @@ import { options, createContext, Component, createElement, Fragment, toChildArray, render } from 'preact'; | ||
}; | ||
const toLocalizedDate = (date, locale) => { | ||
const toLocalizedDateString = (date, locale) => { | ||
return date.toLocaleString(locale, { | ||
month: 'long', | ||
month: 'numeric', | ||
day: 'numeric', | ||
@@ -59,3 +59,3 @@ year: 'numeric', | ||
var chevronIcon$1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#DED8E1\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img$1 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='%23DED8E1' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -65,7 +65,8 @@ function AppInput() { | ||
const getLocalizedDate = (dateString) => { | ||
return toLocalizedDate(toJSDate(dateString), $app.config.locale); | ||
if (dateString === '') | ||
return $app.translate('MM/DD/YYYY'); | ||
return toLocalizedDateString(toJSDate(dateString), $app.config.locale); | ||
}; | ||
const [displayedValue, setDisplayedValue] = h$2(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
p$2(() => { | ||
setDisplayedValue(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
$app.datePickerState.inputDisplayedValue.value = getLocalizedDate($app.datePickerState.selectedDate.value); | ||
}, [$app.datePickerState.selectedDate.value]); | ||
@@ -79,3 +80,25 @@ const [wrapperClasses, setWrapperClasses] = h$2([]); | ||
}, [$app.datePickerState.isOpen.value]); | ||
return (o$2(Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: "Date" }), o$2("input", { value: displayedValue, "data-testid": "date-picker-input", readonly: true, class: "sx__date-input", onClick: () => $app.datePickerState.toggle(), type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: chevronIcon$1, alt: "" })] }) })); | ||
const handleKeyUp = (event) => { | ||
if (event.key === 'Enter') | ||
handleInputValue(event); | ||
}; | ||
const handleInputValue = (event) => { | ||
event.stopPropagation(); // prevent date picker from closing | ||
try { | ||
$app.datePickerState.inputDisplayedValue.value = event.target.value; | ||
$app.datePickerState.close(); | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}; | ||
p$2(() => { | ||
document.addEventListener('change', handleInputValue); // Preact onChange triggers on every input | ||
return () => document.removeEventListener('change', handleInputValue); | ||
}); | ||
const handleClick = (event) => { | ||
handleInputValue(event); | ||
$app.datePickerState.open(); | ||
}; | ||
return (o$2(Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: $app.translate('Date') }), o$2("input", { value: $app.datePickerState.inputDisplayedValue.value, "data-testid": "date-picker-input", class: "sx__date-input", onClick: handleClick, onKeyUp: handleKeyUp, type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: img$1, alt: "" })] }) })); | ||
} | ||
@@ -111,3 +134,3 @@ | ||
const toDateString = (date) => { | ||
const toDateString$1 = (date) => { | ||
return `${date.getFullYear()}-${doubleDigit(date.getMonth() + 1)}-${doubleDigit(date.getDate())}`; | ||
@@ -119,3 +142,3 @@ }; | ||
const toDateTimeString = (date) => { | ||
return `${toDateString(date)} ${toTimeString(date)}`; | ||
return `${toDateString$1(date)} ${toTimeString(date)}`; | ||
}; | ||
@@ -131,3 +154,3 @@ | ||
} | ||
return toDateString(jsDate); | ||
return toDateString$1(jsDate); | ||
}; | ||
@@ -153,3 +176,3 @@ | ||
var chevronIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#000\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -178,3 +201,7 @@ function MonthViewHeader({ setYearsView }) { | ||
}, [$app.datePickerState.datePickerDate.value]); | ||
return (o$2(Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: chevronIcon, alt: "previous month" }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: () => setYearsView(), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: chevronIcon, alt: "next month" }) })] }) })); | ||
const handleOpenYearsView = (e) => { | ||
e.stopPropagation(); | ||
setYearsView(); | ||
}; | ||
return (o$2(Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: img, alt: $app.translate('Previous month') }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: (event) => handleOpenYearsView(event), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: img, alt: $app.translate('Next month') }) })] }) })); | ||
} | ||
@@ -184,3 +211,3 @@ | ||
const $app = q$1(AppContext); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.selectedDate.value)); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.datePickerDate.value)); | ||
const dayNames = getOneLetterDayNames(aWeek, $app.config.locale); | ||
@@ -196,2 +223,6 @@ return (o$2("div", { class: "sx__date-picker__day-names", children: dayNames.map((dayName) => (o$2("span", { "data-testid": "day-name", class: "sx__date-picker__day-name", children: dayName }))) })); | ||
}; | ||
const isSameMonth = (date1, date2) => { | ||
return (date1.getMonth() === date2.getMonth() && | ||
date1.getFullYear() === date2.getFullYear()); | ||
}; | ||
@@ -204,4 +235,6 @@ function MonthViewWeek({ week }) { | ||
classes.push('sx__date-picker__day--today'); | ||
if (toDateString(day) === $app.datePickerState.selectedDate.value) | ||
if (toDateString$1(day) === $app.datePickerState.selectedDate.value) | ||
classes.push('sx__date-picker__day--selected'); | ||
if (!isSameMonth(day, toJSDate($app.datePickerState.datePickerDate.value))) | ||
classes.push('is-leading-or-trailing'); | ||
return { | ||
@@ -213,7 +246,7 @@ day, | ||
const isDateSelectable = (date) => { | ||
const dateString = toDateString(date); | ||
const dateString = toDateString$1(date); | ||
return dateString >= $app.config.min && dateString <= $app.config.max; | ||
}; | ||
const selectDate = (date) => { | ||
$app.datePickerState.selectedDate.value = toDateString(date); | ||
$app.datePickerState.selectedDate.value = toDateString$1(date); | ||
$app.datePickerState.close(); | ||
@@ -240,3 +273,7 @@ }; | ||
const yearWithDates = $app.timeUnitsImpl.getMonthsFor(year); | ||
return (o$2(Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: () => setYearAndMonth(year, month.getMonth()), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
const handleClickOnMonth = (event, month) => { | ||
event.stopPropagation(); | ||
setYearAndMonth(year, month.getMonth()); | ||
}; | ||
return (o$2(Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: (event) => handleClickOnMonth(event, month), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
} | ||
@@ -251,3 +288,3 @@ | ||
const setNewDatePickerDate = (year, month) => { | ||
$app.datePickerState.datePickerDate.value = toDateString(new Date(year, month, 1)); | ||
$app.datePickerState.datePickerDate.value = toDateString$1(new Date(year, month, 1)); | ||
setMonthView(); | ||
@@ -268,5 +305,17 @@ }; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
function AppPopup() { | ||
const $app = q$1(AppContext); | ||
const [datePickerView, setDatePickerView] = h$2(DatePickerView.MONTH_DAYS); | ||
return (o$2(Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: "sx__date-picker-popup", children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
const popupClasses = [POPUP_CLASS_NAME, $app.config.placement]; | ||
const clickOutsideListener = (event) => { | ||
const target = event.target; | ||
if (!target.closest(`.${POPUP_CLASS_NAME}`)) | ||
$app.datePickerState.close(); | ||
}; | ||
p$2(() => { | ||
document.addEventListener('click', clickOutsideListener); | ||
return () => document.removeEventListener('click', clickOutsideListener); | ||
}, []); | ||
return (o$2(Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
} | ||
@@ -298,2 +347,8 @@ | ||
} | ||
get value() { | ||
return this.$app.datePickerState.selectedDate.value; | ||
} | ||
set value(value) { | ||
this.$app.datePickerState.selectedDate.value = value; | ||
} | ||
} | ||
@@ -436,12 +491,111 @@ | ||
const createDatePickerState = (selectedDateParam) => { | ||
const initialSelectedDate = selectedDateParam || | ||
(() => { | ||
const { year, month, date } = new ExtendedDateImpl(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()); | ||
return `${year}-${doubleDigit(month + 1)}-${doubleDigit(date)}`; | ||
})(); | ||
var DateFormatDelimiter; | ||
(function (DateFormatDelimiter) { | ||
DateFormatDelimiter["SLASH"] = "/"; | ||
DateFormatDelimiter["DASH"] = "-"; | ||
DateFormatDelimiter["PERIOD"] = "."; | ||
})(DateFormatDelimiter || (DateFormatDelimiter = {})); | ||
var DateFormatOrder; | ||
(function (DateFormatOrder) { | ||
DateFormatOrder["DMY"] = "DMY"; | ||
DateFormatOrder["MDY"] = "MDY"; | ||
DateFormatOrder["YMD"] = "YMD"; | ||
})(DateFormatOrder || (DateFormatOrder = {})); | ||
const formatRules = { | ||
slashMDY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.MDY, | ||
}, | ||
slashDMY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
periodDMY: { | ||
delimiter: DateFormatDelimiter.PERIOD, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
dashYMD: { | ||
delimiter: DateFormatDelimiter.DASH, | ||
order: DateFormatOrder.YMD, | ||
}, | ||
}; | ||
const dateFormatLocalizedRules = new Map([ | ||
['en-US', formatRules.slashMDY], | ||
['en-GB', formatRules.slashDMY], | ||
['de-DE', formatRules.periodDMY], | ||
['sv-SE', formatRules.dashYMD], | ||
]); | ||
class LocaleNotSupportedError extends Error { | ||
constructor(locale) { | ||
super(`Locale not supported: ${locale}`); | ||
} | ||
} | ||
class InvalidDateFormatError extends Error { | ||
constructor(dateFormat, locale) { | ||
super(`Invalid date format: ${dateFormat} for locale: ${locale}`); | ||
} | ||
} | ||
const _getMatchesOrThrow = (format, matcher, locale) => { | ||
const matches = format.match(matcher); | ||
if (!matches) | ||
throw new InvalidDateFormatError(format, locale); | ||
return matches; | ||
}; | ||
const toDateString = (format, locale) => { | ||
const internationalFormat = /^\d{4}-\d{2}-\d{2}$/; | ||
if (internationalFormat.test(format)) | ||
return format; // allow international format regardless of locale | ||
const localeDateFormatRule = dateFormatLocalizedRules.get(locale); | ||
if (!localeDateFormatRule) | ||
throw new LocaleNotSupportedError(locale); | ||
const { order, delimiter } = localeDateFormatRule; | ||
const pattern224Slashed = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/; | ||
const pattern224Dotted = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/; | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.MDY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, month, day, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.PERIOD) { | ||
const matches = _getMatchesOrThrow(format, pattern224Dotted, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
throw new InvalidDateFormatError(format, locale); | ||
}; | ||
const createDatePickerState = (config, selectedDateParam) => { | ||
const currentDayDateString = toDateString$1(new Date()); | ||
const initialSelectedDate = typeof selectedDateParam === 'string' | ||
? selectedDateParam | ||
: currentDayDateString; | ||
const isOpen = u(false); | ||
const datePickerView = u(DatePickerView.MONTH_DAYS); | ||
const selectedDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate || currentDayDateString); | ||
const inputDisplayedValue = u(selectedDateParam || ''); | ||
b(() => { | ||
try { | ||
const newValue = toDateString(inputDisplayedValue.value, config.locale); | ||
selectedDate.value = newValue; | ||
datePickerDate.value = newValue; | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}); | ||
b(() => { | ||
var _a; | ||
if ((_a = config.listeners) === null || _a === void 0 ? void 0 : _a.onChange) | ||
config.listeners.onChange(selectedDate.value); | ||
}); | ||
return { | ||
@@ -452,2 +606,3 @@ isOpen, | ||
datePickerDate, | ||
inputDisplayedValue, | ||
open: () => (isOpen.value = true), | ||
@@ -461,3 +616,3 @@ close: () => (isOpen.value = false), | ||
class DatePickerAppSingletonImpl { | ||
constructor(datePickerState, config, timeUnitsImpl) { | ||
constructor(datePickerState, config, timeUnitsImpl, translate) { | ||
Object.defineProperty(this, "datePickerState", { | ||
@@ -481,2 +636,8 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: translate | ||
}); | ||
} | ||
@@ -505,5 +666,11 @@ } | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl); | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl, this.translate); | ||
} | ||
@@ -522,6 +689,18 @@ withDatePickerState(datePickerState) { | ||
} | ||
withTranslate(translate) { | ||
this.translate = translate; | ||
return this; | ||
} | ||
} | ||
var Placement; | ||
(function (Placement) { | ||
Placement["TOP_START"] = "top-start"; | ||
Placement["TOP_END"] = "top-end"; | ||
Placement["BOTTOM_START"] = "bottom-start"; | ||
Placement["BOTTOM_END"] = "bottom-end"; | ||
})(Placement || (Placement = {})); | ||
class ConfigImpl { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString(new Date(1970, 0, 1)), max = toDateString(new Date(new Date().getFullYear() + 1, 11, 31))) { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString$1(new Date(1970, 0, 1)), max = toDateString$1(new Date(new Date().getFullYear() + 1, 11, 31)), placement = Placement.BOTTOM_START, listeners = {}) { | ||
Object.defineProperty(this, "locale", { | ||
@@ -551,2 +730,14 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: placement | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: listeners | ||
}); | ||
} | ||
@@ -581,5 +772,17 @@ } | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max); | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max, this.placement, this.listeners); | ||
} | ||
@@ -602,5 +805,56 @@ withLocale(locale) { | ||
} | ||
withPlacement(placement) { | ||
this.placement = placement; | ||
return this; | ||
} | ||
withListeners(listeners) { | ||
this.listeners = listeners; | ||
return this; | ||
} | ||
} | ||
const createDatePicker = (config, el) => { | ||
const datePickerDeDE = { | ||
Date: 'Datum', | ||
'MM/DD/YYYY': 'TT.MM.JJJJ', | ||
'Next month': 'Nächster Monat', | ||
'Previous month': 'Vorheriger Monat', | ||
}; | ||
const deDE = { | ||
...datePickerDeDE, | ||
}; | ||
const datePickerEnUS = { | ||
Date: 'Date', | ||
'MM/DD/YYYY': 'MM/DD/YYYY', | ||
'Next month': 'Next month', | ||
'Previous month': 'Previous month', | ||
}; | ||
const enUS = { | ||
...datePickerEnUS, | ||
}; | ||
class InvalidLocaleError extends Error { | ||
constructor(locale) { | ||
super(`Invalid locale: ${locale}`); | ||
} | ||
} | ||
const translate = (locale, languages) => (key) => { | ||
if (!/^[a-z]{2}-[A-Z]{2}$/.test(locale)) | ||
throw new InvalidLocaleError(locale); | ||
const deHyphenatedLocale = locale.replace('-', ''); | ||
const language = languages[deHyphenatedLocale]; | ||
if (!language) | ||
return key; | ||
return language[key] || key; | ||
}; | ||
const translations = { | ||
deDE, | ||
enUS, | ||
}; | ||
const createAppSingleton = (config = {}) => { | ||
const configInternal = new ConfigBuilder() | ||
@@ -611,2 +865,4 @@ .withFirstDayOfWeek(config.firstDayOfWeek) | ||
.withMax(config.max) | ||
.withPlacement(config.placement) | ||
.withListeners(config.listeners) | ||
.build(); | ||
@@ -616,7 +872,11 @@ const timeUnitsImpl = new TimeUnitsBuilder() | ||
.build(); | ||
const $app = new DatePickerAppSingletonBuilder() | ||
return new DatePickerAppSingletonBuilder() | ||
.withConfig(configInternal) | ||
.withDatePickerState(createDatePickerState()) | ||
.withDatePickerState(createDatePickerState(configInternal, config.selectedDate)) | ||
.withTimeUnitsImpl(timeUnitsImpl) | ||
.withTranslate(translate(configInternal.locale, translations)) | ||
.build(); | ||
}; | ||
const createDatePicker = (el, config) => { | ||
const $app = createAppSingleton(config); | ||
return new DatePickerApp($app, el); | ||
@@ -629,2 +889,1 @@ }; | ||
export { createDatePicker, createDatePickerInternal }; | ||
//# sourceMappingURL=core.js.map |
@@ -49,5 +49,5 @@ (function (global, factory) { | ||
}; | ||
const toLocalizedDate = (date, locale) => { | ||
const toLocalizedDateString = (date, locale) => { | ||
return date.toLocaleString(locale, { | ||
month: 'long', | ||
month: 'numeric', | ||
day: 'numeric', | ||
@@ -63,3 +63,3 @@ year: 'numeric', | ||
var chevronIcon$1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#DED8E1\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img$1 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='%23DED8E1' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -69,7 +69,8 @@ function AppInput() { | ||
const getLocalizedDate = (dateString) => { | ||
return toLocalizedDate(toJSDate(dateString), $app.config.locale); | ||
if (dateString === '') | ||
return $app.translate('MM/DD/YYYY'); | ||
return toLocalizedDateString(toJSDate(dateString), $app.config.locale); | ||
}; | ||
const [displayedValue, setDisplayedValue] = h$2(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
p$2(() => { | ||
setDisplayedValue(getLocalizedDate($app.datePickerState.selectedDate.value)); | ||
$app.datePickerState.inputDisplayedValue.value = getLocalizedDate($app.datePickerState.selectedDate.value); | ||
}, [$app.datePickerState.selectedDate.value]); | ||
@@ -83,3 +84,25 @@ const [wrapperClasses, setWrapperClasses] = h$2([]); | ||
}, [$app.datePickerState.isOpen.value]); | ||
return (o$2(preact.Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: "Date" }), o$2("input", { value: displayedValue, "data-testid": "date-picker-input", readonly: true, class: "sx__date-input", onClick: () => $app.datePickerState.toggle(), type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: chevronIcon$1, alt: "" })] }) })); | ||
const handleKeyUp = (event) => { | ||
if (event.key === 'Enter') | ||
handleInputValue(event); | ||
}; | ||
const handleInputValue = (event) => { | ||
event.stopPropagation(); // prevent date picker from closing | ||
try { | ||
$app.datePickerState.inputDisplayedValue.value = event.target.value; | ||
$app.datePickerState.close(); | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}; | ||
p$2(() => { | ||
document.addEventListener('change', handleInputValue); // Preact onChange triggers on every input | ||
return () => document.removeEventListener('change', handleInputValue); | ||
}); | ||
const handleClick = (event) => { | ||
handleInputValue(event); | ||
$app.datePickerState.open(); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("div", { class: wrapperClasses.join(' '), children: [o$2("label", { class: "sx__date-input-label", children: $app.translate('Date') }), o$2("input", { value: $app.datePickerState.inputDisplayedValue.value, "data-testid": "date-picker-input", class: "sx__date-input", onClick: handleClick, onKeyUp: handleKeyUp, type: "text" }), o$2("img", { class: "sx__date-input-chevron", src: img$1, alt: "" })] }) })); | ||
} | ||
@@ -115,3 +138,3 @@ | ||
const toDateString = (date) => { | ||
const toDateString$1 = (date) => { | ||
return `${date.getFullYear()}-${doubleDigit(date.getMonth() + 1)}-${doubleDigit(date.getDate())}`; | ||
@@ -123,3 +146,3 @@ }; | ||
const toDateTimeString = (date) => { | ||
return `${toDateString(date)} ${toTimeString(date)}`; | ||
return `${toDateString$1(date)} ${toTimeString(date)}`; | ||
}; | ||
@@ -135,3 +158,3 @@ | ||
} | ||
return toDateString(jsDate); | ||
return toDateString$1(jsDate); | ||
}; | ||
@@ -157,3 +180,3 @@ | ||
var chevronIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\r\n<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M6 9L12 15L18 9\" stroke=\"#000\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>"; | ||
var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e%3csvg width='800px' height='800px' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M6 9L12 15L18 9' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e"; | ||
@@ -182,3 +205,7 @@ function MonthViewHeader({ setYearsView }) { | ||
}, [$app.datePickerState.datePickerDate.value]); | ||
return (o$2(preact.Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: chevronIcon, alt: "previous month" }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: () => setYearsView(), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: chevronIcon, alt: "next month" }) })] }) })); | ||
const handleOpenYearsView = (e) => { | ||
e.stopPropagation(); | ||
setYearsView(); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("header", { class: "sx__date-picker__month-view-header", children: [o$2("button", { onClick: () => setPreviousMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--previous", src: img, alt: $app.translate('Previous month') }) }), o$2("button", { class: "sx__date-picker__month-view-header__month-year", onClick: (event) => handleOpenYearsView(event), children: selectedDateMonthName + ' ' + datePickerYear }), o$2("button", { onClick: () => setNextMonth(), children: o$2("img", { class: "sx__date-picker__chevron sx__date-picker__chevron--next", src: img, alt: $app.translate('Next month') }) })] }) })); | ||
} | ||
@@ -188,3 +215,3 @@ | ||
const $app = q$1(AppContext); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.selectedDate.value)); | ||
const aWeek = $app.timeUnitsImpl.getWeekFor(toJSDate($app.datePickerState.datePickerDate.value)); | ||
const dayNames = getOneLetterDayNames(aWeek, $app.config.locale); | ||
@@ -200,2 +227,6 @@ return (o$2("div", { class: "sx__date-picker__day-names", children: dayNames.map((dayName) => (o$2("span", { "data-testid": "day-name", class: "sx__date-picker__day-name", children: dayName }))) })); | ||
}; | ||
const isSameMonth = (date1, date2) => { | ||
return (date1.getMonth() === date2.getMonth() && | ||
date1.getFullYear() === date2.getFullYear()); | ||
}; | ||
@@ -208,4 +239,6 @@ function MonthViewWeek({ week }) { | ||
classes.push('sx__date-picker__day--today'); | ||
if (toDateString(day) === $app.datePickerState.selectedDate.value) | ||
if (toDateString$1(day) === $app.datePickerState.selectedDate.value) | ||
classes.push('sx__date-picker__day--selected'); | ||
if (!isSameMonth(day, toJSDate($app.datePickerState.datePickerDate.value))) | ||
classes.push('is-leading-or-trailing'); | ||
return { | ||
@@ -217,7 +250,7 @@ day, | ||
const isDateSelectable = (date) => { | ||
const dateString = toDateString(date); | ||
const dateString = toDateString$1(date); | ||
return dateString >= $app.config.min && dateString <= $app.config.max; | ||
}; | ||
const selectDate = (date) => { | ||
$app.datePickerState.selectedDate.value = toDateString(date); | ||
$app.datePickerState.selectedDate.value = toDateString$1(date); | ||
$app.datePickerState.close(); | ||
@@ -244,3 +277,7 @@ }; | ||
const yearWithDates = $app.timeUnitsImpl.getMonthsFor(year); | ||
return (o$2(preact.Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: () => setYearAndMonth(year, month.getMonth()), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
const handleClickOnMonth = (event, month) => { | ||
event.stopPropagation(); | ||
setYearAndMonth(year, month.getMonth()); | ||
}; | ||
return (o$2(preact.Fragment, { children: o$2("li", { class: isExpanded ? 'sx__is-expanded' : '', children: [o$2("button", { class: "sx__date-picker__years-accordion__expand-button", onClick: () => expand(year), children: year }), isExpanded && (o$2("div", { class: "sx__date-picker__years-view-accordion__panel", children: yearWithDates.map((month) => (o$2("button", { class: "sx__date-picker__years-view-accordion__month", onClick: (event) => handleClickOnMonth(event, month), children: toLocalizedMonth(month, $app.config.locale) }))) }))] }) })); | ||
} | ||
@@ -255,3 +292,3 @@ | ||
const setNewDatePickerDate = (year, month) => { | ||
$app.datePickerState.datePickerDate.value = toDateString(new Date(year, month, 1)); | ||
$app.datePickerState.datePickerDate.value = toDateString$1(new Date(year, month, 1)); | ||
setMonthView(); | ||
@@ -272,5 +309,17 @@ }; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
function AppPopup() { | ||
const $app = q$1(AppContext); | ||
const [datePickerView, setDatePickerView] = h$2(DatePickerView.MONTH_DAYS); | ||
return (o$2(preact.Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: "sx__date-picker-popup", children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
const popupClasses = [POPUP_CLASS_NAME, $app.config.placement]; | ||
const clickOutsideListener = (event) => { | ||
const target = event.target; | ||
if (!target.closest(`.${POPUP_CLASS_NAME}`)) | ||
$app.datePickerState.close(); | ||
}; | ||
p$2(() => { | ||
document.addEventListener('click', clickOutsideListener); | ||
return () => document.removeEventListener('click', clickOutsideListener); | ||
}, []); | ||
return (o$2(preact.Fragment, { children: o$2("div", { "data-testid": "date-picker-popup", class: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (o$2(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (o$2(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
} | ||
@@ -302,2 +351,8 @@ | ||
} | ||
get value() { | ||
return this.$app.datePickerState.selectedDate.value; | ||
} | ||
set value(value) { | ||
this.$app.datePickerState.selectedDate.value = value; | ||
} | ||
} | ||
@@ -440,12 +495,111 @@ | ||
const createDatePickerState = (selectedDateParam) => { | ||
const initialSelectedDate = selectedDateParam || | ||
(() => { | ||
const { year, month, date } = new ExtendedDateImpl(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()); | ||
return `${year}-${doubleDigit(month + 1)}-${doubleDigit(date)}`; | ||
})(); | ||
var DateFormatDelimiter; | ||
(function (DateFormatDelimiter) { | ||
DateFormatDelimiter["SLASH"] = "/"; | ||
DateFormatDelimiter["DASH"] = "-"; | ||
DateFormatDelimiter["PERIOD"] = "."; | ||
})(DateFormatDelimiter || (DateFormatDelimiter = {})); | ||
var DateFormatOrder; | ||
(function (DateFormatOrder) { | ||
DateFormatOrder["DMY"] = "DMY"; | ||
DateFormatOrder["MDY"] = "MDY"; | ||
DateFormatOrder["YMD"] = "YMD"; | ||
})(DateFormatOrder || (DateFormatOrder = {})); | ||
const formatRules = { | ||
slashMDY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.MDY, | ||
}, | ||
slashDMY: { | ||
delimiter: DateFormatDelimiter.SLASH, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
periodDMY: { | ||
delimiter: DateFormatDelimiter.PERIOD, | ||
order: DateFormatOrder.DMY, | ||
}, | ||
dashYMD: { | ||
delimiter: DateFormatDelimiter.DASH, | ||
order: DateFormatOrder.YMD, | ||
}, | ||
}; | ||
const dateFormatLocalizedRules = new Map([ | ||
['en-US', formatRules.slashMDY], | ||
['en-GB', formatRules.slashDMY], | ||
['de-DE', formatRules.periodDMY], | ||
['sv-SE', formatRules.dashYMD], | ||
]); | ||
class LocaleNotSupportedError extends Error { | ||
constructor(locale) { | ||
super(`Locale not supported: ${locale}`); | ||
} | ||
} | ||
class InvalidDateFormatError extends Error { | ||
constructor(dateFormat, locale) { | ||
super(`Invalid date format: ${dateFormat} for locale: ${locale}`); | ||
} | ||
} | ||
const _getMatchesOrThrow = (format, matcher, locale) => { | ||
const matches = format.match(matcher); | ||
if (!matches) | ||
throw new InvalidDateFormatError(format, locale); | ||
return matches; | ||
}; | ||
const toDateString = (format, locale) => { | ||
const internationalFormat = /^\d{4}-\d{2}-\d{2}$/; | ||
if (internationalFormat.test(format)) | ||
return format; // allow international format regardless of locale | ||
const localeDateFormatRule = dateFormatLocalizedRules.get(locale); | ||
if (!localeDateFormatRule) | ||
throw new LocaleNotSupportedError(locale); | ||
const { order, delimiter } = localeDateFormatRule; | ||
const pattern224Slashed = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/; | ||
const pattern224Dotted = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/; | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.MDY && delimiter === DateFormatDelimiter.SLASH) { | ||
const matches = _getMatchesOrThrow(format, pattern224Slashed, locale); | ||
const [, month, day, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
if (order === DateFormatOrder.DMY && delimiter === DateFormatDelimiter.PERIOD) { | ||
const matches = _getMatchesOrThrow(format, pattern224Dotted, locale); | ||
const [, day, month, year] = matches; | ||
return `${year}-${doubleDigit(+month)}-${doubleDigit(+day)}`; | ||
} | ||
throw new InvalidDateFormatError(format, locale); | ||
}; | ||
const createDatePickerState = (config, selectedDateParam) => { | ||
const currentDayDateString = toDateString$1(new Date()); | ||
const initialSelectedDate = typeof selectedDateParam === 'string' | ||
? selectedDateParam | ||
: currentDayDateString; | ||
const isOpen = u(false); | ||
const datePickerView = u(DatePickerView.MONTH_DAYS); | ||
const selectedDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate); | ||
const datePickerDate = u(initialSelectedDate || currentDayDateString); | ||
const inputDisplayedValue = u(selectedDateParam || ''); | ||
b(() => { | ||
try { | ||
const newValue = toDateString(inputDisplayedValue.value, config.locale); | ||
selectedDate.value = newValue; | ||
datePickerDate.value = newValue; | ||
} | ||
catch (e) { | ||
// nothing to do | ||
} | ||
}); | ||
b(() => { | ||
var _a; | ||
if ((_a = config.listeners) === null || _a === void 0 ? void 0 : _a.onChange) | ||
config.listeners.onChange(selectedDate.value); | ||
}); | ||
return { | ||
@@ -456,2 +610,3 @@ isOpen, | ||
datePickerDate, | ||
inputDisplayedValue, | ||
open: () => (isOpen.value = true), | ||
@@ -465,3 +620,3 @@ close: () => (isOpen.value = false), | ||
class DatePickerAppSingletonImpl { | ||
constructor(datePickerState, config, timeUnitsImpl) { | ||
constructor(datePickerState, config, timeUnitsImpl, translate) { | ||
Object.defineProperty(this, "datePickerState", { | ||
@@ -485,2 +640,8 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: translate | ||
}); | ||
} | ||
@@ -509,5 +670,11 @@ } | ||
}); | ||
Object.defineProperty(this, "translate", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl); | ||
return new DatePickerAppSingletonImpl(this.datePickerState, this.config, this.timeUnitsImpl, this.translate); | ||
} | ||
@@ -526,6 +693,18 @@ withDatePickerState(datePickerState) { | ||
} | ||
withTranslate(translate) { | ||
this.translate = translate; | ||
return this; | ||
} | ||
} | ||
var Placement; | ||
(function (Placement) { | ||
Placement["TOP_START"] = "top-start"; | ||
Placement["TOP_END"] = "top-end"; | ||
Placement["BOTTOM_START"] = "bottom-start"; | ||
Placement["BOTTOM_END"] = "bottom-end"; | ||
})(Placement || (Placement = {})); | ||
class ConfigImpl { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString(new Date(1970, 0, 1)), max = toDateString(new Date(new Date().getFullYear() + 1, 11, 31))) { | ||
constructor(locale = DEFAULT_LOCALE, firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, min = toDateString$1(new Date(1970, 0, 1)), max = toDateString$1(new Date(new Date().getFullYear() + 1, 11, 31)), placement = Placement.BOTTOM_START, listeners = {}) { | ||
Object.defineProperty(this, "locale", { | ||
@@ -555,2 +734,14 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: placement | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: listeners | ||
}); | ||
} | ||
@@ -585,5 +776,17 @@ } | ||
}); | ||
Object.defineProperty(this, "placement", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "listeners", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
} | ||
build() { | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max); | ||
return new ConfigImpl(this.locale, this.firstDayOfWeek, this.min, this.max, this.placement, this.listeners); | ||
} | ||
@@ -606,5 +809,56 @@ withLocale(locale) { | ||
} | ||
withPlacement(placement) { | ||
this.placement = placement; | ||
return this; | ||
} | ||
withListeners(listeners) { | ||
this.listeners = listeners; | ||
return this; | ||
} | ||
} | ||
const createDatePicker = (config, el) => { | ||
const datePickerDeDE = { | ||
Date: 'Datum', | ||
'MM/DD/YYYY': 'TT.MM.JJJJ', | ||
'Next month': 'Nächster Monat', | ||
'Previous month': 'Vorheriger Monat', | ||
}; | ||
const deDE = { | ||
...datePickerDeDE, | ||
}; | ||
const datePickerEnUS = { | ||
Date: 'Date', | ||
'MM/DD/YYYY': 'MM/DD/YYYY', | ||
'Next month': 'Next month', | ||
'Previous month': 'Previous month', | ||
}; | ||
const enUS = { | ||
...datePickerEnUS, | ||
}; | ||
class InvalidLocaleError extends Error { | ||
constructor(locale) { | ||
super(`Invalid locale: ${locale}`); | ||
} | ||
} | ||
const translate = (locale, languages) => (key) => { | ||
if (!/^[a-z]{2}-[A-Z]{2}$/.test(locale)) | ||
throw new InvalidLocaleError(locale); | ||
const deHyphenatedLocale = locale.replace('-', ''); | ||
const language = languages[deHyphenatedLocale]; | ||
if (!language) | ||
return key; | ||
return language[key] || key; | ||
}; | ||
const translations = { | ||
deDE, | ||
enUS, | ||
}; | ||
const createAppSingleton = (config = {}) => { | ||
const configInternal = new ConfigBuilder() | ||
@@ -615,2 +869,4 @@ .withFirstDayOfWeek(config.firstDayOfWeek) | ||
.withMax(config.max) | ||
.withPlacement(config.placement) | ||
.withListeners(config.listeners) | ||
.build(); | ||
@@ -620,7 +876,11 @@ const timeUnitsImpl = new TimeUnitsBuilder() | ||
.build(); | ||
const $app = new DatePickerAppSingletonBuilder() | ||
return new DatePickerAppSingletonBuilder() | ||
.withConfig(configInternal) | ||
.withDatePickerState(createDatePickerState()) | ||
.withDatePickerState(createDatePickerState(configInternal, config.selectedDate)) | ||
.withTimeUnitsImpl(timeUnitsImpl) | ||
.withTranslate(translate(configInternal.locale, translations)) | ||
.build(); | ||
}; | ||
const createDatePicker = (el, config) => { | ||
const $app = createAppSingleton(config); | ||
return new DatePickerApp($app, el); | ||
@@ -638,2 +898,1 @@ }; | ||
})); | ||
//# sourceMappingURL=core.umd.js.map |
@@ -1,1 +0,2 @@ | ||
export declare const factory: () => Element; | ||
import { Placement } from '../../../enums/placement.enum'; | ||
export declare const factory: (placement?: Placement) => Element; |
@@ -7,2 +7,4 @@ import DatePickerAppSingleton from './utils/stateful/app-singleton/date-picker-app.singleton'; | ||
bootstrap(): void; | ||
get value(): string; | ||
set value(value: string); | ||
} |
import { DatePickerConfigExternal } from './utils/stateful/config/config.interface'; | ||
import DatePickerApp from './date-picker.app'; | ||
import DatePickerAppSingleton from './utils/stateful/app-singleton/date-picker-app.singleton'; | ||
export declare const createDatePicker: (config: DatePickerConfigExternal, el: HTMLElement) => DatePickerApp; | ||
export declare const createAppSingleton: (config?: DatePickerConfigExternal) => DatePickerAppSingleton; | ||
export declare const createDatePicker: (el: HTMLElement, config?: DatePickerConfigExternal) => DatePickerApp; | ||
export declare const createDatePickerInternal: ($app: DatePickerAppSingleton, el: HTMLElement) => DatePickerApp; |
@@ -6,2 +6,3 @@ import Builder from '../../../../../../shared/interfaces/builder.interface'; | ||
import TimeUnits from '../../../../../../shared/utils/stateful/time-units/time-units.interface'; | ||
import { TranslateFn } from '../../../../../translations/src'; | ||
export default class DatePickerAppSingletonBuilder implements Builder<DatePickerAppSingleton> { | ||
@@ -11,2 +12,3 @@ private datePickerState; | ||
private timeUnitsImpl; | ||
private translate; | ||
build(): DatePickerAppSingleton; | ||
@@ -16,2 +18,3 @@ withDatePickerState(datePickerState: DatePickerState): DatePickerAppSingletonBuilder; | ||
withTimeUnitsImpl(timeUnitsImpl: TimeUnits): DatePickerAppSingletonBuilder; | ||
withTranslate(translate: TranslateFn): DatePickerAppSingletonBuilder; | ||
} |
@@ -5,2 +5,3 @@ import DatePickerState from '../../../../../../shared/utils/stateful/date-picker-state/date-picker-state.interface'; | ||
import DatePickerAppSingleton from './date-picker-app.singleton'; | ||
import { TranslateFn } from '../../../../../translations/src'; | ||
export default class DatePickerAppSingletonImpl implements DatePickerAppSingleton { | ||
@@ -10,3 +11,4 @@ datePickerState: DatePickerState; | ||
timeUnitsImpl: TimeUnits; | ||
constructor(datePickerState: DatePickerState, config: DatePickerConfigInternal, timeUnitsImpl: TimeUnits); | ||
translate: TranslateFn; | ||
constructor(datePickerState: DatePickerState, config: DatePickerConfigInternal, timeUnitsImpl: TimeUnits, translate: TranslateFn); | ||
} |
import Builder from '../../../../../../shared/interfaces/builder.interface'; | ||
import DatePickerConfigInternal from './config.interface'; | ||
import { WeekDay } from '../../../../../../shared/enums/time/week-day.enum'; | ||
import { Placement } from '../../../enums/placement.enum'; | ||
import { DatePickerListeners } from './listeners.interface'; | ||
export declare class ConfigBuilder implements Builder<DatePickerConfigInternal> { | ||
@@ -9,2 +11,4 @@ locale: string | undefined; | ||
max: string | undefined; | ||
placement: Placement | undefined; | ||
listeners: DatePickerListeners | undefined; | ||
build(): DatePickerConfigInternal; | ||
@@ -15,2 +19,4 @@ withLocale(locale: string | undefined): ConfigBuilder; | ||
withMax(max: string | undefined): ConfigBuilder; | ||
withPlacement(placement: Placement | undefined): ConfigBuilder; | ||
withListeners(listeners: DatePickerListeners | undefined): ConfigBuilder; | ||
} |
import DatePickerConfigInternal from './config.interface'; | ||
import { WeekDay } from '../../../../../../shared/enums/time/week-day.enum'; | ||
import { Placement } from '../../../enums/placement.enum'; | ||
import { DatePickerListeners } from './listeners.interface'; | ||
export declare class ConfigImpl implements DatePickerConfigInternal { | ||
@@ -8,3 +10,5 @@ locale: string; | ||
max: string; | ||
constructor(locale?: string, firstDayOfWeek?: WeekDay, min?: string, max?: string); | ||
placement: Placement; | ||
listeners: DatePickerListeners; | ||
constructor(locale?: string, firstDayOfWeek?: WeekDay, min?: string, max?: string, placement?: Placement, listeners?: DatePickerListeners); | ||
} |
import Config from '../../../../../../shared/interfaces/config.interface'; | ||
import { Placement } from '../../../enums/placement.enum'; | ||
import { DatePickerListeners } from './listeners.interface'; | ||
export default interface DatePickerConfigInternal extends Config { | ||
min: string; | ||
max: string; | ||
placement: Placement; | ||
listeners: DatePickerListeners; | ||
} | ||
export interface DatePickerConfigExternal extends Partial<DatePickerConfigInternal> { | ||
export interface DatePickerConfigExternal extends Partial<Omit<DatePickerConfigInternal, 'placement'>> { | ||
selectedDate?: string; | ||
placement?: Placement | string; | ||
} |
import TimeUnits from '../utils/stateful/time-units/time-units.interface'; | ||
import DatePickerState from '../utils/stateful/date-picker-state/date-picker-state.interface'; | ||
import Config from './config.interface'; | ||
import { TranslateFn } from '../../packages/translations/src'; | ||
export default interface AppSingleton { | ||
@@ -8,2 +9,3 @@ timeUnitsImpl: TimeUnits; | ||
config: Config; | ||
translate: TranslateFn; | ||
} |
import DatePickerState from './date-picker-state.interface'; | ||
export declare const createDatePickerState: (selectedDateParam?: string) => DatePickerState; | ||
import DatePickerConfigInternal from '@schedule-x/date-picker/src/utils/stateful/config/config.interface'; | ||
export declare const createDatePickerState: (config: DatePickerConfigInternal, selectedDateParam?: string) => DatePickerState; |
@@ -6,2 +6,3 @@ import { DatePickerView } from '@schedule-x/date-picker/src/enums/date-picker-view.enum'; | ||
selectedDate: Signal<string>; | ||
inputDisplayedValue: Signal<string>; | ||
datePickerDate: Signal<string>; | ||
@@ -8,0 +9,0 @@ datePickerView: Signal<DatePickerView>; |
export declare const isToday: (date: Date) => boolean; | ||
export declare const isSameMonth: (date1: Date, date2: Date) => boolean; |
export declare const toLocalizedMonth: (date: Date, locale: string) => string; | ||
export declare const toLocalizedDate: (date: Date, locale: string) => string; | ||
export declare const toLocalizedDateString: (date: Date, locale: string) => string; | ||
export declare const getOneLetterDayNames: (week: Date[], locale: string) => string[]; |
{ | ||
"name": "@schedule-x/date-picker", | ||
"version": "0.1.0-alpha.1", | ||
"version": "0.1.0-alpha.2", | ||
"description": "Schedule-X date picker component", | ||
@@ -18,2 +18,3 @@ "author": { | ||
"dependencies": { | ||
"@schedule-x/translations": "^0.1.0-alpha.2", | ||
"preact": "^10.16.0" | ||
@@ -26,3 +27,3 @@ }, | ||
}, | ||
"gitHead": "08e4f6ae6f96e63570e75acd14041271d1d1c59e" | ||
"gitHead": "052aa6562e27bd1776de750b3054ee45daf7a39a" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
91
3881
210723
2
+ Added@schedule-x/translations@0.1.0(transitive)