UNPKG

@salla.sa/twilight-components

Version:
748 lines (736 loc) 134 kB
/*! * Crafted with ❤ by Salla */ 'use strict'; var index = require('./index-uoA36zqH.js'); var calendar = require('./calendar-D-PUoCDH.js'); var keyboard_arrow_down = require('./keyboard_arrow_down-DHJ3FFZq.js'); var minus = require('./minus-CCryh1qf.js'); var Helper = require('./Helper-CU4Xuiki.js'); require('./anime.es-BqW8JHZi.js'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var BookingTime = `<!-- Generated by IcoMoon.io --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"> <title>calendar-time</title> <path d="M22.667 17.333c-0.737 0-1.333 0.596-1.333 1.333v2.667h-2.667c-0.737 0-1.333 0.596-1.333 1.333s0.596 1.333 1.333 1.333h4c0.737 0 1.333-0.596 1.333-1.333v-4c0-0.737-0.596-1.333-1.333-1.333zM28 2.667h-2.667v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-13.333v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-2.667c-2.205 0-4 1.795-4 4v21.333c0 2.205 1.795 4 4 4h5.363c0.737 0 1.333-0.596 1.333-1.333s-0.596-1.333-1.333-1.333h-5.363c-0.736 0-1.333-0.597-1.333-1.333v-21.333c0-0.736 0.597-1.333 1.333-1.333h2.667v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h13.333v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h2.667c0.736 0 1.333 0.599 1.333 1.333v2.696c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.696c0-2.205-1.795-4-4-4zM22 12c-5.515 0-10 4.485-10 10s4.485 10 10 10 10-4.485 10-10-4.485-10-10-10zM22 29.333c-4.043 0-7.333-3.291-7.333-7.333s3.291-7.333 7.333-7.333 7.333 3.291 7.333 7.333-3.291 7.333-7.333 7.333z"></path> </svg> `; var TimeIcon = `<!-- Generated by IcoMoon.io --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"> <title>time</title> <path d="M16 0c-8.823 0-16 7.177-16 16s7.177 16 16 16 16-7.177 16-16-7.177-16-16-16zM16 29.333c-7.352 0-13.333-5.981-13.333-13.333s5.981-13.333 13.333-13.333 13.333 5.981 13.333 13.333-5.981 13.333-13.333 13.333zM16 8c-0.736 0-1.333 0.596-1.333 1.333v6.667h-4c-0.736 0-1.333 0.596-1.333 1.333s0.597 1.333 1.333 1.333h5.333c0.736 0 1.333-0.596 1.333-1.333v-8c0-0.737-0.597-1.333-1.333-1.333z"></path> </svg> `; const sallaBookingFieldCss = ":host{display:block}"; const SallaBookingField = class { constructor(hostRef) { index.registerInstance(this, hostRef); this.invalidInput = index.createEvent(this, "invalidInput"); this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment', 'حجز موعد'); this.editLabel = salla.lang.get('pages.cart.edit_an_appointment', 'تعديل الموعد'); this.bookedLabel = salla.lang.get('pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح'); this.selectDate = salla.lang.get('pages.cart.select_appointment_date', 'حدد تاريخ الموعد'); this.bookingUrl = ''; this.iframeReady = false; this.reservations = []; // Load translations salla.lang.onLoaded(() => this.setTranslations()); // Register event listeners Salla.event.on('booking::open', (data) => this.handleBookingOpen(data)); } async setTranslations() { const setNestedAsync = (lang, key, value) => { return new Promise((resolve) => { salla.helpers.setNested(salla.lang.messages[lang], key, value); resolve(true); }); }; await setNestedAsync('ar.trans', 'pages.cart.book_an_appointment', 'حجز موعد'); await setNestedAsync('en.trans', 'pages.cart.book_an_appointment', 'Book an Appointment'); await setNestedAsync('ar.trans', 'pages.cart.edit_an_appointment', 'تعديل الموعد'); await setNestedAsync('en.trans', 'pages.cart.edit_an_appointment', 'Edit an Appointment'); await setNestedAsync('ar.trans', 'pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح'); await setNestedAsync('en.trans', 'pages.cart.booked_successfully', 'Booked Successfully'); await setNestedAsync('ar.trans', 'pages.cart.select_appointment_date', 'حدد تاريخ الموعد'); await setNestedAsync('en.trans', 'pages.cart.select_appointment_date', 'Select appointment date'); this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment'); this.editLabel = salla.lang.get('pages.cart.edit_an_appointment'); this.bookedLabel = salla.lang.get('pages.cart.booked_successfully'); this.selectDate = salla.lang.get('pages.cart.select_appointment_date'); } openBookingModal(event, afterReload = false) { if (afterReload && (!event.detail || typeof event.detail !== 'number' || event.detail !== this.productId)) { return; } if (salla.config.isGuest()) { this.setAfterReloadEvent('booking::open-after-reload', this.productId); salla.event.dispatch('login::open'); return; } salla.booking.add(this.productId, false) .then((resp) => { if (resp.data.redirect.to !== 'booking') { throw new Error('Unexpected redirect!'); } salla.event.dispatch('booking::open', { url: resp.data.redirect.url, id: this.productId }); }) .catch((error) => { salla.error(salla.lang.get('common.errors.error_occurred')); salla.logger.error(error.response || error); }); } handleBookingOpen(data) { if (data.id !== this.productId) return; this.bookingUrl = salla.url.addParamToUrl('product_id', data.id, data.url); this.iframeReady = true; setTimeout(() => { this.modal.setTitle(this.selectDate); this.modal.open(); }, 100); } setAfterReloadEvent(event, payload) { salla.storage.set('afterReloadEvent', { event, payload }); } emitAfterReloadEvent() { const eventDetails = salla.storage.get('afterReloadEvent'); if (eventDetails && eventDetails.event) { const customEvent = new CustomEvent(eventDetails.event, { detail: eventDetails.payload }); window.dispatchEvent(customEvent); salla.storage.remove('afterReloadEvent'); } } componentWillLoad() { if (this.option && this.option.details.length) { this.reservations = this.option.details; } } componentDidLoad() { window.addEventListener('booking::open-after-reload', (event) => this.openBookingModal(event, true)); this.emitAfterReloadEvent(); window.addEventListener('message', this.handleMessageEvent.bind(this)); this.reservationsInput.addEventListener('invalid', e => this.invalidInput.emit(e)); this.reservationsInput.addEventListener('input', () => { this.reservationsInput.setCustomValidity(''); this.reservationsInput.reportValidity(); }); } handleMessageEvent(event) { if (event.data.source !== 'booking') return; const action = event.data.type; const value = event.data.message; if (localStorage.getItem('debug')) console.log(`Received an action:${action}`, event.data); if (action === 'error') { if (value.fields?.reservation) { salla.notify.error(value.fields.reservation[0]); return; } const errorList = Object.values(value.fields || [value.message]).flat().map(error => `<li>${error}</li>`).join(''); salla.notify.error(`<ul>${errorList}</ul>`); } if (action === 'success') { if (Number(value.productId) !== Number(this.productId)) return; this.reservations = value.data.reservations.map(schedule => { if (schedule.time && schedule.time.length > 0) { const timeSlot = schedule.time[0]; return { date: schedule.date, day: schedule.day, from_timestamp: timeSlot.from, to_timestamp: timeSlot.to, }; } return null; }).filter(item => item !== null); salla.notify.success(this.bookedLabel); this.modal?.close(); setTimeout(() => window.location.reload()); } if (action === 'height') { this.iframe.height = value?.height + 'px'; } } bookingModal() { return (index.h("salla-modal", { class: "s-booking-field-modal", ref: modal => (this.modal = modal), width: "md", position: "middle", noPadding: true }, index.h("iframe", { ref: iframe => (this.iframe = iframe), src: this.bookingUrl, frameborder: "0" }))); } renderReservationDate(reservation) { return (index.h("span", { class: reservation.from_timestamp ? 's-booking-field-reservations-has-time' : '' }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: calendar.SICalendar }), reservation.date)); } renderReservationTime(reservation) { if (!reservation.from_timestamp) return ''; return (index.h("span", { class: "s-booking-field-reservations-time" }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: TimeIcon }), index.h("span", null, reservation.from_timestamp, " - ", reservation.to_timestamp))); } render() { return (index.h(index.Host, { key: '9a65e86d8c731ea7538ae930d73c63a0fba342d6' }, index.h("div", { key: 'fbac1a9dfdf76f36405db4dff611fd9baa47870b', class: "s-booking-field-main" }, this.option.required || this.reservations.length > 0 ? index.h("div", { class: "s-booking-field-price" }, index.h("span", { innerHTML: salla.money(this.option.price) })) : '', index.h("salla-button", { key: '190495f3a42496aa9d14da129363e6ff83e788ac', class: "s-booking-field-book-now", size: "small", loaderPosition: "center", fill: "outline", onClick: event => this.openBookingModal(event, false) }, index.h("span", { key: '7db20f2888bc865d87545804a2f609f7d07e4dc2', class: "s-booking-field-book-now-content" }, index.h("span", { key: '05f6f331e311f79e5a61a7b6e197e24334bdb5d4', innerHTML: BookingTime }), this.reservations.length ? this.editLabel : this.bookNowLabel))), this.reservations.length > 0 && (index.h("div", { key: 'f54c13f40c3109f5d3249361ac299451151909cf', class: "s-booking-field-reservations" }, this.reservations.map((reservation, index$1) => (index.h("div", { key: index$1, class: "s-booking-field-reservations-item" }, this.renderReservationDate(reservation), this.renderReservationTime(reservation)))))), index.h("input", { key: '5d147e4832a2b14ed614152efefa35769e0c52ba', class: "s-hidden", name: this.option.name, required: this.option.required, value: JSON.stringify(this.reservations) === '[]' ? '' : JSON.stringify(this.reservations), ref: reservations => this.reservationsInput = reservations }), this.iframeReady && this.bookingModal())); } get host() { return index.getElement(this); } }; SallaBookingField.style = sallaBookingFieldCss; const sallaColorPickerCss = ""; const SallaColorPicker = class { constructor(hostRef) { index.registerInstance(this, hostRef); this.colorChanged = index.createEvent(this, "colorChanged"); this.invalidInput = index.createEvent(this, "invalidInput"); this.submitted = index.createEvent(this, "submitted"); this.popupOpened = index.createEvent(this, "popupOpened"); this.popupClosed = index.createEvent(this, "popupClosed"); /** Lazy-loaded to avoid bundling vanilla-picker (Babel polyfills) into main/hydrate bundle. */ this.picker = null; this.pickerReady = null; /** * File input name for the native formData */ this.name = 'color'; /** * Set if the color picker input is required or not */ this.required = false; /** * How to display the selected color in the text field * (the text field still supports input in any format). */ this.format = 'hex'; /** * Whether to have a "Cancel" button which closes the popup. */ this.showCancelButton = false; /** * Whether to show a text field for color value editing. */ this.showTextField = true; /** * Whether to enable adjusting the alpha channel. */ this.enableAlpha = false; this.updateViewportCache = () => { this.cachedViewportWidth = this.getViewportWidthFromBreakpoints(); }; this.cachedViewportWidth = 0; // Will be populated in componentDidLoad via requestAnimationFrame } colorChangeHandler(color) { if (this.colorInput) this.colorInput.value = color.hex; this.colorChanged.emit(color); } async submittedHandler(color) { await this.setColorValue(color.rgbaString, true); if (this.canvas) this.canvas.style.backgroundColor = color.rgbString; if (this.colorInput) { this.colorInput.value = color.hex; this.colorInput.dispatchEvent(new window.Event('change', { bubbles: true })); } this.submitted.emit(color); } popupOpenedHandler(color) { // Double rAF: defer setPopInPosition (getBoundingClientRect) until after paint to avoid forced reflow requestAnimationFrame(() => { requestAnimationFrame(() => this.setPopInPosition()); }); this.popupOpened.emit(color); } popupClosedHandler(color) { this.popupClosed.emit(color); } /** Methods */ async ensurePicker() { if (this.picker) return this.picker; if (this.pickerReady) return await this.pickerReady; throw new Error('Color picker not initialized'); } /** * Set the picker options. * * (Usually a new .parent and .color). * @param {Object} options */ async setPickerOption(options) { const picker = await this.ensurePicker(); picker.setOptions(options); } /** * Move the popup to a different parent, optionally opening it at the same time. * * (Usually a new .parent and .color). * @param {Options} option * * Whether to open the popup immediately. * @param {boolean} openImmediately */ async movePopUp(options, openImmediately) { const picker = await this.ensurePicker(); picker.movePopup(options, openImmediately); } /** * Set/initialize the picker's color. * * Color name, RGBA/HSLA/HEX string, or RGBA array. * @param {string} color * * If true, won't trigger onChange. * @param {boolean} triggerEvent */ async setColorValue(color, triggerEvent) { const picker = await this.ensurePicker(); picker.setColor(color, triggerEvent); } /** * Show/open the picker. */ async openPicker() { const picker = await this.ensurePicker(); picker.show(); } /** * Close/Hide the picker. */ async closePicker() { const picker = await this.ensurePicker(); picker.hide(); } /** * Release all resources used by this picker instance. */ async destroyPicker() { const picker = await this.ensurePicker(); picker.destroy(); this.picker = null; this.pickerReady = null; } disconnectedCallback() { window.removeEventListener('resize', this.updateViewportCache); } componentWillLoad() { salla.onReady(() => { this.color = this.color ? this.color : salla.config.get('theme.color.primary', '#5dd5c4'); }); } /** * Returns viewport width from matchMedia breakpoints (no layout read). * Must match updateViewportCache breakpoints for consistency. */ getViewportWidthFromBreakpoints() { if (typeof window === 'undefined') return 1024; if (window.matchMedia('(min-width: 1200px)').matches) return 1200; if (window.matchMedia('(min-width: 992px)').matches) return 992; if (window.matchMedia('(min-width: 768px)').matches) return 768; return 375; } setPopInPosition() { // Use cached viewport width – reading innerWidth at popup open causes forced reflow. // Fallback: matchMedia-based value when cache is 0 (e.g. SSR before hydration). Same breakpoints as updateViewportCache. const viewportWidth = this.cachedViewportWidth || this.getViewportWidthFromBreakpoints(); const popup = this.host.querySelector('.picker_wrapper'); const widgetEl = this.host.querySelector('.s-color-picker-widget'); if (!popup || !widgetEl) return; const widgetPosition = widgetEl.getBoundingClientRect(); const widgetToWindowEq = viewportWidth / 2 - widgetPosition.width / 2; const widgetInLeft = widgetToWindowEq > widgetPosition.x; const widgetInRight = widgetToWindowEq < widgetPosition.x; const widgetInCenter = widgetToWindowEq === widgetPosition.x; const isMobile = !window.matchMedia('(min-width: 768px)').matches; if (isMobile && widgetInLeft) { popup.style.left = '0'; } if (isMobile && widgetInRight) { popup.style.left = 'auto'; } if (!isMobile || (isMobile && ((!widgetInRight && !widgetInLeft) || widgetInCenter))) { popup.style.left = `-95px`; } } initColorPicker() { this.pickerReady = Promise.resolve().then(function () { return require('./vanilla-picker-jTWa07cO.js'); }).then(function (n) { return n.vanillaPicker; }).then(mod => { const Picker = mod.default; const picker = new Picker({ parent: this.host, color: this.color, popup: 'bottom', alpha: this.enableAlpha, editor: this.showTextField, editorFormat: this.format, cancelButton: this.showCancelButton, onChange: (color) => this.colorChangeHandler(color), onDone: (color) => this.submittedHandler(color), onOpen: (color) => this.popupOpenedHandler(color), onClose: (color) => this.popupClosedHandler(color), }); this.picker = picker; return this.picker; }); } render() { return (index.h(index.Host, { key: '2f142fd64afd5571574a7e1c40de3be16ede62e6', class: "s-color-picker-main" }, index.h("slot", { key: '92acdf14b2f42ac52d0a632ba6840a5dcebfa4d4', name: "widget" }, index.h("div", { key: '7ba074040299a91802109d0e1d2e78604e39d3a8', class: "s-color-picker-widget" }, index.h("div", { key: 'a6272207f79fd28e33b66e415a3e05b969ace983', class: "s-color-picker-widget-canvas", ref: dv => (this.canvas = dv) }), index.h("span", { key: 'e6fed242bb84fae6221cdec525658b68f7514ce7', innerHTML: keyboard_arrow_down.ArrowDown }))), index.h("input", { key: '9eb1673f44e663f939124da45fec79c401736203', class: "s-hidden", name: this.name, required: this.required, value: this.color, ref: color => (this.colorInput = color) }))); } componentDidLoad() { if (this.canvas) this.canvas.style.backgroundColor = this.color; this.initColorPicker(); // Populate viewport cache in next frame (avoids forced reflow during initial render) requestAnimationFrame(() => this.updateViewportCache()); window.addEventListener('resize', this.updateViewportCache); if (this.colorInput) { this.colorInput.addEventListener('invalid', e => { this.invalidInput.emit(e); }); this.colorInput.addEventListener('input', () => { this.colorInput.setCustomValidity(''); this.colorInput.reportValidity(); }); } } get host() { return index.getElement(this); } }; SallaColorPicker.style = sallaColorPickerCss; const SallaConditionalFields = class { constructor(hostRef) { index.registerInstance(this, hostRef); } hideAllOptions(optionId) { this.host.querySelectorAll(`[data-show-when^="options[${optionId}"]`).forEach((field) => { field.classList.add('hidden'); this.hideAllOptions(field.dataset.optionId); this.disableInputs(field); }); } disableInputs(field) { field.querySelectorAll('[name]').forEach((node) => { const input = node; input.setAttribute('disabled', ''); input.removeAttribute('required'); if (input instanceof HTMLSelectElement) { input.value = ''; return; } if (input instanceof HTMLTextAreaElement) { input.value = ''; return; } if (input instanceof HTMLInputElement) { const t = (input.type || 'text').toLowerCase(); if (t === 'checkbox' || t === 'radio') { input.checked = false; return; } if (['text', 'search', 'number', 'tel', 'url', 'email'].includes(t)) { input.value = ''; } } }); } changeHandler(event) { salla.event.emit('salla-onditional-fields::change', event); salla.log('Received the change/input event: ', event); if (!event.target || (!['SELECT', 'INPUT', 'TEXTAREA'].includes(event.target.tagName) && !['checkbox', 'radio', 'text'].includes(event.target.getAttribute('type')))) { salla.log('Ignore the event because is not a supported input: ' + (event?.target?.tagName || 'N/A')); return; } // For text inputs, debounce the handling to improve performance on mobile const isTextInput = ['INPUT', 'TEXTAREA'].includes(event.target.tagName) && (!event.target.getAttribute('type') || event.target.getAttribute('type') === 'text'); if (isTextInput && event.type === 'input') { clearTimeout(this.debounceTimeout); this.debounceTimeout = setTimeout(() => { this.processConditionalFields(event); }, 300); // 300ms debounce for text inputs return; } // Process immediately for change events and non-text inputs this.processConditionalFields(event); } processConditionalFields(event) { let optionId = event.target.name.replace('[]', ''); let isMultiple = event.target.getAttribute('type') === 'checkbox'; let isRadio = event.target.getAttribute('type') === 'radio'; let isTextInput = ['INPUT', 'TEXTAREA'].includes(event.target.tagName) && (!event.target.getAttribute('type') || event.target.getAttribute('type') === 'text'); salla.log('Trying to find all elements with condition:', `[data-show-when^="${optionId}"]`); this.host.querySelectorAll(`[data-show-when^="${optionId}"]`) .forEach((field) => { let isEqual = !field?.dataset.showWhen.includes('!='); let value = field?.dataset.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$3').trim(); let isSelected; if (isMultiple) { let selectedValues = Array.from(this.host.querySelectorAll(`input[name="${event.target.name}"]:checked`), e => e?.value); isSelected = selectedValues.includes(value.toString()); } else if (isRadio) { // Handle radio inputs. isSelected = event.target.checked && event.target.value === value; } else if (isTextInput) { // Handle text inputs and textareas - check if value matches or is not empty for boolean conditions isSelected = value === event.target.value || (value.toLowerCase() === 'true' && event.target.value.trim() !== ''); } else { isSelected = value === event.target.value; } salla.log('The input is ', isMultiple ? 'Multiple' : isRadio ? 'Radio' : isTextInput ? 'Text' : 'Single', ' value:', isSelected); let showTheInput = (isEqual && isSelected) || (!isEqual && !isSelected); if (showTheInput) { field.classList.remove('hidden'); field.querySelectorAll('[name]').forEach((input) => { input.removeAttribute('disabled'); const closestProductOption = input.closest('.s-product-options-option'); if (closestProductOption.dataset.optionRequired === 'true') { input.setAttribute('required', ''); } if (input.getAttribute('type') === 'checkbox') { const checkboxes = Array.from(document.querySelectorAll(`input[type="checkbox"][name="${input.getAttribute('name')}"]`)); const isAnyChecked = checkboxes.some((checkbox) => checkbox.checked); if (isAnyChecked) { checkboxes.forEach((checkbox) => { checkbox.removeAttribute('required'); }); } } }); } else { this.hideAllOptions(field.dataset.optionId); field.classList.add('hidden'); this.disableInputs(field); } }); } componentDidRender() { this.host.querySelectorAll(`[data-show-when]`).forEach((field) => { // @ts-ignore let optionName = field?.dataset?.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$1').trim(); if (!optionName) { return; } this.changeHandler({ target: this.host.querySelector('[name^="' + optionName + '"]') }); }); } render() { return (index.h(index.Host, { key: '9931740a40a239483408056ae458769a0ab3997d' }, index.h("slot", { key: '6db0aa3b6db44f3811d1ed456672218891018d6f' }))); } get host() { return index.getElement(this); } }; const sallaDatetimePickerCss = ".flatpickr-calendar{background:transparent;opacity:0;display:none;text-align:center;visibility:hidden;padding:0;-webkit-animation:none;animation:none;direction:ltr;border:0;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-touch-action:manipulation;touch-action:manipulation;background:#fff;-webkit-box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08)}.flatpickr-calendar.open,.flatpickr-calendar.inline{opacity:1;max-height:640px;visibility:visible}.flatpickr-calendar.open{display:inline-block;z-index:99999}.flatpickr-calendar.animate.open{-webkit-animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1)}.flatpickr-calendar.inline{display:block;position:relative;top:2px}.flatpickr-calendar.static{position:absolute;top:calc(100% + 2px)}.flatpickr-calendar.static.open{z-index:999;display:block}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7){-webkit-box-shadow:none !important;box-shadow:none !important}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1){-webkit-box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-calendar .hasWeeks .dayContainer,.flatpickr-calendar .hasTime .dayContainer{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.flatpickr-calendar .hasWeeks .dayContainer{border-left:0}.flatpickr-calendar.hasTime .flatpickr-time{height:40px;border-top:1px solid #e6e6e6}.flatpickr-calendar.noCalendar.hasTime .flatpickr-time{height:auto}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar.rightMost:before,.flatpickr-calendar.arrowRight:before,.flatpickr-calendar.rightMost:after,.flatpickr-calendar.arrowRight:after{left:auto;right:22px}.flatpickr-calendar.arrowCenter:before,.flatpickr-calendar.arrowCenter:after{left:50%;right:50%}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-calendar:focus{outline:0}.flatpickr-wrapper{position:relative;display:inline-block}.flatpickr-months{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-months .flatpickr-month{background:transparent;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9);height:34px;line-height:1;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;cursor:pointer;position:absolute;top:0;height:34px;padding:10px;z-index:3;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9)}.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,.flatpickr-months .flatpickr-next-month.flatpickr-disabled{display:none}.flatpickr-months .flatpickr-prev-month i,.flatpickr-months .flatpickr-next-month i{position:relative}.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,.flatpickr-months .flatpickr-next-month.flatpickr-prev-month{left:0}.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,.flatpickr-months .flatpickr-next-month.flatpickr-next-month{right:0}.flatpickr-months .flatpickr-prev-month:hover,.flatpickr-months .flatpickr-next-month:hover{color:#959ea9}.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:#f64747}.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{width:14px;height:14px}.flatpickr-months .flatpickr-prev-month svg path,.flatpickr-months .flatpickr-next-month svg path{-webkit-transition:fill .1s;transition:fill .1s;fill:inherit}.numInputWrapper{position:relative;height:auto}.numInputWrapper input,.numInputWrapper span{display:inline-block}.numInputWrapper input{width:100%}.numInputWrapper input::-ms-clear{display:none}.numInputWrapper input::-webkit-outer-spin-button,.numInputWrapper input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.numInputWrapper span{position:absolute;right:0;width:14px;padding:0 4px 0 2px;height:50%;line-height:50%;opacity:0;cursor:pointer;border:1px solid rgba(57,57,57,0.15);-webkit-box-sizing:border-box;box-sizing:border-box}.numInputWrapper span:hover{background:rgba(0,0,0,0.1)}.numInputWrapper span:active{background:rgba(0,0,0,0.2)}.numInputWrapper span:after{display:block;content:\"\";position:absolute}.numInputWrapper span.arrowUp{top:0;border-bottom:0}.numInputWrapper span.arrowUp:after{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid rgba(57,57,57,0.6);top:26%}.numInputWrapper span.arrowDown{top:50%}.numInputWrapper span.arrowDown:after{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(57,57,57,0.6);top:40%}.numInputWrapper span svg{width:inherit;height:auto}.numInputWrapper span svg path{fill:rgba(0,0,0,0.5)}.numInputWrapper:hover{background:rgba(0,0,0,0.05)}.numInputWrapper:hover span{opacity:1}.flatpickr-current-month{font-size:135%;line-height:inherit;font-weight:300;color:inherit;position:absolute;width:75%;left:12.5%;padding:7.48px 0 0 0;line-height:1;height:34px;display:inline-block;text-align:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.flatpickr-current-month span.cur-month{font-family:inherit;font-weight:700;color:inherit;display:inline-block;margin-left:.5ch;padding:0}.flatpickr-current-month span.cur-month:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .numInputWrapper{width:6ch;width:7ch\\0;display:inline-block}.flatpickr-current-month .numInputWrapper span.arrowUp:after{border-bottom-color:rgba(0,0,0,0.9)}.flatpickr-current-month .numInputWrapper span.arrowDown:after{border-top-color:rgba(0,0,0,0.9)}.flatpickr-current-month input.cur-year{background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;cursor:text;padding:0 0 0 .5ch;margin:0;display:inline-block;font-size:inherit;font-family:inherit;font-weight:300;line-height:inherit;height:auto;border:0;border-radius:0;vertical-align:initial;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-current-month input.cur-year:focus{outline:0}.flatpickr-current-month input.cur-year[disabled],.flatpickr-current-month input.cur-year[disabled]:hover{font-size:100%;color:rgba(0,0,0,0.5);background:transparent;pointer-events:none}.flatpickr-current-month .flatpickr-monthDropdown-months{appearance:menulist;background:transparent;border:none;border-radius:0;box-sizing:border-box;color:inherit;cursor:pointer;font-size:inherit;font-family:inherit;font-weight:300;height:auto;line-height:inherit;margin:-1px 0 0 0;outline:none;padding:0 0 0 .5ch;position:relative;vertical-align:initial;-webkit-box-sizing:border-box;-webkit-appearance:menulist;-moz-appearance:menulist;width:auto}.flatpickr-current-month .flatpickr-monthDropdown-months:focus,.flatpickr-current-month .flatpickr-monthDropdown-months:active{outline:none}.flatpickr-current-month .flatpickr-monthDropdown-months:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month{background-color:transparent;outline:none;padding:0}.flatpickr-weekdays{background:transparent;text-align:center;overflow:hidden;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:28px}.flatpickr-weekdays .flatpickr-weekdaycontainer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}span.flatpickr-weekday{cursor:default;font-size:90%;background:transparent;color:rgba(0,0,0,0.54);line-height:1;margin:0;text-align:center;display:block;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;font-weight:bolder}.dayContainer,.flatpickr-weeks{padding:1px 0 0 0}.flatpickr-days{position:relative;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;width:307.875px}.flatpickr-days:focus{outline:0}.dayContainer{padding:0;outline:0;text-align:left;width:307.875px;min-width:307.875px;max-width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;display:-ms-flexbox;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-wrap:wrap;-ms-flex-pack:justify;-webkit-justify-content:space-around;justify-content:space-around;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}.dayContainer+.dayContainer{-webkit-box-shadow:-1px 0 0 #e6e6e6;box-shadow:-1px 0 0 #e6e6e6}.flatpickr-day{background:none;border:1px solid transparent;border-radius:150px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#393939;cursor:pointer;font-weight:400;width:14.2857143%;-webkit-flex-basis:14.2857143%;-ms-flex-preferred-size:14.2857143%;flex-basis:14.2857143%;max-width:39px;height:39px;line-height:39px;margin:0;display:inline-block;position:relative;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flatpickr-day.inRange,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.today.inRange,.flatpickr-day.nextMonthDay.today.inRange,.flatpickr-day:hover,.flatpickr-day.prevMonthDay:hover,.flatpickr-day.nextMonthDay:hover,.flatpickr-day:focus,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.nextMonthDay:focus{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#959ea9}.flatpickr-day.today:hover,.flatpickr-day.today:focus{border-color:#959ea9;background:#959ea9;color:#fff}.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected.inRange,.flatpickr-day.startRange.inRange,.flatpickr-day.endRange.inRange,.flatpickr-day.selected:focus,.flatpickr-day.startRange:focus,.flatpickr-day.endRange:focus,.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover,.flatpickr-day.selected.prevMonthDay,.flatpickr-day.startRange.prevMonthDay,.flatpickr-day.endRange.prevMonthDay,.flatpickr-day.selected.nextMonthDay,.flatpickr-day.startRange.nextMonthDay,.flatpickr-day.endRange.nextMonthDay{background:#569ff7;-webkit-box-shadow:none;box-shadow:none;color:#fff;border-color:#569ff7}.flatpickr-day.selected.startRange,.flatpickr-day.startRange.startRange,.flatpickr-day.endRange.startRange{border-radius:50px 0 0 50px}.flatpickr-day.selected.endRange,.flatpickr-day.startRange.endRange,.flatpickr-day.endRange.endRange{border-radius:0 50px 50px 0}.flatpickr-day.selected.startRange+.endRange:not(:nth-child(7n+1)),.flatpickr-day.startRange.startRange+.endRange:not(:nth-child(7n+1)),.flatpickr-day.endRange.startRange+.endRange:not(:nth-child(7n+1)){-webkit-box-shadow:-10px 0 0 #569ff7;box-shadow:-10px 0 0 #569ff7}.flatpickr-day.selected.startRange.endRange,.flatpickr-day.startRange.startRange.endRange,.flatpickr-day.endRange.startRange.endRange{border-radius:50px}.flatpickr-day.inRange{border-radius:0;-webkit-box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.notAllowed.nextMonthDay{color:rgba(57,57,57,0.3);background:transparent;border-color:transparent;cursor:default}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover{cursor:not-allowed;color:rgba(57,57,57,0.1)}.flatpickr-day.week.selected{border-radius:0;-webkit-box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7;box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7}.flatpickr-day.hidden{visibility:hidden}.rangeMode .flatpickr-day{margin-top:1px}.flatpickr-weekwrapper{float:left}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 12px;-webkit-box-shadow:1px 0 0 #e6e6e6;box-shadow:1px 0 0 #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%;line-height:28px}.flatpickr-weekwrapper span.flatpickr-day,.flatpickr-weekwrapper span.flatpickr-day:hover{display:block;width:100%;max-width:none;color:rgba(57,57,57,0.3);background:transparent;cursor:default;border:none}.flatpickr-innerContainer{display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}.flatpickr-rContainer{display:inline-block;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box}.flatpickr-time{text-align:center;outline:0;display:block;height:0;line-height:40px;max-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-time:after{content:\"\";display:table;clear:both}.flatpickr-time .numInputWrapper{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;width:40%;height:40px;float:left}.flatpickr-time .numInputWrapper span.arrowUp:after{border-bottom-color:#393939}.flatpickr-time .numInputWrapper span.arrowDown:after{border-top-color:#393939}.flatpickr-time.hasSeconds .numInputWrapper{width:26%}.flatpickr-time.time24hr .numInputWrapper{width:49%}.flatpickr-time input{background:transparent;-webkit-box-shadow:none;box-shadow:none;border:0;border-radius:0;text-align:center;margin:0;padding:0;height:inherit;line-height:inherit;color:#393939;font-size:14px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-time input.flatpickr-hour{font-weight:bold}.flatpickr-time input.flatpickr-minute,.flatpickr-time input.flatpickr-second{font-weight:400}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time .flatpickr-time-separator,.flatpickr-time .flatpickr-am-pm{height:inherit;float:left;line-height:inherit;color:#393939;font-weight:bold;width:2%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.flatpickr-time .flatpickr-am-pm{outline:0;width:18%;cursor:pointer;text-align:center;font-weight:400}.flatpickr-time input:hover,.flatpickr-time .flatpickr-am-pm:hover,.flatpickr-time input:focus,.flatpickr-time .flatpickr-am-pm:focus{background:#eee}.flatpickr-input[readonly]{cursor:pointer}@-webkit-keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}"; const SallaDatetimePicker = class { constructor(hostRef) { index.registerInstance(this, hostRef); this.picked = index.createEvent(this, "picked"); this.invalidInput = index.createEvent(this, "invalidInput"); /** * Two way data binding to retrieve the selected date[time] value */ this.value = null; /** * Placeholder text to show on the input element */ this.placeholder = salla.lang.get('blocks.buy_as_gift.select_send_date_and_time'); /** * Allows the user to enter a date directly into the input field. By default, direct entry is disabled. */ this.allowInput = true; /** * Allows the preloading of an invalid date. When disabled, the field will be cleared if the provided date is invalid */ this.allowInvalidPreload = false; /** * Exactly the same as date format, but for the altInput field. */ this.altFormat = "F j, Y"; /** * Show the user a readable date (as per altFormat), but return something totally different to the server. */ this.altInput = false; /** * Instead of body, appends the calendar to the specified node instead. */ this.appendTo = undefined; /** * Defines how the date will be formatted in the aria-label for calendar days, * using the same tokens as dateFormat. If you change this, you should choose a * value that will make sense if a screen reader reads it out loud. */ this.ariaDateFormat = "F j, Y"; /** * Whether the default time should be auto-filled when the input is empty and gains or loses focus. */ this.autoFillDefaultTime = true; /** * Whether clicking on the input should open the picker. * Set it to false if you only want to open the calendar programmatically with [open()] */ this.clickOpens = true; /** * Whether calendar should close after date selection or not */ this.closeOnSelect = true; /** * A string of characters which are used to define how the date will be displayed in the input box. * The supported characters are defined in the table below. */ this.dateFormat = "Y-m-d"; /** * Initial value of the hour element, when no date is selected */ this.defaultHour = 12; /** * Initial value of the minute element, when no date is selected */ this.defaultMinute = 0; /** * Initial value of the seconds element, when no date is selected */ this.defaultSeconds = 0; /** * Disables certain dates, preventing them from being selected. * See https://chmln.github.io/flatpickr/examples/#disabling-specific-dates */ this.disable = []; /** * Set this to true to always use the non-native picker on mobile devices. * By default, Flatpickr utilizes native datetime widgets unless certain options (e.g. disable) are used. */ this.disableMobile = false; /** * Disables all dates except these specified. See https://chmln.github.io/flatpickr/examples/#disabling-all-dates-except-select-few */ this.enable = [(_) => true]; /** * Enables seconds selection in the time picker. */ this.enableSeconds = false; /** * Enables the time picker */ this.enableTime = false; /** * Adjusts the step for the hour input (incl. scrolling) */ this.hourIncrement = 1; /** * Displays the calendar inline */ this.inline = false; /** * The locale, either as a string (e.g. "ar", "en") or as an object. * See https://chmln.github.io/flatpickr/localization/ */ this.locale = "en"; /** * The maximum date that a user can pick to (inclusive). */ this.maxDate = null; /** * The minimum date that a user can start picking from (inclusive). */ this.maxTime = null; /** * The minimum date that a user can start picking from (inclusive). */ this.minDate = null; /** * The minimum time that a user can start picking from (inclusive). */ this.minTime = null; /** * Adjusts the step for the minute input (incl. scrolling) Defaults to 5 */ this.minuteIncrement = 5; /** * Date selection mode, defaults to "single" */ this.mode = "single"; /** * How the month should be displayed in the header of the calendar. * If showMonths has a value greater than 1, the month is always shown as static. */ this.monthSelectorType = "dropdown"; /** * HTML for the arrow icon, used to switch months. */ this.nextArrow = '<span class="sicon-keyboard_arrow_right"></span>'; /** * Hides the day selection in calendar. Use it along with enableTime to create a time picker. */ this.noCalendar = false; /** * How the calendar should be positioned with regards to the input. Defaults to "auto" */ this.position = "auto"; /** * HTML for the left arrow icon, used to switch months. */ this.prevArrow = '<span class="sicon-keyboard_arrow_left"></span>'; /** * Whether to display the current month name in shorthand mode, e.g. "Sep" instead "September" */ this.shorthandCurrentMonth = false; /** * Position the calendar inside the wrapper and next to the input element*. */ this.static = false; /** * The number of months to be shown at the same time when displaying the calendar. */ this.showMonths = 1; /** * Displays time picker in 24 hour mode without AM/PM selection when enabled. */ this.time_24hr = false; /** * Enables display of week numbers in calendar. */ this.weekNumbers = false; /** * See https://chmln.github.io/flatpickr/examples/#flatpickr-external-elements */ this.wrap = false; /** * Whether the input is disabled */ this.disabled = false; } /** * Lazy load flatpickr library * This reduces initial bundle size by ~35-40KB */ async loadFlatpickr() { if (this.flatpickr) return; try { const flatpickrModule = await Promise.resolve().then(function () { return require('./index-D-dRbHuJ.js'); }); this.flatpickr = flatpickrModule.default; // Load locale if not English if (this.locale && this.locale !== 'en') { try {