@taprootio/espalier 4.8.0 → 4.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -61,6 +61,19 @@ export type { CalendarDay, DatePickerMode, ParsedValue } from "./helpers/types.j
61
61
  * </script>
62
62
  * ```
63
63
  *
64
+ * To reach a distant date quickly, click the month or the year in the
65
+ * calendar header. The month opens a grid of the twelve months and the
66
+ * year opens a scrolling list of years; choosing one moves the calendar
67
+ * there without changing the value. The header arrows step by month on
68
+ * the day grid, by year on the month grid, and by a page on the year
69
+ * list, and `Escape` returns to the day grid:
70
+ *
71
+ * ```html
72
+ * <esp-form-item label="Date of birth">
73
+ * <esp-date-picker value="1985-03-22"></esp-date-picker>
74
+ * </esp-form-item>
75
+ * ```
76
+ *
64
77
  * Because the picker is form-associated, its value is included when
65
78
  * the form is submitted and it responds to form resets:
66
79
  *
@@ -1,10 +1,10 @@
1
- var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(f,e,t,i);else for(var l=f.length-1;l>=0;l--)(a=f[l])&&(s=(o<3?a(s):o>3?a(e,t,s):a(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s},_;import{html as d,nothing as w}from"lit";import{customElement as $,property as u,state as p}from"lit/decorators.js";import{classMap as C}from"lit/directives/class-map.js";import{createRef as g,ref as v}from"lit/directives/ref.js";import{repeat as A}from"lit/directives/repeat.js";import{EspalierElementBase as P}from"../shared/esp-element-base.js";import{PopoverController as M}from"../shared/popover-controller.js";import{scrollToContainAnchoredSurface as F,spaceAroundRect as E,viewportSize as D}from"../shared/viewport.js";import{FormFieldController as G}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as x}from"../shared/form-field-description-controller.js";import{leftArrow as O}from"../shared/svgs/left-arrow.js";import{rightArrow as V}from"../shared/svgs/right-arrow.js";import{checkSVG as b}from"../shared/svgs/check.js";import{cancelSVG as S}from"../shared/svgs/cancel.js";import"../button/esp-button.js";import"../pickers/esp-pick-one.js";import"../pickers/esp-picker-item.js";import{GRID_COLS as k,GRID_ROWS as q,GRID_SIZE as L,HOURS_12 as I,MINUTES_60 as B,MONTH_NAMES as R,WEEKDAY_LABELS as X}from"./helpers/constants.js";import{displayValue as Y,formatDate as T,parseValue as U}from"./helpers/parsing.js";import{generateCalendarGrid as W,getEffectiveRange as z,getSelectedDate as H,isDateDisabled as N,parseDateBound as y}from"./helpers/calendar-grid.js";import{calendarIcon as K}from"../shared/svgs/calendar-icon.js";import{datePickerStyles as j}from"./helpers/styles.js";let r=_=class extends P{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new G({host:this,internals:this.internals,getFormValue:()=>this._value||null,getValidity:()=>this._getValidityResult(),getValidationAnchor:()=>this.inputRef.value??this,onReset:()=>{this._rangeAnchor=null,this._rangePreview=null,this._value="",this.requestUpdate("value",""),this._syncFromValue()},onRestore:e=>{this.value=e},onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new x({host:this,getTarget:()=>this.inputRef.value}),this.popoverCtrl=new M({host:this,closeStrategy:"source-identity",isOpen:()=>this.open,onShouldClose:()=>this._closePopover(),onPositionUpdate:()=>this._positionPopover(),shouldContinueTracking:()=>{const e=this.getBoundingClientRect(),{height:t}=D();return!(e.bottom<0||e.top>t)},getInsideElements:()=>[this.popoverRef.value??null],onOutsideClick:()=>this._closePopover()}),this.inputRef=g(),this.popoverRef=g(),this.calBodyRef=g(),this.timePickerRef=g(),this._containRepositionFrame=null,this.temporalSupported=!0,this.mode="date",this._value="",this.placeholder="Select...",this.min="",this.max="",this.disabled=!1,this.name="",this.required=!1,this.requiredMessage="",this.open=!1,this.parsed={kind:"none"},this._parsedMinDate=null,this._parsedMaxDate=null,this._hour=12,this._minute=0,this._period="AM",this._rangeAnchor=null,this._rangePreview=null,this._cachedGridKey="",this._cachedGrid=[],this._valueOnOpen="",this._touchStartX=0,this._touchStartY=0,this._touchGesture="none",this._swipeAnimating=!1,this._swipeAnimationGeneration=0,this._longPressTimer=0,this._edgeScrollTimer=0}get value(){return this._value}set value(e){const t=this._value;this._value=e,this.requestUpdate("value",t),this._syncFromValue(),this.formCtrl.syncValue()}get _rangePhase(){return this._rangeAnchor?this.parsed.kind==="range"?"complete":"start":"empty"}_getGrid(){const e=[this.viewDate?.toString(),this._value,this._rangeAnchor?.toString()??"",this._rangePreview?.toString()??""].join("|");if(e!==this._cachedGridKey){this._cachedGridKey=e;const t=H(this.parsed),{start:i,end:o}=z(this.mode,this.parsed,this._rangeAnchor,this._rangePreview);this._cachedGrid=W(this.viewDate,t,i,o,this._minDate,this._maxDate)}return this._cachedGrid}_dateAtPoint(e,t){const i=this.shadowRoot?.elementsFromPoint(e,t);if(!i)return null;for(const o of i){const s=o.dataset?.date;if(s)try{return Temporal.PlainDate.from(s)}catch{return null}}return null}_edgeSide(e){const t=this.shadowRoot?.querySelector(".calendar");if(!t)return null;const i=t.getBoundingClientRect(),o=this.shadowRoot?.querySelector(".day-cell"),s=o?o.getBoundingClientRect().width:32;return e<=i.left+s?"left":e>=i.right-s?"right":null}_onCalendarTouchStart(e){if(e.touches.length!==1||this._swipeAnimating)return;const t=e.touches[0];if(this._touchStartX=t.clientX,this._touchStartY=t.clientY,this._touchGesture="pending",this._clearLongPressTimer(),this.mode==="range"&&this._rangePhase!=="empty"){const i=this.shadowRoot?.querySelector(".calendar");i&&(i.style.touchAction="none"),this._longPressTimer=window.setTimeout(()=>{if(this._longPressTimer=0,this._touchGesture!=="pending")return;this._touchGesture="drag";const o=this._dateAtPoint(this._touchStartX,this._touchStartY);o&&!this._isDateDisabled(o)&&(this._rangePhase==="complete"&&(this._rangeAnchor=o,this._value="",this.parsed={kind:"none"},this.formCtrl.syncValue()),this._rangePreview=o,this.requestUpdate())},_.LONG_PRESS_MS)}}_onCalendarTouchMove(e){if(e.touches.length!==1||this._swipeAnimating||this._touchGesture==="none")return;const t=e.touches[0],i=t.clientX-this._touchStartX,o=t.clientY-this._touchStartY;if(this._touchGesture==="drag"){e.cancelable&&e.preventDefault();const s=this._dateAtPoint(t.clientX,t.clientY);s&&!this._isDateDisabled(s)&&(this._rangePreview=s),this._handleEdgeScroll(t.clientX);return}if(this._touchGesture==="pending"){if(Math.abs(i)<10&&Math.abs(o)<10)return;if(this._clearLongPressTimer(),Math.abs(o)>Math.abs(i)){this._touchGesture="none",this._resetTouchAction();return}this._touchGesture="swipe"}if(this._touchGesture==="swipe"){e.cancelable&&e.preventDefault();const s=this.calBodyRef.value;s&&(s.style.transition="none",s.style.transform=`translateX(${i}px)`)}}_onCalendarTouchEnd(e){this._clearLongPressTimer(),this._clearEdgeScrollTimer(),this._resetTouchAction();const t=this._touchGesture;if(this._touchGesture="none",t==="drag"){if(e.changedTouches.length===1){const o=e.changedTouches[0];let s=this._dateAtPoint(o.clientX,o.clientY);if(s||(s=this._rangePreview),s&&!this._isDateDisabled(s)&&this._rangeAnchor){const a=this._rangeAnchor;let l,c;Temporal.PlainDate.compare(s,a)<0?(l=s,c=a):(l=a,c=s),this._rangePreview=null,this.value=`${l.toString()}/${c.toString()}`,this._dispatchValueChanged()}}return}if(t==="swipe"){this._finishSwipe(e);return}const i=this.calBodyRef.value;i&&(i.style.transition="",i.style.transform="")}_finishSwipe(e){const t=this.calBodyRef.value;if(!t||e.changedTouches.length!==1){t&&(t.style.transition="",t.style.transform="");return}const o=e.changedTouches[0].clientX-this._touchStartX,s=t.offsetWidth;if(Math.abs(o)>=30){const a=o<0?1:-1,l=a===1?-s:s,c=++this._swipeAnimationGeneration;this._swipeAnimating=!0,t.style.transition="transform 150ms ease-in",t.style.transform=`translateX(${l}px)`,t.addEventListener("transitionend",()=>{c!==this._swipeAnimationGeneration||!this.open||!this.isConnected||(this._navigateMonth(a),this.updateComplete.then(()=>{if(c!==this._swipeAnimationGeneration||!this.open||!this.isConnected)return;const h=this.calBodyRef.value;if(!h){this._swipeAnimating=!1;return}h.style.transition="none",h.style.transform=`translateX(${-l}px)`,h.getBoundingClientRect(),h.style.transition="transform 150ms ease-out",h.style.transform="",h.addEventListener("transitionend",()=>{c===this._swipeAnimationGeneration&&(h.style.transition="",this._swipeAnimating=!1)},{once:!0})}))},{once:!0})}else t.style.transition="transform 150ms ease-out",t.style.transform="",t.addEventListener("transitionend",()=>{t.style.transition=""},{once:!0})}_resetSwipeAnimation(){this._swipeAnimationGeneration+=1,this._swipeAnimating=!1;const e=this.calBodyRef.value;e&&(e.style.transition="",e.style.transform="")}_clearLongPressTimer(){this._longPressTimer&&(clearTimeout(this._longPressTimer),this._longPressTimer=0)}_handleEdgeScroll(e){const t=this._edgeSide(e);if(!t){this._clearEdgeScrollTimer();return}if(this._edgeScrollTimer)return;const i=t==="right"?1:-1;this._edgeScrollTimer=window.setTimeout(async()=>{this._edgeScrollTimer=0,this._touchGesture==="drag"&&(this._navigateMonth(i),await this.updateComplete)},_.EDGE_SCROLL_MS)}_clearEdgeScrollTimer(){this._edgeScrollTimer&&(clearTimeout(this._edgeScrollTimer),this._edgeScrollTimer=0)}_resetTouchAction(){const e=this.shadowRoot?.querySelector(".calendar");e&&e.style.removeProperty("touch-action")}connectedCallback(){if(super.connectedCallback(),typeof window.Temporal>"u"){this.temporalSupported=!1;return}this.viewDate||(this.viewDate=Temporal.Now.plainDateISO().toPlainYearMonth()),this.focusedDate||(this.focusedDate=Temporal.Now.plainDateISO()),this._parsedMinDate=y(this.min),this._parsedMaxDate=y(this.max),this._syncFromValue(),this.formCtrl.validate()}disconnectedCallback(){this._resetSwipeAnimation(),this._containRepositionFrame!==null&&(cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=null),super.disconnectedCallback()}willUpdate(e){super.willUpdate(e),e.has("min")&&(this._parsedMinDate=y(this.min)),e.has("max")&&(this._parsedMaxDate=y(this.max))}updated(e){super.updated(e),e.has("disabled")&&(this.internals.ariaDisabled=this.disabled?"true":"false"),e.has("required")&&(this.internals.ariaRequired=this.required?"true":"false",this.formCtrl.validate()),(e.has("min")||e.has("max"))&&this.formCtrl.validate()}focus(e){this.focusResolvedElementAfterUpdate(()=>this.inputRef.value,e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}setFormItemLabel(e){this.formItemDescription.setLabel(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}_syncFromValue(){if(this.temporalSupported)switch(this.parsed=U(this._value,this.mode),this.parsed.kind){case"date":this.viewDate=this.parsed.date.toPlainYearMonth(),this.focusedDate=this.parsed.date;break;case"datetime":{this.viewDate=this.parsed.datetime.toPlainDate().toPlainYearMonth(),this.focusedDate=this.parsed.datetime.toPlainDate();const e=this.parsed.datetime.toPlainTime(),t=e.hour;this._period=t>=12?"PM":"AM",this._hour=t===0?12:t>12?t-12:t,this._minute=e.minute;break}case"time":{const e=this.parsed.time,t=e.hour;this._period=t>=12?"PM":"AM",this._hour=t===0?12:t>12?t-12:t,this._minute=e.minute;break}case"range":this.viewDate=this.parsed.start.toPlainYearMonth(),this.focusedDate=this.parsed.start,this._rangeAnchor=this.parsed.start,this._rangePreview=null;break;case"none":break}}_getValidityResult(){if(!this.temporalSupported)return null;if(this.required&&!this._value)return{flags:{valueMissing:!0},message:this.requiredMessage||"Please select a date."};if(this._value&&this.parsed.kind==="none")return{flags:{typeMismatch:!0},message:"The value is not a valid date."};const e=this._getValidationDates();if(e.length>0){const t=this._minDate,i=this._maxDate;if(t){for(const o of e)if(Temporal.PlainDate.compare(o,t)<0)return{flags:{rangeUnderflow:!0},message:`Date must not be before ${T(t)}.`}}if(i){for(const o of e)if(Temporal.PlainDate.compare(o,i)>0)return{flags:{rangeOverflow:!0},message:`Date must not be after ${T(i)}.`}}}return null}_getValidationDates(){switch(this.parsed.kind){case"date":return[this.parsed.date];case"datetime":return[this.parsed.datetime.toPlainDate()];case"range":return[this.parsed.start,this.parsed.end];default:return[]}}get _minDate(){return this._parsedMinDate}get _maxDate(){return this._parsedMaxDate}_isDateDisabled(e){return N(e,this._minDate,this._maxDate)}_navigateMonth(e){this.viewDate=this.viewDate.add({months:e}),this.focusedDate=this.viewDate.toPlainDate({day:Math.min(this.focusedDate.day,this.viewDate.daysInMonth)})}_moveFocus(e){const t=this.focusedDate.add({days:e});if(this._isDateDisabled(t)){const o=e>0?1:-1;let s=t;for(let a=0;a<L&&this._isDateDisabled(s);a++)s=s.add({days:o});this.focusedDate=s}else this.focusedDate=t;const i=this.focusedDate.toPlainYearMonth();Temporal.PlainYearMonth.compare(i,this.viewDate)!==0&&(this.viewDate=i),this.mode==="range"&&this._rangePhase==="start"&&(this._rangePreview=this.focusedDate)}_selectDate(e){if(!this._isDateDisabled(e)){switch(this.mode){case"date":this.value=e.toString(),this._closePopover(),this.inputRef.value?.focus();break;case"datetime":{const t=this.parsed.kind==="datetime"?this.parsed.datetime.toPlainTime():new Temporal.PlainTime;this.value=e.toPlainDateTime(t).toString();break}case"range":this._selectRangeEndpoint(e);break}this._dispatchValueChanged()}}_selectRangeEndpoint(e){switch(this._rangePhase){case"empty":case"complete":this._rangeAnchor=e,this._rangePreview=null,this._value="",this.parsed={kind:"none"},this.formCtrl.syncValue(),this.requestUpdate();break;case"start":{const i=this._rangeAnchor;let o,s;Temporal.PlainDate.compare(e,i)<0?(o=e,s=i):(o=i,s=e),this._rangePreview=null,this.value=`${o.toString()}/${s.toString()}`;break}}}_dispatchValueChanged(){this.emitValueChanged(this._value)}get _showTimePicker(){return this.mode==="time"||this.mode==="datetime"}get _showCalendar(){return this.mode!=="time"}_commitTime(){let e=this._hour%12;this._period==="PM"&&(e+=12);const t=new Temporal.PlainTime(e,this._minute);if(this.mode==="time")this.value=t.toString();else if(this.mode==="datetime"){const i=this.parsed.kind==="datetime"?this.parsed.datetime.toPlainDate():this.parsed.kind==="date"?this.parsed.date:Temporal.Now.plainDateISO();this.value=i.toPlainDateTime(t).toString()}this._dispatchValueChanged()}async _openPopover(){if(this.disabled||(this.popoverCtrl.publishCloseOthers(),this._valueOnOpen=this._value,this.open=!0,this._positionPopover(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick(),await this.updateComplete,!this.open||!this.isConnected))return;this._shrinkTimePickerToFit(),this._scrollToContainPopover();const t=this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]');requestAnimationFrame(()=>{this.open&&this.isConnected&&t?.focus()})}_closePopover(){this.open=!1,this._resetSwipeAnimation(),this._containRepositionFrame!==null&&(cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=null);const e=this.popoverRef.value;if(e){e.classList.remove("visible");try{e.hidePopover()}catch{}}this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.mode==="range"&&this._rangePhase==="start"&&(this._rangeAnchor=null,this._rangePreview=null)}_togglePopover(){this.open?this._closePopover():this._openPopover()}_positionPopover(){if(!this.open)return;const e=this.popoverRef.value;if(!e)return;const t=this.getBoundingClientRect(),{width:i,height:o}=D(),{spaceAbove:s,spaceBelow:a}=E(t,o);e.matches(":popover-open")||e.showPopover(),e.style.removeProperty("top"),e.style.removeProperty("bottom"),e.style.removeProperty("font-size"),e.style.setProperty("width","min-content"),this._shrinkToFitViewport(e,i);let l=t.left;const c=e.offsetWidth;l+c>i&&(l=Math.max(0,i-c)),e.style.setProperty("left",`${l}px`);const h=e.offsetHeight;if(s>a){let m=o-t.top;h>s&&(m=o-h),e.style.setProperty("bottom",`${m}px`)}else{let m=t.bottom;h>a&&(m=o-h),e.style.setProperty("top",`${Math.max(0,m)}px`)}requestAnimationFrame(()=>e.classList.add("visible"))}_shrinkToFitViewport(e,t){if(e.offsetWidth<=t)return;const i=getComputedStyle(e);let o=parseFloat(i.fontSize);const s=8;for(;e.offsetWidth>t&&o>s;)o-=.5,e.style.setProperty("font-size",`${o}px`)}_shrinkTimePickerToFit(){const e=this.timePickerRef.value,t=this.popoverRef.value;if(!e||!t)return;e.style.removeProperty("font-size");const i=t.clientWidth;if(e.scrollWidth<=i)return;const o=getComputedStyle(e);let s=parseFloat(o.fontSize);const a=8;for(;e.scrollWidth>i&&s>a;)s-=.5,e.style.setProperty("font-size",`${s}px`)}_scrollToContainPopover(){const e=this.popoverRef.value;e&&(this._containRepositionFrame!==null&&cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=F(this,e,()=>{this._containRepositionFrame=null,this.open&&this._positionPopover()}))}async _handleGridKeyDown(e){let t=!0;switch(e.key){case"ArrowLeft":this._moveFocus(-1);break;case"ArrowRight":this._moveFocus(1);break;case"ArrowUp":this._moveFocus(-7);break;case"ArrowDown":this._moveFocus(7);break;case"Home":{const i=this.focusedDate.dayOfWeek;i>1&&this._moveFocus(-(i-1));break}case"End":{const i=this.focusedDate.dayOfWeek;i<7&&this._moveFocus(7-i);break}case"PageUp":this._navigateMonth(e.shiftKey?-12:-1);break;case"PageDown":this._navigateMonth(e.shiftKey?12:1);break;case"Enter":case" ":this._selectDate(this.focusedDate);break;case"Escape":this._closePopover(),this.inputRef.value?.focus();break;default:t=!1}t&&(e.preventDefault(),e.stopPropagation(),await this.updateComplete,this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]')?.focus())}_onDayCellHover(e){this.mode==="range"&&this._rangePhase==="start"&&(this._rangePreview=e)}render(){return this.temporalSupported?d`
1
+ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")a=Reflect.decorate(y,e,t,i);else for(var h=y.length-1;h>=0;h--)(o=y[h])&&(a=(s<3?o(a):s>3?o(e,t,a):o(e,t))||a);return s>3&&a&&Object.defineProperty(e,t,a),a},f;import{html as l,nothing as _}from"lit";import{customElement as C,property as p,state as d}from"lit/decorators.js";import{classMap as D}from"lit/directives/class-map.js";import{createRef as g,ref as v}from"lit/directives/ref.js";import{repeat as x}from"lit/directives/repeat.js";import{EspalierElementBase as P}from"../shared/esp-element-base.js";import{PopoverController as F}from"../shared/popover-controller.js";import{scrollToContainAnchoredSurface as E,spaceAroundRect as G,viewportSize as S}from"../shared/viewport.js";import{FormFieldController as Y}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as O}from"../shared/form-field-description-controller.js";import{leftArrow as V}from"../shared/svgs/left-arrow.js";import{rightArrow as L}from"../shared/svgs/right-arrow.js";import{checkSVG as k}from"../shared/svgs/check.js";import{cancelSVG as $}from"../shared/svgs/cancel.js";import"../button/esp-button.js";import"../pickers/esp-pick-one.js";import"../pickers/esp-picker-item.js";import{GRID_COLS as R,GRID_ROWS as j,GRID_SIZE as B,HOURS_12 as q,MINUTES_60 as W,MONTH_GRID_COLS as T,MONTH_NAMES as w,MONTH_SHORT_NAMES as H,WEEKDAY_LABELS as I}from"./helpers/constants.js";import{displayValue as z,formatDate as M,parseValue as U}from"./helpers/parsing.js";import{clampMonthToBounds as X,generateCalendarGrid as N,generateYearWindow as K,getEffectiveRange as Z,getSelectedDate as J,isDateDisabled as Q,isMonthDisabled as A,parseDateBound as b}from"./helpers/calendar-grid.js";import{calendarIcon as ee}from"../shared/svgs/calendar-icon.js";import{datePickerStyles as te}from"./helpers/styles.js";let r=f=class extends P{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new Y({host:this,internals:this.internals,getFormValue:()=>this._value||null,getValidity:()=>this._getValidityResult(),getValidationAnchor:()=>this.inputRef.value??this,onReset:()=>{this._rangeAnchor=null,this._rangePreview=null,this._value="",this.requestUpdate("value",""),this._syncFromValue()},onRestore:e=>{this.value=e},onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new O({host:this,getTarget:()=>this.inputRef.value}),this.popoverCtrl=new F({host:this,closeStrategy:"source-identity",isOpen:()=>this.open,onShouldClose:()=>this._closePopover(),onPositionUpdate:()=>this._positionPopover(),shouldContinueTracking:()=>{const e=this.getBoundingClientRect(),{height:t}=S();return!(e.bottom<0||e.top>t)},getInsideElements:()=>[this.popoverRef.value??null],onOutsideClick:()=>this._closePopover()}),this.inputRef=g(),this.popoverRef=g(),this.calBodyRef=g(),this.timePickerRef=g(),this.yearListRef=g(),this._containRepositionFrame=null,this.temporalSupported=!0,this.mode="date",this._value="",this.placeholder="Select...",this.min="",this.max="",this.disabled=!1,this.name="",this.required=!1,this.requiredMessage="",this._surface="days",this._jumpFocus=0,this._yearWindow=[],this._pinnedBodySize=null,this.open=!1,this.parsed={kind:"none"},this._parsedMinDate=null,this._parsedMaxDate=null,this._hour=12,this._minute=0,this._period="AM",this._rangeAnchor=null,this._rangePreview=null,this._cachedGridKey="",this._cachedGrid=[],this._valueOnOpen="",this._touchStartX=0,this._touchStartY=0,this._touchGesture="none",this._swipeAnimating=!1,this._swipeAnimationGeneration=0,this._longPressTimer=0,this._edgeScrollTimer=0}get value(){return this._value}set value(e){const t=this._value;this._value=e,this.requestUpdate("value",t),this._syncFromValue(),this.formCtrl.syncValue()}get _rangePhase(){return this._rangeAnchor?this.parsed.kind==="range"?"complete":"start":"empty"}_getGrid(){const e=[this.viewDate?.toString(),this._value,this._rangeAnchor?.toString()??"",this._rangePreview?.toString()??""].join("|");if(e!==this._cachedGridKey){this._cachedGridKey=e;const t=J(this.parsed),{start:i,end:s}=Z(this.mode,this.parsed,this._rangeAnchor,this._rangePreview);this._cachedGrid=N(this.viewDate,t,i,s,this._minDate,this._maxDate)}return this._cachedGrid}_dateAtPoint(e,t){const i=this.shadowRoot?.elementsFromPoint(e,t);if(!i)return null;for(const s of i){const a=s.dataset?.date;if(a)try{return Temporal.PlainDate.from(a)}catch{return null}}return null}_edgeSide(e){const t=this.shadowRoot?.querySelector(".calendar");if(!t)return null;const i=t.getBoundingClientRect(),s=this.shadowRoot?.querySelector(".day-cell"),a=s?s.getBoundingClientRect().width:32;return e<=i.left+a?"left":e>=i.right-a?"right":null}_onCalendarTouchStart(e){if(e.touches.length!==1||this._swipeAnimating||this._surface!=="days")return;const t=e.touches[0];if(this._touchStartX=t.clientX,this._touchStartY=t.clientY,this._touchGesture="pending",this._clearLongPressTimer(),this.mode==="range"&&this._rangePhase!=="empty"){const i=this.shadowRoot?.querySelector(".calendar");i&&(i.style.touchAction="none"),this._longPressTimer=window.setTimeout(()=>{if(this._longPressTimer=0,this._touchGesture!=="pending")return;this._touchGesture="drag";const s=this._dateAtPoint(this._touchStartX,this._touchStartY);s&&!this._isDateDisabled(s)&&(this._rangePhase==="complete"&&(this._rangeAnchor=s,this._value="",this.parsed={kind:"none"},this.formCtrl.syncValue()),this._rangePreview=s,this.requestUpdate())},f.LONG_PRESS_MS)}}_onCalendarTouchMove(e){if(e.touches.length!==1||this._swipeAnimating||this._touchGesture==="none")return;const t=e.touches[0],i=t.clientX-this._touchStartX,s=t.clientY-this._touchStartY;if(this._touchGesture==="drag"){e.cancelable&&e.preventDefault();const a=this._dateAtPoint(t.clientX,t.clientY);a&&!this._isDateDisabled(a)&&(this._rangePreview=a),this._handleEdgeScroll(t.clientX);return}if(this._touchGesture==="pending"){if(Math.abs(i)<10&&Math.abs(s)<10)return;if(this._clearLongPressTimer(),Math.abs(s)>Math.abs(i)){this._touchGesture="none",this._resetTouchAction();return}this._touchGesture="swipe"}if(this._touchGesture==="swipe"){e.cancelable&&e.preventDefault();const a=this.calBodyRef.value;a&&(a.style.transition="none",a.style.transform=`translateX(${i}px)`)}}_onCalendarTouchEnd(e){this._clearLongPressTimer(),this._clearEdgeScrollTimer(),this._resetTouchAction();const t=this._touchGesture;if(this._touchGesture="none",t==="drag"){if(e.changedTouches.length===1){const s=e.changedTouches[0];let a=this._dateAtPoint(s.clientX,s.clientY);if(a||(a=this._rangePreview),a&&!this._isDateDisabled(a)&&this._rangeAnchor){const o=this._rangeAnchor;let h,u;Temporal.PlainDate.compare(a,o)<0?(h=a,u=o):(h=o,u=a),this._rangePreview=null,this.value=`${h.toString()}/${u.toString()}`,this._dispatchValueChanged()}}return}if(t==="swipe"){this._finishSwipe(e);return}const i=this.calBodyRef.value;i&&(i.style.transition="",i.style.transform="")}_finishSwipe(e){const t=this.calBodyRef.value;if(!t||e.changedTouches.length!==1){t&&(t.style.transition="",t.style.transform="");return}const s=e.changedTouches[0].clientX-this._touchStartX,a=t.offsetWidth;if(Math.abs(s)>=30){const o=s<0?1:-1,h=o===1?-a:a,u=++this._swipeAnimationGeneration;this._swipeAnimating=!0,t.style.transition="transform 150ms ease-in",t.style.transform=`translateX(${h}px)`,t.addEventListener("transitionend",()=>{u!==this._swipeAnimationGeneration||!this.open||!this.isConnected||(this._navigateMonth(o),this.updateComplete.then(()=>{if(u!==this._swipeAnimationGeneration||!this.open||!this.isConnected)return;const c=this.calBodyRef.value;if(!c){this._swipeAnimating=!1;return}c.style.transition="none",c.style.transform=`translateX(${-h}px)`,c.getBoundingClientRect(),c.style.transition="transform 150ms ease-out",c.style.transform="",c.addEventListener("transitionend",()=>{u===this._swipeAnimationGeneration&&(c.style.transition="",this._swipeAnimating=!1)},{once:!0})}))},{once:!0})}else t.style.transition="transform 150ms ease-out",t.style.transform="",t.addEventListener("transitionend",()=>{t.style.transition=""},{once:!0})}_resetSwipeAnimation(){this._swipeAnimationGeneration+=1,this._swipeAnimating=!1;const e=this.calBodyRef.value;e&&(e.style.transition="",e.style.transform="")}_clearLongPressTimer(){this._longPressTimer&&(clearTimeout(this._longPressTimer),this._longPressTimer=0)}_handleEdgeScroll(e){const t=this._edgeSide(e);if(!t){this._clearEdgeScrollTimer();return}if(this._edgeScrollTimer)return;const i=t==="right"?1:-1;this._edgeScrollTimer=window.setTimeout(async()=>{this._edgeScrollTimer=0,this._touchGesture==="drag"&&(this._navigateMonth(i),await this.updateComplete)},f.EDGE_SCROLL_MS)}_clearEdgeScrollTimer(){this._edgeScrollTimer&&(clearTimeout(this._edgeScrollTimer),this._edgeScrollTimer=0)}_resetTouchAction(){const e=this.shadowRoot?.querySelector(".calendar");e&&e.style.removeProperty("touch-action")}connectedCallback(){if(super.connectedCallback(),typeof window.Temporal>"u"){this.temporalSupported=!1;return}this.viewDate||(this.viewDate=Temporal.Now.plainDateISO().toPlainYearMonth()),this.focusedDate||(this.focusedDate=Temporal.Now.plainDateISO()),this._parsedMinDate=b(this.min),this._parsedMaxDate=b(this.max),this._syncFromValue(),this.formCtrl.validate()}disconnectedCallback(){this._resetSwipeAnimation(),this._containRepositionFrame!==null&&(cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=null),super.disconnectedCallback()}willUpdate(e){if(super.willUpdate(e),e.has("min")&&(this._parsedMinDate=b(this.min)),e.has("max")&&(this._parsedMaxDate=b(this.max)),e.has("mode")&&this.open){const t=!!this.shadowRoot?.activeElement;this._closePopover(),t&&this.inputRef.value?.focus()}e.has("value")&&this._surface==="months"&&(this._jumpFocus=this.viewDate.month),(e.has("min")||e.has("max")||e.has("value"))&&this._surface==="years"&&this._openYearWindow(e.has("value")?this.viewDate.year:this._jumpFocus)}updated(e){super.updated(e),e.has("disabled")&&(this.internals.ariaDisabled=this.disabled?"true":"false"),e.has("required")&&(this.internals.ariaRequired=this.required?"true":"false",this.formCtrl.validate()),(e.has("min")||e.has("max"))&&this.formCtrl.validate(),e.has("_surface")?this._applySurfaceChange(e.get("_surface")):(e.has("min")||e.has("max")||e.has("value"))&&this._surface==="years"&&this.open?(this._scrollYearIntoView(this._jumpFocus,e.has("value")?"center":"nearest"),this._focusSurface()):e.has("value")&&this._surface==="months"&&this.open&&this._focusSurface()}focus(e){this.focusResolvedElementAfterUpdate(()=>this.inputRef.value,e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}setFormItemLabel(e){this.formItemDescription.setLabel(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}_syncFromValue(){if(this.temporalSupported)switch(this.parsed=U(this._value,this.mode),this.parsed.kind){case"date":this.viewDate=this.parsed.date.toPlainYearMonth(),this.focusedDate=this.parsed.date;break;case"datetime":{this.viewDate=this.parsed.datetime.toPlainDate().toPlainYearMonth(),this.focusedDate=this.parsed.datetime.toPlainDate();const e=this.parsed.datetime.toPlainTime(),t=e.hour;this._period=t>=12?"PM":"AM",this._hour=t===0?12:t>12?t-12:t,this._minute=e.minute;break}case"time":{const e=this.parsed.time,t=e.hour;this._period=t>=12?"PM":"AM",this._hour=t===0?12:t>12?t-12:t,this._minute=e.minute;break}case"range":this.viewDate=this.parsed.start.toPlainYearMonth(),this.focusedDate=this.parsed.start,this._rangeAnchor=this.parsed.start,this._rangePreview=null;break;case"none":break}}_getValidityResult(){if(!this.temporalSupported)return null;if(this.required&&!this._value)return{flags:{valueMissing:!0},message:this.requiredMessage||"Please select a date."};if(this._value&&this.parsed.kind==="none")return{flags:{typeMismatch:!0},message:"The value is not a valid date."};const e=this._getValidationDates();if(e.length>0){const t=this._minDate,i=this._maxDate;if(t){for(const s of e)if(Temporal.PlainDate.compare(s,t)<0)return{flags:{rangeUnderflow:!0},message:`Date must not be before ${M(t)}.`}}if(i){for(const s of e)if(Temporal.PlainDate.compare(s,i)>0)return{flags:{rangeOverflow:!0},message:`Date must not be after ${M(i)}.`}}}return null}_getValidationDates(){switch(this.parsed.kind){case"date":return[this.parsed.date];case"datetime":return[this.parsed.datetime.toPlainDate()];case"range":return[this.parsed.start,this.parsed.end];default:return[]}}get _minDate(){return this._parsedMinDate}get _maxDate(){return this._parsedMaxDate}_isDateDisabled(e){return Q(e,this._minDate,this._maxDate)}_navigateMonth(e){this._setViewMonth(this.viewDate.add({months:e}))}_setViewMonth(e){this.viewDate=e;let t=e.toPlainDate({day:Math.min(this.focusedDate.day,e.daysInMonth)});const i=this._minDate,s=this._maxDate;i&&Temporal.PlainDate.compare(t,i)<0&&Temporal.PlainYearMonth.compare(i.toPlainYearMonth(),e)===0&&(t=i),s&&Temporal.PlainDate.compare(t,s)>0&&Temporal.PlainYearMonth.compare(s.toPlainYearMonth(),e)===0&&(t=s),this.focusedDate=t}_navigateHeader(e){switch(this._surface){case"days":this._navigateMonth(e);break;case"months":this._navigateMonth(e*12);break;case"years":this._moveYearFocus(e*this._yearPageSize());break}}_toggleSurface(e){this._showSurface(this._surface===e?"days":e)}_showSurface(e){if(e!==this._surface){if(this._surface==="days"){const t=this.calBodyRef.value?.getBoundingClientRect();this._pinnedBodySize=t&&t.width>0&&t.height>0?{width:t.width,height:t.height}:null}e==="days"?this._pinnedBodySize=null:e==="months"?this._jumpFocus=this.viewDate.month:this._openYearWindow(this.viewDate.year),this._surface=e}}_openYearWindow(e){this._yearWindow=K(this.viewDate.year,this._minDate,this._maxDate);const t=this._yearWindow[0]??e,i=this._yearWindow[this._yearWindow.length-1]??e;this._jumpFocus=Math.min(i,Math.max(t,e))}_applySurfaceChange(e){const t=this.calBodyRef.value;if(t){const i=this._surface==="days"?null:this._pinnedBodySize;i?(t.style.setProperty("inline-size",`${i.width}px`),t.style.setProperty("block-size",`${i.height}px`)):(t.style.removeProperty("inline-size"),t.style.removeProperty("block-size"))}e===void 0||!this.open||(this._surface==="years"&&this._scrollYearIntoView(this._jumpFocus,"center"),this._focusSurface())}_focusSurface(){const e=this._surface==="days"?'[role="grid"] [tabindex="0"]':'.jump-surface [tabindex="0"]',t=this.shadowRoot?.querySelector(e);(t&&!t.hasAttribute("disabled")?t:this.shadowRoot?.querySelector(".cal-title-part"))?.focus({preventScroll:this._surface==="years"})}_chooseMonth(e){this._setViewMonth(new Temporal.PlainYearMonth(this.viewDate.year,e)),this._showSurface("days")}_chooseYear(e){this._setViewMonth(X(new Temporal.PlainYearMonth(e,this.viewDate.month),this._minDate,this._maxDate)),this._showSurface("days")}_handleMonthKeyDown(e){let t=this._jumpFocus;switch(e.key){case"ArrowLeft":t-=1;break;case"ArrowRight":t+=1;break;case"ArrowUp":t-=T;break;case"ArrowDown":t+=T;break;case"Home":t=1;break;case"End":t=12;break;case"PageUp":this._navigateMonth(-12);break;case"PageDown":this._navigateMonth(12);break;case"Enter":case" ":{const i=new Temporal.PlainYearMonth(this.viewDate.year,this._jumpFocus);A(i,this._minDate,this._maxDate)||this._chooseMonth(this._jumpFocus);break}case"Escape":this._showSurface("days");break;default:return}e.preventDefault(),e.stopPropagation(),t=Math.min(12,Math.max(1,t)),t!==this._jumpFocus&&(this._jumpFocus=t,this._focusSurfaceAfterUpdate())}_handleYearKeyDown(e){const t=this._yearWindow;if(t.length===0)return;const i=t.indexOf(this._jumpFocus);let s=i;switch(e.key){case"ArrowUp":s=i-1;break;case"ArrowDown":s=i+1;break;case"PageUp":s=i-this._yearPageSize();break;case"PageDown":s=i+this._yearPageSize();break;case"Home":s=0;break;case"End":s=t.length-1;break;case"Enter":case" ":this._chooseYear(this._jumpFocus);break;case"Escape":this._showSurface("days");break;default:return}e.preventDefault(),e.stopPropagation(),this._moveYearFocus(s-i)&&this._focusSurfaceAfterUpdate()}_moveYearFocus(e){const t=this._yearWindow;if(t.length===0||e===0)return!1;const i=Math.max(0,Math.min(t.length-1,t.indexOf(this._jumpFocus)+e));return t[i]===this._jumpFocus?!1:(this._jumpFocus=t[i],this.updateComplete.then(()=>{this.open&&this._surface==="years"&&this._scrollYearIntoView(this._jumpFocus,"nearest")}),!0)}_focusSurfaceAfterUpdate(){this.updateComplete.then(()=>{this.open&&this._focusSurface()})}_yearPageSize(){const e=this.yearListRef.value,t=e?.querySelector(".year-cell");return!e||!t||t.offsetHeight===0?5:Math.max(1,Math.floor(e.clientHeight/t.offsetHeight))}_scrollYearIntoView(e,t){const i=this.yearListRef.value,s=i?.querySelector(`[data-year="${e}"]`);if(!i||!s)return;const a=s.offsetTop,o=a+s.offsetHeight;t==="center"?i.scrollTop=Math.max(0,a-(i.clientHeight-s.offsetHeight)/2):a<i.scrollTop?i.scrollTop=a:o>i.scrollTop+i.clientHeight&&(i.scrollTop=o-i.clientHeight)}_moveFocus(e){const t=this.focusedDate.add({days:e});if(this._isDateDisabled(t)){const s=e>0?1:-1;let a=t;for(let o=0;o<B&&this._isDateDisabled(a);o++)a=a.add({days:s});this.focusedDate=a}else this.focusedDate=t;const i=this.focusedDate.toPlainYearMonth();Temporal.PlainYearMonth.compare(i,this.viewDate)!==0&&(this.viewDate=i),this.mode==="range"&&this._rangePhase==="start"&&(this._rangePreview=this.focusedDate)}_selectDate(e){if(!this._isDateDisabled(e)){switch(this.mode){case"date":this.value=e.toString(),this._closePopover(),this.inputRef.value?.focus();break;case"datetime":{const t=this.parsed.kind==="datetime"?this.parsed.datetime.toPlainTime():new Temporal.PlainTime;this.value=e.toPlainDateTime(t).toString();break}case"range":this._selectRangeEndpoint(e);break}this._dispatchValueChanged()}}_selectRangeEndpoint(e){switch(this._rangePhase){case"empty":case"complete":this._rangeAnchor=e,this._rangePreview=null,this._value="",this.parsed={kind:"none"},this.formCtrl.syncValue(),this.requestUpdate();break;case"start":{const i=this._rangeAnchor;let s,a;Temporal.PlainDate.compare(e,i)<0?(s=e,a=i):(s=i,a=e),this._rangePreview=null,this.value=`${s.toString()}/${a.toString()}`;break}}}_dispatchValueChanged(){this.emitValueChanged(this._value)}get _showTimePicker(){return this.mode==="time"||this.mode==="datetime"}get _showCalendar(){return this.mode!=="time"}_commitTime(){let e=this._hour%12;this._period==="PM"&&(e+=12);const t=new Temporal.PlainTime(e,this._minute);if(this.mode==="time")this.value=t.toString();else if(this.mode==="datetime"){const i=this.parsed.kind==="datetime"?this.parsed.datetime.toPlainDate():this.parsed.kind==="date"?this.parsed.date:Temporal.Now.plainDateISO();this.value=i.toPlainDateTime(t).toString()}this._dispatchValueChanged()}async _openPopover(){if(this.disabled||(this.popoverCtrl.publishCloseOthers(),this._valueOnOpen=this._value,this.open=!0,this._positionPopover(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick(),await this.updateComplete,!this.open||!this.isConnected))return;this._shrinkTimePickerToFit(),this._scrollToContainPopover();const t=this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]');requestAnimationFrame(()=>{this.open&&this.isConnected&&t?.focus()})}_closePopover(){this.open=!1,this._resetSwipeAnimation(),this._surface="days",this._pinnedBodySize=null,this._containRepositionFrame!==null&&(cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=null);const e=this.popoverRef.value;if(e){e.classList.remove("visible");try{e.hidePopover()}catch{}}this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.mode==="range"&&this._rangePhase==="start"&&(this._rangeAnchor=null,this._rangePreview=null)}_togglePopover(){this.open?this._closePopover():this._openPopover()}_positionPopover(){if(!this.open)return;const e=this.popoverRef.value;if(!e)return;const t=this.getBoundingClientRect(),{width:i,height:s}=S(),{spaceAbove:a,spaceBelow:o}=G(t,s);e.matches(":popover-open")||e.showPopover(),e.style.removeProperty("top"),e.style.removeProperty("bottom"),e.style.removeProperty("font-size"),e.style.setProperty("width","min-content"),this._shrinkToFitViewport(e,i);let h=t.left;const u=e.offsetWidth;h+u>i&&(h=Math.max(0,i-u)),e.style.setProperty("left",`${h}px`);const c=e.offsetHeight;if(a>o){let m=s-t.top;c>a&&(m=s-c),e.style.setProperty("bottom",`${m}px`)}else{let m=t.bottom;c>o&&(m=s-c),e.style.setProperty("top",`${Math.max(0,m)}px`)}requestAnimationFrame(()=>e.classList.add("visible"))}_shrinkToFitViewport(e,t){if(e.offsetWidth<=t)return;const i=getComputedStyle(e);let s=parseFloat(i.fontSize);const a=8;for(;e.offsetWidth>t&&s>a;)s-=.5,e.style.setProperty("font-size",`${s}px`)}_shrinkTimePickerToFit(){const e=this.timePickerRef.value,t=this.popoverRef.value;if(!e||!t)return;e.style.removeProperty("font-size");const i=t.clientWidth;if(e.scrollWidth<=i)return;const s=getComputedStyle(e);let a=parseFloat(s.fontSize);const o=8;for(;e.scrollWidth>i&&a>o;)a-=.5,e.style.setProperty("font-size",`${a}px`)}_scrollToContainPopover(){const e=this.popoverRef.value;e&&(this._containRepositionFrame!==null&&cancelAnimationFrame(this._containRepositionFrame),this._containRepositionFrame=E(this,e,()=>{this._containRepositionFrame=null,this.open&&this._positionPopover()}))}async _handleGridKeyDown(e){const s=!!!e.target?.closest?.('[role="grid"]')&&(e.key==="Enter"||e.key===" ");if(this._surface!=="days"){e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),this._showSurface("days"));return}if(s)return;let a=!0;switch(e.key){case"ArrowLeft":this._moveFocus(-1);break;case"ArrowRight":this._moveFocus(1);break;case"ArrowUp":this._moveFocus(-7);break;case"ArrowDown":this._moveFocus(7);break;case"Home":{const o=this.focusedDate.dayOfWeek;o>1&&this._moveFocus(-(o-1));break}case"End":{const o=this.focusedDate.dayOfWeek;o<7&&this._moveFocus(7-o);break}case"PageUp":this._navigateMonth(e.shiftKey?-12:-1);break;case"PageDown":this._navigateMonth(e.shiftKey?12:1);break;case"Enter":case" ":this._selectDate(this.focusedDate);break;case"Escape":this._closePopover(),this.inputRef.value?.focus();break;default:a=!1}a&&(e.preventDefault(),e.stopPropagation(),await this.updateComplete,this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]')?.focus())}_onDayCellHover(e){this.mode==="range"&&this._rangePhase==="start"&&(this._rangePreview=e)}render(){return this.temporalSupported?l`
2
2
 
