Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@schedule-x/date-picker

Package Overview
Dependencies
Maintainers
1
Versions
133
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@schedule-x/date-picker - npm Package Compare versions

Comparing version 0.1.0-alpha.1 to 0.1.0-alpha.2

./dist/core.cjs.js

327

dist/core.cjs.js

@@ -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

@@ -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

3

dist/packages/date-picker/src/components/__test__/app-popup/utils.d.ts

@@ -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"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc