calcite-input-date-picker.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. import { proxyCustomElement, HTMLElement, createEvent, h, Host, Build } from '@stencil/core/internal/client';
  7. import { T as TEXT, g as getLocaleData, d as defineCustomElement$8 } from './date-picker.js';
  8. import { d as dateToISO, a as dateFromISO, b as dateFromRange, s as sameDate, f as parseDateString, i as inRange } from './date.js';
  9. import { c as connectLabel, d as disconnectLabel, g as getLabelText } from './label.js';
  10. import { s as submitForm, c as connectForm, d as disconnectForm, H as HiddenFormInputSlot } from './form.js';
  11. import { a as defaultMenuPlacement, f as filterComputedPlacements, u as updatePopper, C as CSS, c as createPopper, p as popperMenuComputedPlacements } from './popper.js';
  12. import { u as updateHostInteraction } from './interactive.js';
  13. import { t as toAriaBoolean } from './dom.js';
  14. import { d as defineCustomElement$7 } from './date-picker-day.js';
  15. import { d as defineCustomElement$6 } from './date-picker-month.js';
  16. import { d as defineCustomElement$5 } from './date-picker-month-header.js';
  17. import { d as defineCustomElement$4 } from './icon.js';
  18. import { d as defineCustomElement$3 } from './input.js';
  19. import { d as defineCustomElement$2 } from './progress.js';
  20. const inputDatePickerCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:host{--calcite-icon-size:1rem;--calcite-spacing-eighth:0.125rem;--calcite-spacing-quarter:0.25rem;--calcite-spacing-half:0.5rem;--calcite-spacing-three-quarters:0.75rem;--calcite-spacing:1rem;--calcite-spacing-plus-quarter:1.25rem;--calcite-spacing-plus-half:1.5rem;--calcite-spacing-double:2rem;--calcite-menu-min-width:10rem;--calcite-header-min-height:3rem;--calcite-footer-min-height:3rem}:root{--calcite-popper-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host{position:relative;display:inline-block;width:100%;overflow:visible;vertical-align:top;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;-webkit-box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.calendar-picker-wrapper{position:static;width:100%;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;-webkit-box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.input-wrapper{position:relative}:host([range]) .input-container{display:-ms-flexbox;display:flex}:host([range]) .input-wrapper{-ms-flex:1 1 auto;flex:1 1 auto}:host([range]) .horizontal-arrow-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;border-width:1px;border-left-width:0px;border-right-width:0px;border-style:solid;border-color:var(--calcite-ui-border-input);background-color:var(--calcite-ui-background);padding-top:0px;padding-bottom:0px;padding-left:0.25rem;padding-right:0.25rem}:host([range][layout=vertical]) .input-wrapper{width:100%}:host([range][layout=vertical]) .input-container{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start}:host([range][layout=vertical]) .calendar-picker-wrapper--end{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}:host([range][layout=vertical]) .vertical-arrow-container{top:1.5rem;position:absolute;left:0px;z-index:10;margin-left:1px;margin-right:1px;background-color:var(--calcite-ui-foreground-1);padding-left:0.625rem;padding-right:0.625rem}:host([scale=s][range]:not([layout=vertical])) .calendar-picker-wrapper{width:216px}:host([scale=m][range]:not([layout=vertical])) .calendar-picker-wrapper{width:286px}:host([scale=l][range]:not([layout=vertical])) .calendar-picker-wrapper{width:398px}.menu-container{display:block;position:absolute;z-index:900;-webkit-transform:scale(0);transform:scale(0);visibility:hidden;pointer-events:none}.menu-container .calcite-popper-anim{position:relative;z-index:1;-webkit-transition:var(--calcite-popper-transition);transition:var(--calcite-popper-transition);visibility:hidden;-webkit-transition-property:visibility, opacity, -webkit-transform;transition-property:visibility, opacity, -webkit-transform;transition-property:transform, visibility, opacity;transition-property:transform, visibility, opacity, -webkit-transform;opacity:0;-webkit-box-shadow:0 0 16px 0 rgba(0, 0, 0, 0.16);box-shadow:0 0 16px 0 rgba(0, 0, 0, 0.16);border-radius:0.25rem}.menu-container[data-popper-placement^=bottom] .calcite-popper-anim{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.menu-container[data-popper-placement^=top] .calcite-popper-anim{-webkit-transform:translateY(5px);transform:translateY(5px)}.menu-container[data-popper-placement^=left] .calcite-popper-anim{-webkit-transform:translateX(5px);transform:translateX(5px)}.menu-container[data-popper-placement^=right] .calcite-popper-anim{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.menu-container[data-popper-placement] .calcite-popper-anim--active{opacity:1;visibility:visible;-webkit-transform:translate(0);transform:translate(0)}:host([active]) .menu-container{pointer-events:initial;visibility:visible}.menu-container--active .menu-container .calcite-popper-anim{position:relative;z-index:1;-webkit-transition:var(--calcite-popper-transition);transition:var(--calcite-popper-transition);visibility:hidden;-webkit-transition-property:visibility, opacity, -webkit-transform;transition-property:visibility, opacity, -webkit-transform;transition-property:transform, visibility, opacity;transition-property:transform, visibility, opacity, -webkit-transform;opacity:0;-webkit-box-shadow:0 0 16px 0 rgba(0, 0, 0, 0.16);box-shadow:0 0 16px 0 rgba(0, 0, 0, 0.16);border-radius:0.25rem}.menu-container--active .menu-container[data-popper-placement^=bottom] .calcite-popper-anim{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.menu-container--active .menu-container[data-popper-placement^=top] .calcite-popper-anim{-webkit-transform:translateY(5px);transform:translateY(5px)}.menu-container--active .menu-container[data-popper-placement^=left] .calcite-popper-anim{-webkit-transform:translateX(5px);transform:translateX(5px)}.menu-container--active .menu-container[data-popper-placement^=right] .calcite-popper-anim{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.menu-container--active .menu-container[data-popper-placement] .calcite-popper-anim--active{opacity:1;visibility:visible;-webkit-transform:translate(0);transform:translate(0)}.input .calcite-input__wrapper{margin-top:0px}:host([range][layout=vertical][scale=m]) .vertical-arrow-container{top:1.5rem;padding-left:0.75rem}:host([range][layout=vertical][scale=m]) .vertical-arrow-container calcite-icon{height:0.75rem;width:0.75rem;min-width:0px}:host([range][layout=vertical][scale=l]) .vertical-arrow-container{top:2.25rem;padding-left:0.875rem;padding-right:0.875rem}:host([range][layout=vertical][active]) .vertical-arrow-container{display:none}::slotted(input[slot=hidden-form-input]){bottom:0 !important;left:0 !important;margin:0 !important;opacity:0 !important;outline:none !important;padding:0 !important;position:absolute !important;right:0 !important;top:0 !important;-webkit-transform:none !important;transform:none !important;-webkit-appearance:none !important;z-index:-1 !important}";
  21. const InputDatePicker = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
  22. constructor() {
  23. super();
  24. this.__registerHost();
  25. this.__attachShadow();
  26. this.calciteDatePickerChange = createEvent(this, "calciteDatePickerChange", 7);
  27. this.calciteDatePickerRangeChange = createEvent(this, "calciteDatePickerRangeChange", 7);
  28. this.calciteInputDatePickerChange = createEvent(this, "calciteInputDatePickerChange", 7);
  29. this.calciteInputDatePickerOpen = createEvent(this, "calciteInputDatePickerOpen", 7);
  30. this.calciteInputDatePickerClose = createEvent(this, "calciteInputDatePickerClose", 7);
  31. //--------------------------------------------------------------------------
  32. //
  33. // Public Properties
  34. //
  35. //--------------------------------------------------------------------------
  36. /**
  37. * When false, the component won't be interactive.
  38. */
  39. this.disabled = false;
  40. /** Expand or collapse when calendar does not have input */
  41. this.active = false;
  42. /** Localized string for "previous month" (used for aria label)
  43. * @default "Previous month"
  44. */
  45. this.intlPrevMonth = TEXT.prevMonth;
  46. /** Localized string for "next month" (used for aria label)
  47. * @default "Next month"
  48. */
  49. this.intlNextMonth = TEXT.nextMonth;
  50. /** Localized string for "year" (used for aria label)
  51. * @default "Year"
  52. */
  53. this.intlYear = TEXT.year;
  54. /** BCP 47 language tag for desired language and country format */
  55. this.locale = document.documentElement.lang || "en";
  56. /** specify the scale of the date picker */
  57. this.scale = "m";
  58. /**
  59. * Determines where the date-picker component will be positioned relative to the input.
  60. * @default "bottom-leading"
  61. */
  62. this.placement = defaultMenuPlacement;
  63. /** Range mode activation */
  64. this.range = false;
  65. /**
  66. * When true, makes the component required for form-submission.
  67. *
  68. * @internal
  69. */
  70. this.required = false;
  71. /** Describes the type of positioning to use for the overlaid content. If your element is in a fixed container, use the 'fixed' value. */
  72. this.overlayPositioning = "absolute";
  73. /** Disables the default behaviour on the third click of narrowing or extending the range and instead starts a new range. */
  74. this.proximitySelectionDisabled = false;
  75. /** Layout */
  76. this.layout = "horizontal";
  77. this.focusedInput = "start";
  78. this.activeTransitionProp = "opacity";
  79. //--------------------------------------------------------------------------
  80. //
  81. // Private Methods
  82. //
  83. //--------------------------------------------------------------------------
  84. this.setFilteredPlacements = () => {
  85. const { el, flipPlacements } = this;
  86. this.filteredFlipPlacements = flipPlacements
  87. ? filterComputedPlacements(flipPlacements, el)
  88. : null;
  89. };
  90. this.transitionEnd = (event) => {
  91. if (event.propertyName === this.activeTransitionProp) {
  92. this.active
  93. ? this.calciteInputDatePickerOpen.emit()
  94. : this.calciteInputDatePickerClose.emit();
  95. }
  96. };
  97. this.setStartInput = (el) => {
  98. this.startInput = el;
  99. };
  100. this.setEndInput = (el) => {
  101. this.endInput = el;
  102. };
  103. this.deactivate = () => {
  104. this.active = false;
  105. };
  106. this.keyDownHandler = (event) => {
  107. if (event.key === "Enter" && !event.defaultPrevented) {
  108. submitForm(this);
  109. }
  110. };
  111. this.keyUpHandler = (e) => {
  112. if (e.key === "Escape") {
  113. this.active = false;
  114. }
  115. };
  116. this.inputBlur = (e) => {
  117. this.blur(e.detail);
  118. };
  119. this.startInputFocus = () => {
  120. this.active = true;
  121. this.focusedInput = "start";
  122. };
  123. this.endInputFocus = () => {
  124. this.active = true;
  125. this.focusedInput = "end";
  126. };
  127. this.inputInput = (e) => {
  128. this.input(e.detail.value);
  129. };
  130. this.setMenuEl = (el) => {
  131. if (el) {
  132. this.menuEl = el;
  133. this.createPopper();
  134. }
  135. };
  136. this.setStartWrapper = (el) => {
  137. this.startWrapper = el;
  138. this.setReferenceEl();
  139. };
  140. this.setEndWrapper = (el) => {
  141. this.endWrapper = el;
  142. this.setReferenceEl();
  143. };
  144. /**
  145. * Event handler for when the selected date changes
  146. */
  147. this.handleDateChange = (event) => {
  148. if (this.range) {
  149. return;
  150. }
  151. this.value = dateToISO(event.detail);
  152. };
  153. this.handleDateRangeChange = (event) => {
  154. var _a, _b;
  155. if (!this.range || !event.detail) {
  156. return;
  157. }
  158. const { startDate, endDate } = event.detail;
  159. this.start = dateToISO(startDate);
  160. this.end = dateToISO(endDate);
  161. this.value = [this.start, this.end];
  162. if (this.shouldFocusRangeEnd()) {
  163. (_a = this.endInput) === null || _a === void 0 ? void 0 : _a.setFocus();
  164. }
  165. else if (this.shouldFocusRangeStart()) {
  166. (_b = this.startInput) === null || _b === void 0 ? void 0 : _b.setFocus();
  167. }
  168. };
  169. }
  170. handleDisabledChange(value) {
  171. if (!value) {
  172. this.active = false;
  173. }
  174. }
  175. valueHandler(value) {
  176. if (Array.isArray(value)) {
  177. this.valueAsDate = value.map((v) => dateFromISO(v));
  178. this.start = value[0];
  179. this.end = value[1];
  180. }
  181. else if (value) {
  182. this.valueAsDate = dateFromISO(value);
  183. this.start = "";
  184. this.end = "";
  185. }
  186. else {
  187. this.valueAsDate = undefined;
  188. this.start = undefined;
  189. this.end = undefined;
  190. }
  191. }
  192. flipPlacementsHandler() {
  193. this.setFilteredPlacements();
  194. }
  195. onMinChanged(min) {
  196. if (min) {
  197. this.minAsDate = dateFromISO(min);
  198. }
  199. }
  200. onMaxChanged(max) {
  201. if (max) {
  202. this.maxAsDate = dateFromISO(max);
  203. }
  204. }
  205. activeHandler() {
  206. if (!this.disabled) {
  207. this.reposition();
  208. return;
  209. }
  210. this.active = false;
  211. }
  212. //--------------------------------------------------------------------------
  213. //
  214. // Event Listeners
  215. //
  216. //--------------------------------------------------------------------------
  217. handleDateOrRangeChange() {
  218. this.calciteInputDatePickerChange.emit();
  219. }
  220. calciteDaySelectHandler() {
  221. if (this.shouldFocusRangeStart() || this.shouldFocusRangeEnd()) {
  222. return;
  223. }
  224. this.active = false;
  225. }
  226. // --------------------------------------------------------------------------
  227. //
  228. // Public Methods
  229. //
  230. // --------------------------------------------------------------------------
  231. /** Updates the position of the component. */
  232. async setFocus() {
  233. var _a;
  234. (_a = this.startInput) === null || _a === void 0 ? void 0 : _a.setFocus();
  235. }
  236. /** Updates the position of the component. */
  237. async reposition() {
  238. const { placement, popper, menuEl } = this;
  239. const modifiers = this.getModifiers();
  240. popper
  241. ? await updatePopper({
  242. el: menuEl,
  243. modifiers,
  244. placement,
  245. popper
  246. })
  247. : this.createPopper();
  248. }
  249. // --------------------------------------------------------------------------
  250. //
  251. // Lifecycle
  252. //
  253. // --------------------------------------------------------------------------
  254. connectedCallback() {
  255. if (Array.isArray(this.value)) {
  256. this.valueAsDate = this.value.map((v) => dateFromISO(v));
  257. this.start = this.value[0];
  258. this.end = this.value[1];
  259. }
  260. else if (this.value) {
  261. this.valueAsDate = dateFromISO(this.value);
  262. this.start = "";
  263. this.end = "";
  264. }
  265. if (this.start) {
  266. this.startAsDate = dateFromISO(this.start);
  267. }
  268. if (this.end) {
  269. this.endAsDate = dateFromISO(this.end);
  270. }
  271. if (this.min) {
  272. this.minAsDate = dateFromISO(this.min);
  273. }
  274. if (this.max) {
  275. this.maxAsDate = dateFromISO(this.max);
  276. }
  277. this.createPopper();
  278. connectLabel(this);
  279. connectForm(this);
  280. this.setFilteredPlacements();
  281. }
  282. async componentWillLoad() {
  283. await this.loadLocaleData();
  284. this.onMinChanged(this.min);
  285. this.onMaxChanged(this.max);
  286. }
  287. disconnectedCallback() {
  288. this.destroyPopper();
  289. disconnectLabel(this);
  290. disconnectForm(this);
  291. }
  292. componentDidRender() {
  293. updateHostInteraction(this);
  294. }
  295. render() {
  296. var _a, _b;
  297. const { disabled } = this;
  298. const date = dateFromRange(this.range ? this.startAsDate : this.valueAsDate, this.minAsDate, this.maxAsDate);
  299. const endDate = this.range
  300. ? dateFromRange(this.endAsDate, this.minAsDate, this.maxAsDate)
  301. : null;
  302. const formattedEndDate = endDate ? endDate.toLocaleDateString(this.locale) : "";
  303. const formattedDate = date ? date.toLocaleDateString(this.locale) : "";
  304. return (h(Host, { onBlur: this.deactivate, onKeyDown: this.keyDownHandler, onKeyUp: this.keyUpHandler, role: "application" }, this.localeData && (h("div", { "aria-expanded": toAriaBoolean(this.active), class: "input-container", role: "application" }, h("div", { class: "input-wrapper", ref: this.setStartWrapper }, h("calcite-input", { class: `input ${this.layout === "vertical" && this.range ? `no-bottom-border` : ``}`, disabled: disabled, icon: "calendar", label: getLabelText(this), "number-button-type": "none", onCalciteInputBlur: this.inputBlur, onCalciteInputFocus: this.startInputFocus, onCalciteInputInput: this.inputInput, placeholder: (_a = this.localeData) === null || _a === void 0 ? void 0 : _a.placeholder, ref: this.setStartInput, scale: this.scale, type: "text", value: formattedDate })), h("div", { "aria-hidden": toAriaBoolean(!this.active), class: {
  305. "menu-container": true,
  306. "menu-container--active": this.active
  307. }, ref: this.setMenuEl }, h("div", { class: {
  308. ["calendar-picker-wrapper"]: true,
  309. ["calendar-picker-wrapper--end"]: this.focusedInput === "end",
  310. [CSS.animation]: true,
  311. [CSS.animationActive]: this.active
  312. }, onTransitionEnd: this.transitionEnd }, h("calcite-date-picker", { activeRange: this.focusedInput, endAsDate: this.endAsDate, headingLevel: this.headingLevel, intlNextMonth: this.intlNextMonth, intlPrevMonth: this.intlPrevMonth, intlYear: this.intlYear, locale: this.locale, max: this.max, maxAsDate: this.maxAsDate, min: this.min, minAsDate: this.minAsDate, onCalciteDatePickerChange: this.handleDateChange, onCalciteDatePickerRangeChange: this.handleDateRangeChange, proximitySelectionDisabled: this.proximitySelectionDisabled, range: this.range, scale: this.scale, startAsDate: this.startAsDate, tabIndex: 0, valueAsDate: this.valueAsDate }))), this.range && this.layout === "horizontal" && (h("div", { class: "horizontal-arrow-container" }, h("calcite-icon", { flipRtl: true, icon: "arrow-right", scale: "s" }))), this.range && this.layout === "vertical" && this.scale !== "s" && (h("div", { class: "vertical-arrow-container" }, h("calcite-icon", { icon: "arrow-down", scale: "s" }))), this.range && (h("div", { class: "input-wrapper", ref: this.setEndWrapper }, h("calcite-input", { class: {
  313. input: true,
  314. "border-top-color-one": this.layout === "vertical" && this.range
  315. }, disabled: disabled, icon: "calendar", "number-button-type": "none", onCalciteInputBlur: this.inputBlur, onCalciteInputFocus: this.endInputFocus, onCalciteInputInput: this.inputInput, placeholder: (_b = this.localeData) === null || _b === void 0 ? void 0 : _b.placeholder, ref: this.setEndInput, scale: this.scale, type: "text", value: formattedEndDate }))))), h(HiddenFormInputSlot, { component: this })));
  316. }
  317. setReferenceEl() {
  318. const { focusedInput, layout, endWrapper, startWrapper } = this;
  319. this.referenceEl =
  320. focusedInput === "end" || layout === "vertical"
  321. ? endWrapper || startWrapper
  322. : startWrapper || endWrapper;
  323. this.createPopper();
  324. }
  325. onLabelClick() {
  326. this.setFocus();
  327. }
  328. getModifiers() {
  329. const flipModifier = {
  330. name: "flip",
  331. enabled: true
  332. };
  333. flipModifier.options = {
  334. fallbackPlacements: this.filteredFlipPlacements || popperMenuComputedPlacements
  335. };
  336. const eventListenerModifier = {
  337. name: "eventListeners",
  338. enabled: this.active
  339. };
  340. return [flipModifier, eventListenerModifier];
  341. }
  342. createPopper() {
  343. this.destroyPopper();
  344. const { menuEl, placement, referenceEl, overlayPositioning } = this;
  345. if (!menuEl || !referenceEl) {
  346. return;
  347. }
  348. const modifiers = this.getModifiers();
  349. this.popper = createPopper({
  350. el: menuEl,
  351. modifiers,
  352. overlayPositioning,
  353. placement,
  354. referenceEl
  355. });
  356. }
  357. destroyPopper() {
  358. const { popper } = this;
  359. if (popper) {
  360. popper.destroy();
  361. }
  362. this.popper = null;
  363. }
  364. startWatcher(start) {
  365. this.startAsDate = dateFromISO(start);
  366. }
  367. endWatcher(end) {
  368. this.endAsDate = dateFromISO(end);
  369. }
  370. async loadLocaleData() {
  371. if (!Build.isBrowser) {
  372. return;
  373. }
  374. const { locale } = this;
  375. this.localeData = await getLocaleData(locale);
  376. }
  377. clearCurrentValue() {
  378. if (!this.range) {
  379. if (typeof this.value === "string" && this.value) {
  380. this.calciteDatePickerChange.emit();
  381. }
  382. this.value = "";
  383. return;
  384. }
  385. const { focusedInput } = this;
  386. if (focusedInput === "start") {
  387. if (this.start) {
  388. this.calciteDatePickerRangeChange.emit();
  389. }
  390. this.value = Array.isArray(this.value) ? ["", this.value[1] || ""] : [""];
  391. this.start = undefined;
  392. }
  393. else if (focusedInput === "end") {
  394. if (this.end) {
  395. this.calciteDatePickerRangeChange.emit();
  396. }
  397. this.value = Array.isArray(this.value) ? [this.value[0] || "", ""] : ["", ""];
  398. this.end = undefined;
  399. }
  400. }
  401. /**
  402. * If inputted string is a valid date, update value/active
  403. */
  404. input(value) {
  405. const date = this.getDateFromInput(value);
  406. if (!date) {
  407. this.clearCurrentValue();
  408. return;
  409. }
  410. if (!this.range) {
  411. this.value = dateToISO(date);
  412. this.calciteDatePickerChange.emit(date);
  413. return;
  414. }
  415. const { focusedInput } = this;
  416. if (focusedInput === "start") {
  417. if (!this.startAsDate || !sameDate(date, this.startAsDate)) {
  418. const startDateISO = dateToISO(date);
  419. this.value = Array.isArray(this.value)
  420. ? [startDateISO, this.value[1] || ""]
  421. : [startDateISO];
  422. this.start = startDateISO;
  423. this.calciteDatePickerRangeChange.emit({
  424. startDate: date,
  425. endDate: this.endAsDate
  426. });
  427. }
  428. }
  429. else if (focusedInput === "end") {
  430. if (!this.endAsDate || !sameDate(date, this.endAsDate)) {
  431. const endDateISO = dateToISO(date);
  432. this.value = Array.isArray(this.value)
  433. ? [this.value[0] || "", endDateISO]
  434. : ["", endDateISO];
  435. this.end = endDateISO;
  436. this.calciteDatePickerRangeChange.emit({
  437. startDate: this.startAsDate,
  438. endDate: date
  439. });
  440. }
  441. }
  442. }
  443. /**
  444. * Clean up invalid date from input on blur
  445. */
  446. blur(target) {
  447. const { locale, focusedInput, endAsDate, range, startAsDate, valueAsDate } = this;
  448. const date = this.getDateFromInput(target.value);
  449. if (!date) {
  450. if (!range && valueAsDate) {
  451. target.value = Array.isArray(valueAsDate)
  452. ? valueAsDate[focusedInput === "end" ? 1 : 0].toLocaleDateString(locale)
  453. : valueAsDate.toLocaleDateString(locale);
  454. }
  455. else if (focusedInput === "start" && startAsDate) {
  456. target.value = startAsDate.toLocaleDateString(locale);
  457. }
  458. else if (focusedInput === "end" && endAsDate) {
  459. target.value = endAsDate.toLocaleDateString(locale);
  460. }
  461. }
  462. }
  463. shouldFocusRangeStart() {
  464. return !!(this.endAsDate &&
  465. !this.startAsDate &&
  466. this.focusedInput === "end" &&
  467. this.startInput);
  468. }
  469. shouldFocusRangeEnd() {
  470. return !!(this.startAsDate &&
  471. !this.endAsDate &&
  472. this.focusedInput === "start" &&
  473. this.endInput);
  474. }
  475. /**
  476. * Find a date from input string
  477. * return false if date is invalid, or out of range
  478. */
  479. getDateFromInput(value) {
  480. if (!this.localeData) {
  481. return false;
  482. }
  483. const { separator } = this.localeData;
  484. const { day, month, year } = parseDateString(value, this.localeData);
  485. const validDay = day > 0;
  486. const validMonth = month > -1;
  487. const date = new Date(year, month, day);
  488. date.setFullYear(year);
  489. const validDate = !isNaN(date.getTime());
  490. const validLength = value.split(separator).filter((c) => c).length > 2;
  491. const validYear = year.toString().length > 0;
  492. if (validDay &&
  493. validMonth &&
  494. validDate &&
  495. validLength &&
  496. validYear &&
  497. inRange(date, this.min, this.max)) {
  498. return date;
  499. }
  500. return false;
  501. }
  502. get el() { return this; }
  503. static get watchers() { return {
  504. "disabled": ["handleDisabledChange"],
  505. "value": ["valueHandler"],
  506. "flipPlacements": ["flipPlacementsHandler"],
  507. "min": ["onMinChanged"],
  508. "max": ["onMaxChanged"],
  509. "active": ["activeHandler"],
  510. "layout": ["setReferenceEl"],
  511. "focusedInput": ["setReferenceEl"],
  512. "start": ["startWatcher"],
  513. "end": ["endWatcher"],
  514. "locale": ["loadLocaleData"]
  515. }; }
  516. static get style() { return inputDatePickerCss; }
  517. }, [1, "calcite-input-date-picker", {
  518. "disabled": [516],
  519. "value": [1025],
  520. "flipPlacements": [16],
  521. "headingLevel": [2, "heading-level"],
  522. "valueAsDate": [1040],
  523. "startAsDate": [1040],
  524. "endAsDate": [1040],
  525. "minAsDate": [1040],
  526. "maxAsDate": [1040],
  527. "min": [1025],
  528. "max": [1025],
  529. "active": [1540],
  530. "name": [1],
  531. "intlPrevMonth": [1, "intl-prev-month"],
  532. "intlNextMonth": [1, "intl-next-month"],
  533. "intlYear": [1, "intl-year"],
  534. "locale": [1],
  535. "scale": [513],
  536. "placement": [513],
  537. "range": [516],
  538. "required": [516],
  539. "start": [1025],
  540. "end": [1025],
  541. "overlayPositioning": [1, "overlay-positioning"],
  542. "proximitySelectionDisabled": [4, "proximity-selection-disabled"],
  543. "layout": [513],
  544. "focusedInput": [32],
  545. "localeData": [32],
  546. "setFocus": [64],
  547. "reposition": [64]
  548. }, [[0, "calciteDatePickerChange", "handleDateOrRangeChange"], [0, "calciteDatePickerRangeChange", "handleDateOrRangeChange"], [0, "calciteDaySelect", "calciteDaySelectHandler"]]]);
  549. function defineCustomElement$1() {
  550. if (typeof customElements === "undefined") {
  551. return;
  552. }
  553. const components = ["calcite-input-date-picker", "calcite-date-picker", "calcite-date-picker-day", "calcite-date-picker-month", "calcite-date-picker-month-header", "calcite-icon", "calcite-input", "calcite-progress"];
  554. components.forEach(tagName => { switch (tagName) {
  555. case "calcite-input-date-picker":
  556. if (!customElements.get(tagName)) {
  557. customElements.define(tagName, InputDatePicker);
  558. }
  559. break;
  560. case "calcite-date-picker":
  561. if (!customElements.get(tagName)) {
  562. defineCustomElement$8();
  563. }
  564. break;
  565. case "calcite-date-picker-day":
  566. if (!customElements.get(tagName)) {
  567. defineCustomElement$7();
  568. }
  569. break;
  570. case "calcite-date-picker-month":
  571. if (!customElements.get(tagName)) {
  572. defineCustomElement$6();
  573. }
  574. break;
  575. case "calcite-date-picker-month-header":
  576. if (!customElements.get(tagName)) {
  577. defineCustomElement$5();
  578. }
  579. break;
  580. case "calcite-icon":
  581. if (!customElements.get(tagName)) {
  582. defineCustomElement$4();
  583. }
  584. break;
  585. case "calcite-input":
  586. if (!customElements.get(tagName)) {
  587. defineCustomElement$3();
  588. }
  589. break;
  590. case "calcite-progress":
  591. if (!customElements.get(tagName)) {
  592. defineCustomElement$2();
  593. }
  594. break;
  595. } });
  596. }
  597. defineCustomElement$1();
  598. const CalciteInputDatePicker = InputDatePicker;
  599. const defineCustomElement = defineCustomElement$1;
  600. export { CalciteInputDatePicker, defineCustomElement };