3
3
  <div class="esp-field" @click=${()=>this._togglePopover()}>
4
4
  <input
5
5
  ${v(this.inputRef)}
6
6
  class="esp-input"
7
- .value=${Y(this.parsed)}
7
+ .value=${z(this.parsed)}
8
8
  placeholder=${this.placeholder}
9
9
  readonly
10
10
  ?disabled=${this.disabled}
@@ -12,7 +12,7 @@ var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnP
12
12
  aria-expanded=${this.open?"true":"false"}
13
13
  @keydown=${e=>{(e.key==="Enter"||e.key===" "||e.key==="ArrowDown"||e.key==="ArrowUp")&&(e.preventDefault(),this._openPopover()),e.key==="Escape"&&this.open&&(e.preventDefault(),this._closePopover())}}
14
14
  />
15
- <label class="field-icon">${K}</label>
15
+ <label class="field-icon">${ee}</label>
16
16
  </div>
17
17
 
18
18
 
@@ -22,73 +22,141 @@ var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnP
22
22
  popover="manual"
23
23
  @keydown=${e=>{e.key==="Tab"&&(e.preventDefault(),this._closePopover(),this.inputRef.value?.focus())}}
24
24
  >
25
- ${this._showCalendar?this._renderCalendar():w}
26
- ${this._showTimePicker?this._renderTimePicker():w}
27
- ${!this._showTimePicker&&this.mode!=="date"?this._renderActions():w}
25
+ ${this._showCalendar?this._renderCalendar():_}
26
+ ${this._showTimePicker?this._renderTimePicker():_}
27
+ ${!this._showTimePicker&&this.mode!=="date"?this._renderActions():_}
28
28
  </div>
29
- `:d`<p class="temporal-error">
29
+ `:l`<p class="temporal-error">
30
30
  <code>Temporal</code> API not found. Load the polyfill in <code>&lt;head&gt;</code> before
31
31
  using <code>&lt;esp-date-picker&gt;</code>.
32
- </p>`}_renderCalendar(){const e=this._getGrid(),t=`${R[this.viewDate.month-1]} ${this.viewDate.year}`;return d`
32
+ </p>`}_renderCalendar(){const[e,t]=f.ARROW_LABELS[this._surface];let i;switch(this._surface){case"months":i=this._renderMonthSurface();break;case"years":i=this._renderYearSurface();break;default:i=this._renderDaySurface()}return l`
33
33
  <div
34
34
  class="calendar"
35
- @keydown=${i=>this._handleGridKeyDown(i)}
36
- @touchstart=${i=>this._onCalendarTouchStart(i)}
37
- @touchmove=${i=>this._onCalendarTouchMove(i)}
38
- @touchend=${i=>this._onCalendarTouchEnd(i)}
39
- @touchcancel=${i=>this._onCalendarTouchEnd(i)}
35
+ @keydown=${s=>this._handleGridKeyDown(s)}
36
+ @touchstart=${s=>this._onCalendarTouchStart(s)}
37
+ @touchmove=${s=>this._onCalendarTouchMove(s)}
38
+ @touchend=${s=>this._onCalendarTouchEnd(s)}
39
+ @touchcancel=${s=>this._onCalendarTouchEnd(s)}
40
40
  >
41
41
 
42
42
  <header class="cal-header">
43
43
  <button
44
44
  class="nav-btn"
45
- aria-label="Previous month"
46
- @click=${i=>{i.stopPropagation(),this._navigateMonth(-1)}}
45
+ aria-label=${e}
46
+ @click=${s=>{s.stopPropagation(),this._navigateHeader(-1)}}
47
47
  >
48
- ${O}
48
+ ${V}
49
49
  </button>
50
- <span class="cal-title">${t}</span>
50
+ ${this._renderTitle()}
51
51
  <button
52
52
  class="nav-btn"
53
- aria-label="Next month"
54
- @click=${i=>{i.stopPropagation(),this._navigateMonth(1)}}
53
+ aria-label=${t}
54
+ @click=${s=>{s.stopPropagation(),this._navigateHeader(1)}}
55
55
  >
56
- ${V}
56
+ ${L}
57
57
  </button>
58
58
  </header>
59
59
 
60
60
 
61
- <div ${v(this.calBodyRef)} class="cal-body">
62
- <div class="weekday-row" role="row">
63
- ${X.map(i=>d`<abbr class="weekday-label" title=${i}>${i}</abbr>`)}
64
- </div>
61
+ <div ${v(this.calBodyRef)} class="cal-body">${i}</div>
62
+ </div>
63
+ `}_renderTitle(){const e=w[this.viewDate.month-1],t=this.viewDate.year,i=this._surface==="months",s=this._surface==="years";return l`<span class="cal-title"
64
+ ><button
65
+ type="button"
66
+ class="cal-title-part"
67
+ aria-label=${`Choose month, ${e}`}
68
+ aria-expanded=${i?"true":"false"}
69
+ aria-controls=${i?"month-surface":_}
70
+ @click=${a=>{a.stopPropagation(),this._toggleSurface("months")}}
71
+ >
72
+ ${e}
73
+ </button>
74
+ <button
75
+ type="button"
76
+ class="cal-title-part"
77
+ aria-label=${`Choose year, ${t}`}
78
+ aria-expanded=${s?"true":"false"}
79
+ aria-controls=${s?"year-surface":_}
80
+ @click=${a=>{a.stopPropagation(),this._toggleSurface("years")}}
81
+ >
82
+ ${t}
83
+ </button></span
84
+ >`}_renderDaySurface(){const e=this._getGrid(),t=`${w[this.viewDate.month-1]} ${this.viewDate.year}`;return l`
85
+ <div class="weekday-row" role="row">
86
+ ${I.map(i=>l`<abbr class="weekday-label" title=${i}>${i}</abbr>`)}
87
+ </div>
65
88
 
66
- <div class="day-grid" role="grid" aria-label=${t}>
67
- ${this._renderGridRows(e)}
68
- </div>
69
- </div>
89
+ <div class="day-grid" role="grid" aria-label=${t}>${this._renderGridRows(e)}</div>
90
+ `}_renderMonthSurface(){const e=this.viewDate.year;return l`
91
+ <div
92
+ class="jump-surface month-surface"
93
+ id="month-surface"
94
+ role="listbox"
95
+ aria-label=${`Months of ${e}`}
96
+ @keydown=${t=>this._handleMonthKeyDown(t)}
97
+ >
98
+ ${H.map((t,i)=>{const s=i+1,a=A(new Temporal.PlainYearMonth(e,s),this._minDate,this._maxDate),o=s===this.viewDate.month;return l`
99
+ <button
100
+ type="button"
101
+ role="option"
102
+ class=${D({"jump-cell":!0,"month-cell":!0,selected:o,disabled:a})}
103
+ tabindex=${s===this._jumpFocus?0:-1}
104
+ data-month=${s}
105
+ aria-selected=${o?"true":"false"}
106
+ aria-disabled=${a?"true":"false"}
107
+ aria-label=${`${w[i]} ${e}`}
108
+ @focus=${()=>{this._jumpFocus=s}}
109
+ @click=${u=>{u.stopPropagation(),a||this._chooseMonth(s)}}
110
+ >
111
+ ${t}
112
+ </button>
113
+ `})}
114
+ </div>
115
+ `}_renderYearSurface(){return l`
116
+ <div
117
+ ${v(this.yearListRef)}
118
+ class="jump-surface year-surface"
119
+ id="year-surface"
120
+ role="listbox"
121
+ aria-label="Years"
122
+ @keydown=${e=>this._handleYearKeyDown(e)}
123
+ >
124
+ ${this._yearWindow.map(e=>{const t=e===this.viewDate.year;return l`
125
+ <button
126
+ type="button"
127
+ role="option"
128
+ class=${D({"jump-cell":!0,"year-cell":!0,selected:t})}
129
+ tabindex=${e===this._jumpFocus?0:-1}
130
+ data-year=${e}
131
+ aria-selected=${t?"true":"false"}
132
+ @focus=${()=>{this._jumpFocus=e}}
133
+ @click=${s=>{s.stopPropagation(),this._chooseYear(e)}}
134
+ >
135
+ ${e}
136
+ </button>
137
+ `})}
70
138
  </div>
71
- `}_renderGridRows(e){const t=[];for(let i=0;i<q;i++){const o=e.slice(i*k,(i+1)*k);t.push(d`
139
+ `}_renderGridRows(e){const t=[];for(let i=0;i<j;i++){const s=e.slice(i*R,(i+1)*R);t.push(l`
72
140
  <div class="day-row" role="row">
73
- ${A(o,s=>s.date.toString(),s=>this._renderDayCell(s))}
141
+ ${x(s,a=>a.date.toString(),a=>this._renderDayCell(a))}
74
142
  </div>
75
- `)}return t}_renderDayCell(e){const t=this.focusedDate&&Temporal.PlainDate.compare(e.date,this.focusedDate)===0,i={"day-cell":!0,"outside-month":e.isOutsideMonth,today:e.isToday,selected:e.isSelected||e.isRangeStart||e.isRangeEnd,"range-start":e.isRangeStart,"range-end":e.isRangeEnd,"in-range":e.isInRange,disabled:e.isDisabled,focused:t};return d`
143
+ `)}return t}_renderDayCell(e){const t=this.focusedDate&&Temporal.PlainDate.compare(e.date,this.focusedDate)===0,i={"day-cell":!0,"outside-month":e.isOutsideMonth,today:e.isToday,selected:e.isSelected||e.isRangeStart||e.isRangeEnd,"range-start":e.isRangeStart,"range-end":e.isRangeEnd,"in-range":e.isInRange,disabled:e.isDisabled,focused:t};return l`
76
144
  <button
77
145
  role="gridcell"
78
- class=${C(i)}
146
+ class=${D(i)}
79
147
  tabindex=${t?0:-1}
80
148
  data-date=${e.date.toString()}
81
149
  aria-selected=${e.isSelected||e.isRangeStart||e.isRangeEnd?"true":"false"}
82
150
  aria-disabled=${e.isDisabled?"true":"false"}
83
151
  ?disabled=${e.isDisabled}
84
- aria-label=${`${R[e.date.month-1]} ${e.date.day}, ${e.date.year}`}
152
+ aria-label=${`${w[e.date.month-1]} ${e.date.day}, ${e.date.year}`}
85
153
  aria-current=${e.isToday?"date":"false"}
86
- @click=${async o=>{o.stopPropagation(),this.focusedDate=e.date,this._selectDate(e.date),this.open&&(await this.updateComplete,this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]')?.focus())}}
154
+ @click=${async s=>{s.stopPropagation(),this.focusedDate=e.date,this._selectDate(e.date),this.open&&(await this.updateComplete,this.shadowRoot?.querySelector('[role="grid"]')?.querySelector('[tabindex="0"]')?.focus())}}
87
155
  @pointerenter=${()=>this._onDayCellHover(e.date)}
88
156
  >
89
157
  ${e.date.day}
90
158
  </button>
91
- `}_renderTimePicker(){return d`
159
+ `}_renderTimePicker(){return l`
92
160
  <div ${v(this.timePickerRef)} class="time-picker" aria-label="Time picker">
93
161
  <esp-pick-one
94
162
  class="time-pick"
@@ -97,7 +165,7 @@ var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnP
97
165
  .value=${String(this._hour)}
98
166
  @esp-value-changed=${e=>{e.stopPropagation(),e.detail?.value&&(this._hour=Number(e.detail.value),this._commitTime())}}
99
167
  >
100
- ${I.map(e=>d`
168
+ ${q.map(e=>l`
101
169
  <esp-picker-item
102
170
  text=${String(e)}
103
171
  value=${String(e)}
@@ -115,7 +183,7 @@ var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnP
115
183
  .value=${String(this._minute)}
116
184
  @esp-value-changed=${e=>{e.stopPropagation(),e.detail?.value&&(this._minute=Number(e.detail.value),this._commitTime())}}
117
185
  >
118
- ${B.map(e=>d`
186
+ ${W.map(e=>l`
119
187
  <esp-picker-item
120
188
  text=${String(e).padStart(2,"0")}
121
189
  value=${String(e)}
@@ -147,30 +215,30 @@ var n=function(f,e,t,i){var o=arguments.length,s=o<3?e:i===null?i=Object.getOwnP
147
215
  icon-only
148
216
  @esp-clicked=${()=>{this._closePopover(),this.inputRef.value?.focus()}}
149
217
  >
150
- ${b}
218
+ ${k}
151
219
  </esp-button>
152
220
  <esp-button
153
221
  icon-only
154
222
  intent="danger"
155
223
  @esp-clicked=${()=>{this.value=this._valueOnOpen,this._closePopover(),this.inputRef.value?.focus()}}
156
224
  >
157
- ${S}
225
+ ${$}
158
226
  </esp-button>
159
227
  </div>
160
- `}_renderActions(){return d`
228
+ `}_renderActions(){return l`
161
229
  <div class="popover-actions">
162
230
  <esp-button
163
231
  icon-only
164
232
  @esp-clicked=${()=>{this._closePopover(),this.inputRef.value?.focus()}}
165
233
  >
166
- ${b}
234
+ ${k}
167
235
  </esp-button>
168
236
  <esp-button
169
237
  icon-only
170
238
  intent="danger"
171
239
  @esp-clicked=${()=>{this.value=this._valueOnOpen,this._closePopover(),this.inputRef.value?.focus()}}
172
240
  >
173
- ${S}
241
+ ${$}
174
242
  </esp-button>
175
243
  </div>
176
- `}};r.formAssociated=!0,r.LONG_PRESS_MS=400,r.EDGE_SCROLL_MS=1e3,r.styles=[...P.styles,j],n([p()],r.prototype,"temporalSupported",void 0),n([u({type:String,reflect:!0})],r.prototype,"mode",void 0),n([u({type:String})],r.prototype,"value",null),n([u({type:String})],r.prototype,"placeholder",void 0),n([u({type:String})],r.prototype,"min",void 0),n([u({type:String})],r.prototype,"max",void 0),n([u({type:Boolean,reflect:!0})],r.prototype,"disabled",void 0),n([u({type:String,reflect:!0})],r.prototype,"name",void 0),n([u({type:Boolean,reflect:!0})],r.prototype,"required",void 0),n([u({attribute:"required-message"})],r.prototype,"requiredMessage",void 0),n([p()],r.prototype,"viewDate",void 0),n([p()],r.prototype,"focusedDate",void 0),n([p()],r.prototype,"open",void 0),n([p()],r.prototype,"parsed",void 0),n([p()],r.prototype,"_hour",void 0),n([p()],r.prototype,"_minute",void 0),n([p()],r.prototype,"_period",void 0),n([p()],r.prototype,"_rangeAnchor",void 0),n([p()],r.prototype,"_rangePreview",void 0),r=_=n([$("esp-date-picker")],r);export{r as EspalierDatePicker};
244
+ `}};r.formAssociated=!0,r.LONG_PRESS_MS=400,r.EDGE_SCROLL_MS=1e3,r.ARROW_LABELS={days:["Previous month","Next month"],months:["Previous year","Next year"],years:["Earlier years","Later years"]},r.styles=[...P.styles,te],n([d()],r.prototype,"temporalSupported",void 0),n([p({type:String,reflect:!0})],r.prototype,"mode",void 0),n([p({type:String})],r.prototype,"value",null),n([p({type:String})],r.prototype,"placeholder",void 0),n([p({type:String})],r.prototype,"min",void 0),n([p({type:String})],r.prototype,"max",void 0),n([p({type:Boolean,reflect:!0})],r.prototype,"disabled",void 0),n([p({type:String,reflect:!0})],r.prototype,"name",void 0),n([p({type:Boolean,reflect:!0})],r.prototype,"required",void 0),n([p({attribute:"required-message"})],r.prototype,"requiredMessage",void 0),n([d()],r.prototype,"viewDate",void 0),n([d()],r.prototype,"focusedDate",void 0),n([d()],r.prototype,"_surface",void 0),n([d()],r.prototype,"_jumpFocus",void 0),n([d()],r.prototype,"open",void 0),n([d()],r.prototype,"parsed",void 0),n([d()],r.prototype,"_hour",void 0),n([d()],r.prototype,"_minute",void 0),n([d()],r.prototype,"_period",void 0),n([d()],r.prototype,"_rangeAnchor",void 0),n([d()],r.prototype,"_rangePreview",void 0),r=f=n([C("esp-date-picker")],r);export{r as EspalierDatePicker};
@@ -1 +1 @@
1
- import{GRID_SIZE as k}from"./constants.js";function b(t){if(!t)return null;try{return Temporal.PlainDate.from(t)}catch{return null}}function x(t,n,e){return!!(n&&Temporal.PlainDate.compare(t,n)<0||e&&Temporal.PlainDate.compare(t,e)>0)}function S(t){switch(t.kind){case"date":return t.date;case"datetime":return t.datetime.toPlainDate();default:return null}}function B(t,n,e,l){return t!=="range"?{start:null,end:null}:n.kind==="range"?{start:n.start,end:n.end}:e&&l?Temporal.PlainDate.compare(l,e)<0?{start:l,end:e}:{start:e,end:l}:e?{start:e,end:null}:{start:null,end:null}}function G(t,n,e,l,u,s){const c=Temporal.Now.plainDateISO(),o=t.toPlainDate({day:1}),d=o.dayOfWeek-1,p=o.subtract({days:d}),i=[];for(let r=0;r<k;r++){const a=p.add({days:r}),f=a.month!==t.month||a.year!==t.year,m=Temporal.PlainDate.compare(a,c)===0,D=n!==null&&Temporal.PlainDate.compare(a,n)===0,T=e!==null&&Temporal.PlainDate.compare(a,e)===0,y=l!==null&&Temporal.PlainDate.compare(a,l)===0,P=e!==null&&l!==null&&Temporal.PlainDate.compare(a,e)>0&&Temporal.PlainDate.compare(a,l)<0,R=x(a,u,s);i.push({date:a,isOutsideMonth:f,isToday:m,isSelected:D,isRangeStart:T,isRangeEnd:y,isInRange:P,isDisabled:R})}return i}export{G as generateCalendarGrid,B as getEffectiveRange,S as getSelectedDate,x as isDateDisabled,b as parseDateBound};
1
+ import{GRID_SIZE as N,YEAR_WINDOW_AFTER as R,YEAR_WINDOW_BEFORE as h}from"./constants.js";function Y(e){if(!e)return null;try{return Temporal.PlainDate.from(e)}catch{return null}}function E(e,a,t){return!!(a&&Temporal.PlainDate.compare(e,a)<0||t&&Temporal.PlainDate.compare(e,t)>0)}function _(e,a,t){return!!(a&&t&&Temporal.PlainDate.compare(a,t)>0||a&&Temporal.PlainDate.compare(e.toPlainDate({day:e.daysInMonth}),a)<0||t&&Temporal.PlainDate.compare(e.toPlainDate({day:1}),t)>0)}function B(e,a,t){if(a){const r=a.toPlainYearMonth();if(Temporal.PlainYearMonth.compare(e,r)<0)return r}if(t){const r=t.toPlainYearMonth();if(Temporal.PlainYearMonth.compare(e,r)>0)return r}return e}function W(e,a,t,r=h,i=R){if(a&&t&&Temporal.PlainDate.compare(a,t)>0)return[];const s=a?.year??Number.NEGATIVE_INFINITY,c=t?.year??Number.POSITIVE_INFINITY;let o=Math.max(e-r,s),l=Math.min(e+i,c);o>l&&(a&&e<a.year?(o=a.year,l=Math.min(a.year+i,c)):t&&(l=t.year,o=Math.max(t.year-r,s)));const p=[];for(let u=o;u<=l;u++)p.push(u);return p}function b(e){switch(e.kind){case"date":return e.date;case"datetime":return e.datetime.toPlainDate();default:return null}}function k(e,a,t,r){return e!=="range"?{start:null,end:null}:a.kind==="range"?{start:a.start,end:a.end}:t&&r?Temporal.PlainDate.compare(r,t)<0?{start:r,end:t}:{start:t,end:r}:t?{start:t,end:null}:{start:null,end:null}}function F(e,a,t,r,i,s){const c=Temporal.Now.plainDateISO(),o=e.toPlainDate({day:1}),p=o.dayOfWeek-1,u=o.subtract({days:p}),d=[];for(let f=0;f<N;f++){const n=u.add({days:f}),D=n.month!==e.month||n.year!==e.year,T=Temporal.PlainDate.compare(n,c)===0,y=a!==null&&Temporal.PlainDate.compare(n,a)===0,P=t!==null&&Temporal.PlainDate.compare(n,t)===0,m=r!==null&&Temporal.PlainDate.compare(n,r)===0,I=t!==null&&r!==null&&Temporal.PlainDate.compare(n,t)>0&&Temporal.PlainDate.compare(n,r)<0,M=E(n,i,s);d.push({date:n,isOutsideMonth:D,isToday:T,isSelected:y,isRangeStart:P,isRangeEnd:m,isInRange:I,isDisabled:M})}return d}export{B as clampMonthToBounds,F as generateCalendarGrid,W as generateYearWindow,k as getEffectiveRange,b as getSelectedDate,E as isDateDisabled,_ as isMonthDisabled,Y as parseDateBound};
@@ -1 +1 @@
1
- const o=6,t=7,S=42,n=["Mo","Tu","We","Th","Fr","Sa","Su"],_=["January","February","March","April","May","June","July","August","September","October","November","December"],c=Array.from({length:12},(e,r)=>r+1),p=Array.from({length:60},(e,r)=>r);export{t as GRID_COLS,o as GRID_ROWS,S as GRID_SIZE,c as HOURS_12,p as MINUTES_60,_ as MONTH_NAMES,n as WEEKDAY_LABELS};
1
+ const o=6,t=7,_=42,n=["Mo","Tu","We","Th","Fr","Sa","Su"],c=["January","February","March","April","May","June","July","August","September","October","November","December"],S=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],p=3,O=100,R=50,A=Array.from({length:12},(e,r)=>r+1),s=Array.from({length:60},(e,r)=>r);export{t as GRID_COLS,o as GRID_ROWS,_ as GRID_SIZE,A as HOURS_12,s as MINUTES_60,p as MONTH_GRID_COLS,c as MONTH_NAMES,S as MONTH_SHORT_NAMES,n as WEEKDAY_LABELS,R as YEAR_WINDOW_AFTER,O as YEAR_WINDOW_BEFORE};
@@ -65,11 +65,15 @@ import{css as e}from"lit";const r=e`
65
65
 
66
66
 
67
67
  .calendar {
68
+ --_cell-size: 2.4em;
69
+
68
70
  display: flex;
69
71
  flex-direction: column;
70
72
  gap: var(--esp-size-tiny);
71
73
  user-select: none;
72
- overflow: hidden;
74
+
75
+ overflow: clip;
76
+ overflow-clip-margin: 4px;
73
77
  }
74
78
 
75
79
  .cal-body {
@@ -89,6 +93,27 @@ import{css as e}from"lit";const r=e`
89
93
  color: var(--esp-color-headings);
90
94
  }
91
95
 
96
+
97
+ .cal-title-part {
98
+ appearance: none;
99
+ display: inline;
100
+ margin: 0;
101
+ padding: 0;
102
+ border: 0;
103
+ border-radius: var(--esp-size-border-radius);
104
+ background: none;
105
+ font: inherit;
106
+ letter-spacing: inherit;
107
+ color: inherit;
108
+ cursor: pointer;
109
+
110
+
111
+ &:focus-visible {
112
+ outline: 2px solid var(--esp-color-action-text);
113
+ outline-offset: 2px;
114
+ }
115
+ }
116
+
92
117
  .nav-btn {
93
118
  display: grid;
94
119
  place-content: center;
@@ -152,14 +177,12 @@ import{css as e}from"lit";const r=e`
152
177
 
153
178
 
154
179
 
155
- .day-cell {
156
- --_cell-size: 2.4em;
157
-
180
+
181
+ .day-cell,
182
+ .jump-cell {
158
183
  position: relative;
159
184
  display: grid;
160
185
  place-content: center;
161
- width: var(--_cell-size);
162
- height: var(--_cell-size);
163
186
  border: none;
164
187
  border-radius: var(--esp-size-border-radius);
165
188
  background: none;
@@ -182,6 +205,18 @@ import{css as e}from"lit";const r=e`
182
205
  }
183
206
 
184
207
 
208
+ &.selected {
209
+ background-color: var(--esp-color-layer-3);
210
+ color: var(--esp-color-action-text);
211
+ font-weight: bold;
212
+ }
213
+ }
214
+
215
+ .day-cell {
216
+ width: var(--_cell-size);
217
+ height: var(--_cell-size);
218
+
219
+
185
220
  &.outside-month {
186
221
  opacity: 0.38;
187
222
  }
@@ -194,13 +229,6 @@ import{css as e}from"lit";const r=e`
194
229
  }
195
230
 
196
231
 
197
- &.selected {
198
- background-color: var(--esp-color-layer-3);
199
- color: var(--esp-color-action-text);
200
- font-weight: bold;
201
- }
202
-
203
-
204
232
  &.in-range {
205
233
  background-color: oklch(from var(--esp-color-layer-3) calc(l + 0.15) calc(c * 0.4) h);
206
234
  border-radius: 0;
@@ -213,12 +241,43 @@ import{css as e}from"lit";const r=e`
213
241
  &.range-end {
214
242
  border-radius: 0 var(--esp-size-border-radius) var(--esp-size-border-radius) 0;
215
243
  }
244
+ }
216
245
 
246
+
247
+ .day-cell.disabled,
248
+ .jump-cell.disabled {
249
+ opacity: 0.3;
250
+ cursor: not-allowed;
251
+ }
252
+
253
+
254
+
255
+
256
+ .jump-surface {
257
+ box-sizing: border-box;
258
+ block-size: 100%;
259
+ }
260
+
261
+ .month-surface {
262
+ display: grid;
263
+ grid-template-columns: repeat(3, 1fr);
264
+ grid-auto-rows: 1fr;
265
+ gap: var(--esp-size-tiny);
266
+ }
267
+
268
+ .year-surface {
217
269
 
218
- &.disabled {
219
- opacity: 0.3;
220
- cursor: not-allowed;
221
- }
270
+ position: relative;
271
+ display: flex;
272
+ flex-direction: column;
273
+ overflow-y: auto;
274
+ overscroll-behavior: contain;
275
+ scrollbar-width: thin;
276
+ }
277
+
278
+ .year-cell {
279
+ flex: 0 0 auto;
280
+ min-block-size: var(--_cell-size);
222
281
  }
223
282
 
224
283
 
@@ -1,5 +1,15 @@
1
1
  import "../temporal.js";
2
2
  export type DatePickerMode = "date" | "datetime" | "time" | "range";
3
+ /**
4
+ * Which surface the calendar body is showing.
5
+ *
6
+ * | Value | Body content |
7
+ * |----------|------------------------------------------------|
8
+ * | `days` | Weekday labels and the 6×7 day grid (default) |
9
+ * | `months` | The twelve months of the title's year |
10
+ * | `years` | A scrolling window of years around the view |
11
+ */
12
+ export type CalendarSurface = "days" | "months" | "years";
3
13
  /**
4
14
  * Range selection follows a three-state machine:
5
15
  *