@taprootio/espalier 4.20.2 → 6.0.0

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/custom-elements.json +2904 -741
  3. package/dist/checkbox/esp-checkbox-group.d.ts +6 -0
  4. package/dist/checkbox/esp-checkbox-group.js +10 -5
  5. package/dist/checkbox/esp-checkbox.d.ts +24 -0
  6. package/dist/checkbox/esp-checkbox.js +3 -3
  7. package/dist/cli/theme-check.js +2 -2
  8. package/dist/date-picker/esp-date-picker.js +6 -6
  9. package/dist/flyout/esp-flyout.d.ts +1 -1
  10. package/dist/flyout/esp-flyout.js +3 -9
  11. package/dist/font-picker/esp-font-picker.js +3 -3
  12. package/dist/footer/esp-footer.d.ts +1 -1
  13. package/dist/form-item/esp-form-item.d.ts +35 -0
  14. package/dist/form-item/esp-form-item.js +16 -11
  15. package/dist/image/esp-image.d.ts +2 -2
  16. package/dist/image/esp-image.js +4 -4
  17. package/dist/image/image-ratio.d.ts +5 -0
  18. package/dist/image/image-ratio.js +1 -0
  19. package/dist/image-picker/esp-image-picker.js +2 -2
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +1 -1
  22. package/dist/input/esp-input.d.ts +29 -3
  23. package/dist/input/esp-input.js +14 -14
  24. package/dist/menu/esp-menu.d.ts +0 -5
  25. package/dist/menu/esp-menu.js +4 -4
  26. package/dist/page/esp-page.d.ts +2 -17
  27. package/dist/page/esp-page.js +2 -2
  28. package/dist/page/esp-page.styles.js +8 -32
  29. package/dist/pickers/esp-pick-one.d.ts +4 -0
  30. package/dist/pickers/esp-pick-one.js +11 -11
  31. package/dist/pickers/esp-pick-some.js +8 -8
  32. package/dist/pickers/esp-picker-base.js +5 -5
  33. package/dist/pickers/esp-picker-item.js +5 -5
  34. package/dist/pickers/esp-picker-menu.js +2 -2
  35. package/dist/pickers/typeahead-controller.js +1 -1
  36. package/dist/radio-button/esp-radio-button-group.d.ts +6 -0
  37. package/dist/radio-button/esp-radio-button-group.js +5 -4
  38. package/dist/radio-button/esp-radio-button.d.ts +22 -0
  39. package/dist/radio-button/esp-radio-button.js +2 -2
  40. package/dist/root/esp-root.js +2 -2
  41. package/dist/shared/enum-converter.js +1 -0
  42. package/dist/shared/events.d.ts +11 -0
  43. package/dist/shared/events.js +1 -1
  44. package/dist/shared/font-helpers.d.ts +0 -2
  45. package/dist/shared/font-helpers.js +1 -1
  46. package/dist/shared/form-field-description-controller.js +1 -1
  47. package/dist/shared/form-item-relay.js +1 -0
  48. package/dist/shared/justified-layout.d.ts +5 -31
  49. package/dist/shared/justified-layout.js +1 -1
  50. package/dist/slider/esp-slider.js +1 -1
  51. package/dist/switch/esp-switch.js +3 -3
  52. package/dist/textarea/esp-textarea.js +2 -2
  53. package/dist/video/esp-video.d.ts +231 -0
  54. package/dist/video/esp-video.js +253 -0
  55. package/espalier.css-data.json +40 -16
  56. package/espalier.token-manifest.json +60 -24
  57. package/licenses/ASSET_PROVENANCE.md +1 -0
  58. package/licenses/asset-provenance.json +22 -0
  59. package/package.json +5 -1
@@ -31,6 +31,12 @@ import { type EspalierFormField } from "../form-item/esp-form-item.js";
31
31
  * </esp-box>
32
32
  * ```
33
33
  *
34
+ * Inside an `esp-form-item`, the group's `group` element takes the form
35
+ * item's `label` as its accessible name and its hint as its description.
36
+ * While the form item shows an error, that element is `aria-invalid="true"`
37
+ * and the error joins its description after the hint. Each option keeps its
38
+ * own label and is not described separately.
39
+ *
34
40
  * @slot - Place `esp-checkbox` elements in the default slot.
35
41
  *
36
42
  * @event {CustomEvent<string[]>} esp-value-changed - Fired when any
@@ -1,10 +1,15 @@
1
- var o=function(l,e,t,r){var a=arguments.length,i=a<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(l,e,t,r);else for(var c=l.length-1;c>=0;c--)(h=l[c])&&(i=(a<3?h(i):a>3?h(e,t,i):h(e,t))||i);return a>3&&i&&Object.defineProperty(e,t,i),i};import{css as p,html as m}from"lit";import{customElement as f,property as n}from"lit/decorators.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{createRef as u,ref as b}from"lit/directives/ref.js";import{EspalierCheckbox as g}from"./esp-checkbox.js";import{FormFieldController as C}from"../shared/form-field-controller.js";let s=class extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new C({host:this,internals:this.internals,getFormValue:()=>{const e=this.values;return e.length>0?e.join(","):null},getValidity:()=>this.required&&this.values.length===0?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select at least one option."}:null,onReset:()=>{for(const e of this.getCheckboxes())e.checked=!1},onRestore:e=>{const t=e.split(",");for(const r of this.getCheckboxes())r.checked=t.includes(r.value)},onDisabled:e=>{this.disabled=e}}),this.itemsSlot=u(),this.formItemDescription=null,this.describedCheckboxes=new Set,this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.handleItemsSlotChange=()=>{this.applyDisabledState(),this.applyFormItemDescription()}}get values(){return this.getCheckboxes().filter(e=>e.checked).map(e=>e.value)}focus(e){this.focusResolvedElementAfterUpdate(()=>this.getCheckboxes().find(t=>!t.disabled),e)}setFormItemDescription(e){this.formItemDescription=e,this.applyFormItemDescription()}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}getCheckboxes(){return this.itemsSlot.value?Array.from(this.itemsSlot.value.assignedElements()).filter(e=>e instanceof g):[]}applyDisabledState(){for(const e of this.getCheckboxes())e.disabled=this.disabled}applyFormItemDescription(){const e=new Set(this.getCheckboxes());for(const t of this.describedCheckboxes)e.has(t)||t.setFormItemDescription(null);for(const t of e)t.setFormItemDescription(this.formItemDescription);this.describedCheckboxes=e}handleChildChanged(e){e.stopPropagation(),this.formCtrl.syncValue(),this.emitValueChanged(this.values)}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}firstUpdated(e){super.firstUpdated(e),this.applyDisabledState(),this.applyFormItemDescription()}updated(e){super.updated(e),e.has("disabled")&&this.applyDisabledState()}render(){return m`
2
- <div class="checkbox-group" role="group" @esp-value-changed=${this.handleChildChanged}>
3
- <slot ${b(this.itemsSlot)} @slotchange=${this.handleItemsSlotChange}></slot>
1
+ var o=function(l,e,s,i){var a=arguments.length,r=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,s):i,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(l,e,s,i);else for(var d=l.length-1;d>=0;d--)(n=l[d])&&(r=(a<3?n(r):a>3?n(e,s,r):n(e,s))||r);return a>3&&r&&Object.defineProperty(e,s,r),r};import{css as u,html as f}from"lit";import{customElement as g,property as h}from"lit/decorators.js";import{EspalierElementBase as c}from"../shared/esp-element-base.js";import{createRef as m,ref as p}from"lit/directives/ref.js";import{EspalierCheckbox as b}from"./esp-checkbox.js";import{FormFieldController as C}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as v}from"../shared/form-field-description-controller.js";let t=class extends c{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new C({host:this,internals:this.internals,getFormValue:()=>{const e=this.values;return e.length>0?e.join(","):null},getValidity:()=>this.required&&this.values.length===0?{flags:{valueMissing:!0},message:this.requiredMessage||"Please select at least one option."}:null,onReset:()=>{for(const e of this.getCheckboxes())e.checked=!1},onRestore:e=>{const s=e.split(",");for(const i of this.getCheckboxes())i.checked=s.includes(i.value)},onDisabled:e=>{this.disabled=e}}),this.itemsSlot=m(),this.groupElement=m(),this.formItemDescription=new v({host:this,getTarget:()=>this.groupElement.value}),this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.handleItemsSlotChange=()=>{this.applyDisabledState()}}get values(){return this.getCheckboxes().filter(e=>e.checked).map(e=>e.value)}focus(e){this.focusResolvedElementAfterUpdate(()=>this.getCheckboxes().find(s=>!s.disabled),e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}setFormItemLabel(e){this.formItemDescription.setLabel(e)}setFormItemInvalid(e){this.formItemDescription.setInvalid(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}getCheckboxes(){return this.itemsSlot.value?Array.from(this.itemsSlot.value.assignedElements()).filter(e=>e instanceof b):[]}applyDisabledState(){for(const e of this.getCheckboxes())e.disabled=this.disabled}handleChildChanged(e){e.stopPropagation(),this.formCtrl.syncValue(),this.emitValueChanged(this.values)}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}firstUpdated(e){super.firstUpdated(e),this.applyDisabledState()}updated(e){super.updated(e),e.has("disabled")&&this.applyDisabledState()}render(){return f`
2
+ <div
3
+ class="checkbox-group"
4
+ role="group"
5
+ ${p(this.groupElement)}
6
+ @esp-value-changed=${this.handleChildChanged}
7
+ >
8
+ <slot ${p(this.itemsSlot)} @slotchange=${this.handleItemsSlotChange}></slot>
4
9
  </div>
5
- `}};s.formAssociated=!0,s.styles=[...d.styles,p`
10
+ `}};t.clearsFormItemErrorOnChange=!0,t.formAssociated=!0,t.styles=[...c.styles,u`
6
11
  .checkbox-group {
7
12
  display: grid;
8
13
  gap: var(--esp-size-tiny);
9
14
  }
10
- `],o([n({type:String,reflect:!0})],s.prototype,"name",void 0),o([n({type:Boolean,reflect:!0})],s.prototype,"required",void 0),o([n({attribute:"required-message"})],s.prototype,"requiredMessage",void 0),o([n({type:Boolean,reflect:!0})],s.prototype,"disabled",void 0),s=o([f("esp-checkbox-group")],s);export{s as EspalierCheckboxGroup};
15
+ `],o([h({type:String,reflect:!0})],t.prototype,"name",void 0),o([h({type:Boolean,reflect:!0})],t.prototype,"required",void 0),o([h({attribute:"required-message"})],t.prototype,"requiredMessage",void 0),o([h({type:Boolean,reflect:!0})],t.prototype,"disabled",void 0),t=o([g("esp-checkbox-group")],t);export{t as EspalierCheckboxGroup};
@@ -31,6 +31,30 @@ import { type EspalierFormField } from "../form-item/esp-form-item.js";
31
31
  * </esp-box>
32
32
  * ```
33
33
  *
34
+ * ### Errors
35
+ *
36
+ * Inside an `esp-form-item`, a checkbox that shows an error is
37
+ * `aria-invalid="true"`, the error joins its description after any hint,
38
+ * and the error is announced once. In an `esp-checkbox-group`, the group
39
+ * carries all of this instead, and takes the form item's `label` as its
40
+ * accessible name. Checking or unchecking clears an error set through the
41
+ * form item's `error` or `errorPool`; a `required` checkbox or group raises
42
+ * its own error again when it is left empty.
43
+ *
44
+ * ```html
45
+ * <esp-box>
46
+ * <esp-form-item label="Terms" error="Accept the terms to continue.">
47
+ * <esp-checkbox value="agree">I agree to the terms</esp-checkbox>
48
+ * </esp-form-item>
49
+ * <esp-form-item label="Pizza toppings" hint="Pick up to three." error="Choose at least one topping.">
50
+ * <esp-checkbox-group required>
51
+ * <esp-checkbox value="cheese">Cheese</esp-checkbox>
52
+ * <esp-checkbox value="basil">Basil</esp-checkbox>
53
+ * </esp-checkbox-group>
54
+ * </esp-form-item>
55
+ * </esp-box>
56
+ * ```
57
+ *
34
58
  * @slot - The label text for the checkbox.
35
59
  *
36
60
  * @event {CustomEvent<{ checked: boolean; value: string }>} esp-value-changed -
@@ -1,4 +1,4 @@
1
- var i=function(l,e,s,c){var a=arguments.length,o=a<3?e:c===null?c=Object.getOwnPropertyDescriptor(e,s):c,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(l,e,s,c);else for(var h=l.length-1;h>=0;h--)(n=l[h])&&(o=(a<3?n(o):a>3?n(e,s,o):n(e,s))||o);return a>3&&o&&Object.defineProperty(e,s,o),o};import{css as p,html as m}from"lit";import{customElement as f,property as r}from"lit/decorators.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{checkboxChecked as u}from"../shared/svgs/checkbox-checked.js";import{checkboxUnchecked as b}from"../shared/svgs/checkbox-unchecked.js";import{checkboxIndeterminate as v}from"../shared/svgs/checkbox-indeterminate.js";import{FormFieldController as k}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as g}from"../shared/form-field-description-controller.js";import{disabledControl as y,focusRing as x}from"../shared/style-fragments.js";let t=class extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new k({host:this,internals:this.internals,getFormValue:()=>this.checked?this.value||"on":null,getValidity:()=>this.required&&!this.checked?{flags:{valueMissing:!0},message:this.requiredMessage||"Please check this box to continue."}:null,onReset:()=>{this.checked=!1,this.indeterminate=!1},onRestore:e=>{this.checked=e==="on"||e===this.value},onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new g({host:this,getTarget:()=>this.shadowRoot?.querySelector(".checkbox-control")}),this.checked=!1,this.value="",this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.indeterminate=!1}focus(e){this.focusShadowElementAfterUpdate(".checkbox-control",e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}toggle(){this.disabled||(this.indeterminate=!1,this.checked=!this.checked,this.formCtrl.syncValue(),this.emitValueChanged({checked:this.checked,value:this.value}))}handleKeyDown(e){e.key===" "&&(e.preventDefault(),this.toggle())}getSvg(){return this.indeterminate?v:this.checked?u:b}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}render(){return m`
1
+ var o=function(l,e,s,a){var c=arguments.length,r=c<3?e:a===null?a=Object.getOwnPropertyDescriptor(e,s):a,n;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(l,e,s,a);else for(var h=l.length-1;h>=0;h--)(n=l[h])&&(r=(c<3?n(r):c>3?n(e,s,r):n(e,s))||r);return c>3&&r&&Object.defineProperty(e,s,r),r};import{css as m,html as p}from"lit";import{customElement as f,property as i}from"lit/decorators.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";import{checkboxChecked as u}from"../shared/svgs/checkbox-checked.js";import{checkboxUnchecked as b}from"../shared/svgs/checkbox-unchecked.js";import{checkboxIndeterminate as v}from"../shared/svgs/checkbox-indeterminate.js";import{FormFieldController as k}from"../shared/form-field-controller.js";import{FormFieldDescriptionController as g}from"../shared/form-field-description-controller.js";import{disabledControl as y,focusRing as x}from"../shared/style-fragments.js";let t=class extends d{constructor(){super(...arguments),this.internals=this.attachInternals(),this.formCtrl=new k({host:this,internals:this.internals,getFormValue:()=>this.checked?this.value||"on":null,getValidity:()=>this.required&&!this.checked?{flags:{valueMissing:!0},message:this.requiredMessage||"Please check this box to continue."}:null,onReset:()=>{this.checked=!1,this.indeterminate=!1},onRestore:e=>{this.checked=e==="on"||e===this.value},onDisabled:e=>{this.disabled=e}}),this.formItemDescription=new g({host:this,getTarget:()=>this.shadowRoot?.querySelector(".checkbox-control")}),this.checked=!1,this.value="",this.name="",this.required=!1,this.requiredMessage="",this.disabled=!1,this.indeterminate=!1}focus(e){this.focusShadowElementAfterUpdate(".checkbox-control",e)}setFormItemDescription(e){this.formItemDescription.setDescription(e)}setFormItemInvalid(e){this.formItemDescription.setInvalid(e)}validate(){this.formCtrl.validate()}checkValidity(){return this.formCtrl.checkValidity()}toggle(){this.disabled||(this.indeterminate=!1,this.checked=!this.checked,this.formCtrl.syncValue(),this.emitValueChanged({checked:this.checked,value:this.value}))}handleKeyDown(e){e.key===" "&&(e.preventDefault(),this.toggle())}getSvg(){return this.indeterminate?v:this.checked?u:b}formResetCallback(){this.formCtrl.handleFormReset()}formStateRestoreCallback(e){this.formCtrl.handleFormStateRestore(e)}formDisabledCallback(e){this.formCtrl.handleFormDisabled(e)}render(){return p`
2
2
  <div
3
3
  class="checkbox-control"
4
4
  role="checkbox"
@@ -11,7 +11,7 @@ var i=function(l,e,s,c){var a=arguments.length,o=a<3?e:c===null?c=Object.getOwnP
11
11
  <span class="icon">${this.getSvg()}</span>
12
12
  <span class="label"><slot></slot></span>
13
13
  </div>
14
- `}};t.formAssociated=!0,t.styles=[...d.styles,x(".checkbox-control:focus-visible","--esp-checkbox-focus-shadow"),y(".checkbox-control"),p`
14
+ `}};t.clearsFormItemErrorOnChange=!0,t.formAssociated=!0,t.styles=[...d.styles,x(".checkbox-control:focus-visible","--esp-checkbox-focus-shadow"),y(".checkbox-control"),m`
15
15
  :host {
16
16
  display: block;
17
17
  }
@@ -47,4 +47,4 @@ var i=function(l,e,s,c){var a=arguments.length,o=a<3?e:c===null?c=Object.getOwnP
47
47
  line-height: 1.3;
48
48
  }
49
49
  }
50
- `],i([r({type:Boolean,reflect:!0})],t.prototype,"checked",void 0),i([r({type:String})],t.prototype,"value",void 0),i([r({type:String,reflect:!0})],t.prototype,"name",void 0),i([r({type:Boolean,reflect:!0})],t.prototype,"required",void 0),i([r({attribute:"required-message"})],t.prototype,"requiredMessage",void 0),i([r({type:Boolean,reflect:!0})],t.prototype,"disabled",void 0),i([r({type:Boolean,reflect:!0})],t.prototype,"indeterminate",void 0),t=i([f("esp-checkbox")],t);export{t as EspalierCheckbox};
50
+ `],o([i({type:Boolean,reflect:!0})],t.prototype,"checked",void 0),o([i({type:String})],t.prototype,"value",void 0),o([i({type:String,reflect:!0})],t.prototype,"name",void 0),o([i({type:Boolean,reflect:!0})],t.prototype,"required",void 0),o([i({attribute:"required-message"})],t.prototype,"requiredMessage",void 0),o([i({type:Boolean,reflect:!0})],t.prototype,"disabled",void 0),o([i({type:Boolean,reflect:!0})],t.prototype,"indeterminate",void 0),t=o([f("esp-checkbox")],t);export{t as EspalierCheckbox};
@@ -1,2 +1,2 @@
1
- import{encodeTheme as P,isObjectRecord as p,isSemanticColorName as D,validateThemePair as G}from"../shared/theme.js";import{THEME_FIT_ANCHOR_FIELDS as N,THEME_FIT_APCA_FIELDS as C,THEME_FIT_DATA_PALETTE_LINT_FIELDS as M,THEME_FIT_DATA_PALETTE_LINT_IDS as X,THEME_FIT_EXPLICIT_VALUES as Y,THEME_FIT_LINT_FIELDS as R,THEME_FIT_LINT_IDS as B,THEME_FIT_LINT_SEVERITIES as Q,THEME_FIT_PAIRING_VALUES as Z,THEME_FIT_REPORT_FIELDS as _,THEME_FIT_SUITE_FIELDS as k,THEME_FIT_TOKEN_FIELDS as x,themeFitReportSuite as v}from"../shared/theme-fit-report.js";import{COLOR_VISION_SIMULATIONS as ee,DATA_SERIES_KEYS as A,isPaletteCollisionDescription as te}from"../shared/data-colors.js";import{isSafeKey as re}from"../shared/unsafe-keys.js";const I="usage: espalier theme check <theme.json> [--json] [--expect <fit.json>] [--update-expect <fit.json>]";function Re(e,t){const[r,i,...n]=e;if(r!=="theme"||i!=="check")return t.error(I),2;const s=ne(n,t);return s?oe(s,t):2}function ne(e,t){const r={file:"",json:!1};for(let i=0;i<e.length;i+=1){const n=e[i];if(n==="--json")r.json=!0;else if(n==="--expect"||n==="--update-expect"){const s=e[i+1];if(s===void 0)return t.error(`${n} requires a file path. ${I}`),null;n==="--expect"?r.expect=s:r.updateExpect=s,i+=1}else if(!n.startsWith("--")&&r.file==="")r.file=n;else return t.error(`Unknown argument "${n}". ${I}`),null}return r.file===""?(t.error(I),null):r.expect!==void 0&&r.updateExpect!==void 0?(t.error(`--expect checks the committed fit tables and --update-expect rewrites them \u2014 pick one. ${I}`),null):r}function ie(e,t){let r;try{r=t.readFile(e)}catch(s){return t.error(`Cannot read ${e}: ${s instanceof Error?s.message:String(s)}`),null}let i;try{i=JSON.parse(r)}catch(s){return t.error(`${e} is not JSON: ${s instanceof Error?s.message:String(s)}`),null}if(typeof i!="object"||i===null||Array.isArray(i))return t.error(`${e} must contain a theme object.`),null;const n=i;if("light"in n||"dark"in n){for(const s of["light","dark"]){const o=n[s];if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))return t.error(`${e}: "${s}" must be a theme object.`),null}return{light:n.light??{},dark:n.dark??{}}}return{light:n,dark:n}}function oe(e,t){const r=ie(e.file,t);if(!r)return 2;const i=G(P(r.light),P(r.dark));if(!i.valid){for(const c of i.warnings)t.error(`warning: ${c}`);for(const c of i.errors)t.error(`error: ${c}`);return t.error(`${e.file}: ${i.errors.length} validation error(s).`),1}const n=v(r.light,r.dark);for(const c of i.warnings)be(c,n)||t.error(`warning: ${c}`);const s=we(n),o=e.json?t.error:t.log;if(e.updateExpect!==void 0){try{t.writeFile(e.updateExpect,`${JSON.stringify(n,null,2)}
2
- `)}catch(c){return t.error(`Cannot write ${e.updateExpect}: ${c instanceof Error?c.message:String(c)}`),2}o(`Wrote fit tables to ${e.updateExpect}.`)}if(e.expect!==void 0){let c;try{c=t.readFile(e.expect)}catch{return t.error(`Expected fit tables not found at ${e.expect} \u2014 create them with --update-expect ${e.expect}.`),2}let a;try{a=JSON.parse(c)}catch{return t.error(`${e.expect} is not JSON.`),2}if(ce(a))return t.error(`${e.expect} was written by espalier \u22644.2.0 \u2014 regenerate it with --update-expect ${e.expect}.`),2;if(!se(a))return t.error(`${e.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${e.expect}.`),2;const f=me(a,n);if(f.length>0){s>0&&Ie(n,s,t);for(const u of f)t.error(`drift: ${u}`);return t.error(`Fit tables drifted from ${e.expect} (${f.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}o(`Fit tables match ${e.expect}.`)}return e.json?(t.log(JSON.stringify(n,null,2)),s>0?1:0):(Ae(n,s,t),s>0?1:0)}function se(e){if(!p(e)||!k.every(({field:r,kind:i})=>T(e[String(r)],i)))return!1;const t=e;if(!w(t.surfaces))return!1;for(const r of["light","dark"]){const n=t.paletteLints[r].map(h);if(!w(n))return!1;const s=t[r],o=new Set;for(const c of s){if(!le(c,r)||!t.surfaces.includes(c.surface)||o.has(c.surface))return!1;o.add(c.surface)}}return!0}function ce(e){return p(e)&&H(e.surfaces)&&Array.isArray(e.light)&&Array.isArray(e.dark)&&!("dataPalette"in e)&&!("paletteLints"in e)}function ae(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function w(e){return new Set(e).size===e.length}function fe(e){return p(e)&&M.every(({field:t,kind:r})=>T(e[String(t)],r))}function ue(e){return p(e)&&R.every(({field:t,kind:r})=>T(e[String(t)],r))}function de(e){return p(e)&&x.every(({field:t,kind:r})=>T(e[String(t)],r))}function T(e,t){switch(t){case"anchor":return e===void 0||V(e,N);case"anchor-record":return p(e)&&Object.keys(e).every(re)&&Object.values(e).every(r=>typeof r=="string");case"apca":return e===void 0||V(e,C);case"boolean":return typeof e=="boolean";case"data-palette-record":return p(e)?["light","dark"].every(r=>{const i=e[r];return p(i)&&A.every(n=>typeof i[n]=="string")}):!1;case"explicit":return e===void 0||Y.includes(e);case"fit-lint-id":return B.includes(e);case"lint-array":return Array.isArray(e)&&e.every(ue);case"message":case"string":return typeof e=="string";case"number":return ae(e);case"pairing":return e===void 0||Z.includes(e);case"palette-lint-id":return X.includes(e);case"palette-lint-record":return p(e)&&["light","dark"].every(r=>Array.isArray(e[r])&&e[r].every(fe));case"report-array":return Array.isArray(e);case"scheme":return e==="light"||e==="dark";case"semantic":return D(e);case"semantic-array":return Array.isArray(e)&&e.every(D);case"series-pair":return pe(e);case"simulation":return ee.includes(e);case"string-array":return H(e);case"token-array":return Array.isArray(e)&&e.every(de);case"warning":return Q.includes(e);default:{const r=t;return!1}}}function V(e,t){return p(e)&&t.every(({field:r,kind:i})=>T(e[String(r)],i))}function pe(e){if(!Array.isArray(e)||e.length!==2)return!1;const t=A.indexOf(e[0]),r=A.indexOf(e[1]);return t>=0&&r>t}function le(e,t){if(!p(e)||!_.every(({field:i,kind:n})=>T(e[String(i)],n)))return!1;const r=e;return r.scheme!==t?!1:w(r.tokens.map(i=>i.token))&&w(r.adjustedTokens)&&w(r.lints.map(i=>i.id))}function me(e,t){const r=[];for(const n of k)n.compared&&ge(r,n,e,t);return(g(z(e))!==g(z(t))||r.length===0&&g(e)!==g(t))&&r.push("fit tables differ outside compared fields"),r}function ge(e,t,r,i){const{field:n,kind:s}=t;if(s==="string-array"){const o=r[n],c=i[n];J(e,String(n),o,c),E(e,String(n),o,c);return}if(s==="data-palette-record"){const o=r[n],c=i[n];for(const a of["light","dark"])for(const f of A)K(e,`${a}/${String(n)}/${f}`,o[a][f],c[a][f]);return}if(s==="palette-lint-record"){const o=r[n],c=i[n];for(const a of["light","dark"])Te(e,a,String(n),o[a],c[a]),E(e,`${a}/${String(n)}`,o[a].map(h),c[a].map(h));return}if(s==="report-array"&&(n==="light"||n==="dark")){he(e,n,r[n],i[n]);return}F(e,"fit tables",String(n),r[n],i[n],s)}function he(e,t,r,i){const n=new Map(r.map(o=>[o.surface,o])),s=new Map(i.map(o=>[o.surface,o]));E(e,`${t}/reports`,r.map(o=>o.surface),i.map(o=>o.surface));for(const o of L(n.keys(),s.keys())){const c=n.get(o),a=s.get(o),f=`${t}/${o}`;if(!c||!a){e.push(`${f}: surface ${c?"removed":"added"}`);continue}$e(e,f,c,a)}}function $e(e,t,r,i){for(const n of _){const{compared:s,field:o,kind:c}=n;if(!(!s||o==="scheme"||o==="surface")){if(c==="anchor-record"){Ee(e,`${t}/${String(o)}`,r[o],i[o]);continue}if(c==="semantic-array"){const a=r[o],f=i[o];J(e,`${t}/${String(o)}`,a,f),E(e,`${t}/${String(o)}`,a,f);continue}if(c==="lint-array"){const a=r[o],f=i[o];ke(e,t,String(o),a,f),E(e,`${t}/${String(o)}`,a.map(u=>u.id),f.map(u=>u.id));continue}if(c==="token-array"){ye(e,t,String(o),r[o],i[o]);continue}F(e,t,String(o),r[o],i[o],c)}}}function ye(e,t,r,i,n){const s=new Map(i.map(a=>[a.token,a])),o=new Map(n.map(a=>[a.token,a]));E(e,`${t}/${r}`,i.map(a=>a.token),n.map(a=>a.token));const c=r==="tokens"?t:`${t}/${r}`;for(const a of L(s.keys(),o.keys())){const f=s.get(a),u=o.get(a),S=`${c}/${a}`;if(!f||!u){e.push(`${S}: token ${f?"removed":"added"}`);continue}Se(e,S,f,u)}}function Se(e,t,r,i){for(const{compared:n,field:s,kind:o}of x)if(!(!n||s==="token")){if(o==="anchor"){U(e,t,"anchor",r.anchor,i.anchor,N);continue}if(o==="apca"){U(e,t,"apca",r.apca,i.apca,C);continue}F(e,t,String(s),r[s],i[s],o)}}function U(e,t,r,i,n,s){const o=i,c=n;for(const{compared:a,field:f,kind:u}of s)a&&F(e,t,`${r}.${String(f)}`,o?.[f],c?.[f],u)}function ke(e,t,r,i,n){const s=new Map(i.map(c=>[c.id,c])),o=new Map(n.map(c=>[c.id,c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of R)if(!(!S||d==="id")){if(b==="semantic-array"){Fe(e,u,String(d),a[d],f[d]);continue}F(e,u,String(d),a[d],f[d],b)}}}function Te(e,t,r,i,n){const s=new Map(i.map(c=>[h(c),c])),o=new Map(n.map(c=>[h(c),c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of M)!S||d==="id"||d==="series"||d==="simulation"||F(e,u,String(d),a[d],f[d],b)}}function h(e){return`${e.id}/${e.series[0]}+${e.series[1]}/${e.simulation}`}function Ee(e,t,r,i){for(const n of L(Object.keys(r),Object.keys(i)))K(e,`${t}/${n}`,r[n],i[n])}function J(e,t,r,i){const n=new Set(r),s=new Set(i);for(const o of L(n,s))n.has(o)!==s.has(o)&&e.push(`${t}/${o}: ${n.has(o)?"removed":"added"}`)}function E(e,t,r,i){const n=new Set(r),s=new Set(i),o=r.filter(a=>s.has(a)),c=i.filter(a=>n.has(a));o.some((a,f)=>a!==c[f])&&e.push(`${t}: order changed`)}function Fe(e,t,r,i,n){const s=Math.max(i.length,n.length);for(let o=0;o<s;o+=1)W(e,t,`${r}[${o}]`,i[o],n[o])}function K(e,t,r,i){r!==i&&e.push(`${t}: ${j(r)} \u2192 ${j(i)}`)}function W(e,t,r,i,n,s){if(!Object.is(i,n)){if(s==="message"){e.push(`${t}: message changed`);return}e.push(`${t}: ${r} ${j(i)} \u2192 ${j(n)}`)}}function Le(e,t,r,i,n){g(i)!==g(n)&&e.push(`${t}: ${r} changed`)}function F(e,t,r,i,n,s){if(xe(s)){W(e,t,r,i,n,s);return}Le(e,t,r,i,n)}const _e={anchor:!1,"anchor-record":!1,apca:!1,boolean:!0,"data-palette-record":!1,explicit:!0,"fit-lint-id":!0,"lint-array":!1,message:!0,number:!0,pairing:!0,"palette-lint-id":!0,"palette-lint-record":!1,"report-array":!1,scheme:!0,semantic:!0,"semantic-array":!1,"series-pair":!1,simulation:!0,string:!0,"string-array":!1,"token-array":!1,warning:!0};function xe(e){return _e[e]===!0}function j(e){return e===void 0?"(absent)":e===""?'""':String(e)}function L(e,t){return[...new Set([...e,...t])].sort()}function g(e){return Array.isArray(e)?`[${e.map(g).join(",")}]`:p(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${g(e[t])}`).join(",")}}`:JSON.stringify(e)??"undefined"}function z(e){const t=m(e,$(k)),r=["light","dark"];if(y(k,"dataPalette")){const i=m(e.dataPalette,r);for(const n of r)l(i,n,m(e.dataPalette[n],A));l(t,"dataPalette",i)}if(y(k,"paletteLints")){const i=m(e.paletteLints,r);for(const n of r)l(i,n,q(e.paletteLints[n],h,$(M)));l(t,"paletteLints",i)}for(const i of r){if(!y(k,i))continue;const n=O();for(const s of e[i]){const o=m(s,$(_));if(y(_,"tokens")){const c=O();for(const a of s.tokens){const f=m(a,$(x));a.anchor&&y(x,"anchor")&&l(f,"anchor",m(a.anchor,$(N))),a.apca&&y(x,"apca")&&l(f,"apca",m(a.apca,$(C))),l(c,a.token,f)}l(o,"tokens",c)}y(_,"lints")&&l(o,"lints",q(s.lints,c=>c.id,$(R))),l(n,s.surface,o)}l(t,i,n)}return t}function q(e,t,r){const i=O();for(const n of e)l(i,t(n),m(n,r));return i}function $(e){return e.filter(({compared:t})=>t).map(({field:t})=>t)}function y(e,t){return e.some(r=>r.field===t&&r.compared)}function m(e,t){const r=new Set(t.map(String)),i=O();for(const[n,s]of Object.entries(e))r.has(n)||(i[n]=s);return i}function O(){return Object.create(null)}function l(e,t,r){Object.keys(r).length>0&&(e[t]=r)}function Ae(e,t,r){for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.log(` ${i} lint(${n.id}): ${n.message}`);for(const n of e[i]){r.log(je(i,n));for(const s of n.lints)r.log(` lint(${s.id}): ${s.message}`)}}r.log(`Checked ${e.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(t===0?"no lints.":`${t} lint(s), listed above.`))}function Ie(e,t,r){r.error(`${t} theme lint(s) are standing while fit-table drift is present:`);for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.error(`lint: ${i}/paletteLints/${h(n)}: ${n.message}`);for(const n of e[i])for(const s of n.lints)r.error(`lint: ${i}/${n.surface}/lints/${s.id}: ${s.message}`)}}function we(e){return[...e.light,...e.dark].reduce((r,i)=>r+i.lints.length,0)+e.paletteLints.light.length+e.paletteLints.dark.length}function be(e,t){return["light","dark"].some(r=>{const i=`${r}: `;if(!e.startsWith(i))return!1;const n=e.slice(i.length);return t.paletteLints[r].some(s=>te(n,s))})}function je(e,t){const r=t.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${t.adjustedTokens.join(", ")}`,i=t.tokens.filter(s=>s.explicit==="inherited").length,n=i===0?"":`; ${i} inherited explicit pin(s) \u2014 see the fit tables`;return`${e}/${t.surface}: ${t.tokens.length} tokens, ${r}${n}.`}export{Re as runEspalierCli};
1
+ import{encodeTheme as D,isObjectRecord as l,isSemanticColorName as P,validateThemePair as q}from"../shared/theme.js";import{THEME_FIT_ANCHOR_FIELDS as N,THEME_FIT_APCA_FIELDS as C,THEME_FIT_DATA_PALETTE_LINT_FIELDS as M,THEME_FIT_DATA_PALETTE_LINT_IDS as G,THEME_FIT_EXPLICIT_VALUES as X,THEME_FIT_LINT_FIELDS as R,THEME_FIT_LINT_IDS as Y,THEME_FIT_LINT_SEVERITIES as B,THEME_FIT_PAIRING_VALUES as Q,THEME_FIT_REPORT_FIELDS as _,THEME_FIT_SUITE_FIELDS as k,THEME_FIT_TOKEN_FIELDS as I,themeFitReportSuite as Z}from"../shared/theme-fit-report.js";import{COLOR_VISION_SIMULATIONS as v,DATA_SERIES_KEYS as x,isPaletteCollisionDescription as ee}from"../shared/data-colors.js";import{isSafeKey as te}from"../shared/unsafe-keys.js";const A="usage: espalier theme check <theme.json> [--json] [--expect <fit.json>] [--update-expect <fit.json>]";function Me(e,t){const[r,o,...n]=e;if(r!=="theme"||o!=="check")return t.error(A),2;const s=re(n,t);return s?oe(s,t):2}function re(e,t){const r={file:"",json:!1};for(let o=0;o<e.length;o+=1){const n=e[o];if(n==="--json")r.json=!0;else if(n==="--expect"||n==="--update-expect"){const s=e[o+1];if(s===void 0)return t.error(`${n} requires a file path. ${A}`),null;n==="--expect"?r.expect=s:r.updateExpect=s,o+=1}else if(!n.startsWith("--")&&r.file==="")r.file=n;else return t.error(`Unknown argument "${n}". ${A}`),null}return r.file===""?(t.error(A),null):r.expect!==void 0&&r.updateExpect!==void 0?(t.error(`--expect checks the committed fit tables and --update-expect rewrites them \u2014 pick one. ${A}`),null):r}function ne(e,t){let r;try{r=t.readFile(e)}catch(s){return t.error(`Cannot read ${e}: ${s instanceof Error?s.message:String(s)}`),null}let o;try{o=JSON.parse(r)}catch(s){return t.error(`${e} is not JSON: ${s instanceof Error?s.message:String(s)}`),null}if(typeof o!="object"||o===null||Array.isArray(o))return t.error(`${e} must contain a theme object.`),null;const n=o;if("light"in n||"dark"in n){for(const s of["light","dark"]){const i=n[s];if(i!==void 0&&(typeof i!="object"||i===null||Array.isArray(i)))return t.error(`${e}: "${s}" must be a theme object.`),null}return{light:n.light??{},dark:n.dark??{}}}return{light:n,dark:n}}function oe(e,t){const r=ne(e.file,t);if(!r)return 2;const o=q(D(r.light),D(r.dark));if(!o.valid){for(const c of o.warnings)t.error(`warning: ${c}`);for(const c of o.errors)t.error(`error: ${c}`);return t.error(`${e.file}: ${o.errors.length} validation error(s).`),1}const n=Z(r.light,r.dark);for(const c of o.warnings)we(c,n)||t.error(`warning: ${c}`);const s=Ae(n),i=e.json?t.error:t.log;if(e.updateExpect!==void 0){try{t.writeFile(e.updateExpect,`${JSON.stringify(n,null,2)}
2
+ `)}catch(c){return t.error(`Cannot write ${e.updateExpect}: ${c instanceof Error?c.message:String(c)}`),2}i(`Wrote fit tables to ${e.updateExpect}.`)}if(e.expect!==void 0){let c;try{c=t.readFile(e.expect)}catch{return t.error(`Expected fit tables not found at ${e.expect} \u2014 create them with --update-expect ${e.expect}.`),2}let a;try{a=JSON.parse(c)}catch{return t.error(`${e.expect} is not JSON.`),2}if(!ie(a))return t.error(`${e.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${e.expect}.`),2;const f=le(a,n);if(f.length>0){s>0&&xe(n,s,t);for(const u of f)t.error(`drift: ${u}`);return t.error(`Fit tables drifted from ${e.expect} (${f.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}i(`Fit tables match ${e.expect}.`)}return e.json?(t.log(JSON.stringify(n,null,2)),s>0?1:0):(Ie(n,s,t),s>0?1:0)}function ie(e){if(!l(e)||!k.every(({field:r,kind:o})=>T(e[String(r)],o)))return!1;const t=e;if(!w(t.surfaces))return!1;for(const r of["light","dark"]){const n=t.paletteLints[r].map(h);if(!w(n))return!1;const s=t[r],i=new Set;for(const c of s){if(!pe(c,r)||!t.surfaces.includes(c.surface)||i.has(c.surface))return!1;i.add(c.surface)}}return!0}function se(e){return typeof e=="number"&&Number.isFinite(e)}function ce(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function w(e){return new Set(e).size===e.length}function ae(e){return l(e)&&M.every(({field:t,kind:r})=>T(e[String(t)],r))}function fe(e){return l(e)&&R.every(({field:t,kind:r})=>T(e[String(t)],r))}function ue(e){return l(e)&&I.every(({field:t,kind:r})=>T(e[String(t)],r))}function T(e,t){switch(t){case"anchor":return e===void 0||H(e,N);case"anchor-record":return l(e)&&Object.keys(e).every(te)&&Object.values(e).every(r=>typeof r=="string");case"apca":return e===void 0||H(e,C);case"boolean":return typeof e=="boolean";case"data-palette-record":return l(e)?["light","dark"].every(r=>{const o=e[r];return l(o)&&x.every(n=>typeof o[n]=="string")}):!1;case"explicit":return e===void 0||X.includes(e);case"fit-lint-id":return Y.includes(e);case"lint-array":return Array.isArray(e)&&e.every(fe);case"message":case"string":return typeof e=="string";case"number":return se(e);case"pairing":return e===void 0||Q.includes(e);case"palette-lint-id":return G.includes(e);case"palette-lint-record":return l(e)&&["light","dark"].every(r=>Array.isArray(e[r])&&e[r].every(ae));case"report-array":return Array.isArray(e);case"scheme":return e==="light"||e==="dark";case"semantic":return P(e);case"semantic-array":return Array.isArray(e)&&e.every(P);case"series-pair":return de(e);case"simulation":return v.includes(e);case"string-array":return ce(e);case"token-array":return Array.isArray(e)&&e.every(ue);case"warning":return B.includes(e);default:{const r=t;return!1}}}function H(e,t){return l(e)&&t.every(({field:r,kind:o})=>T(e[String(r)],o))}function de(e){if(!Array.isArray(e)||e.length!==2)return!1;const t=x.indexOf(e[0]),r=x.indexOf(e[1]);return t>=0&&r>t}function pe(e,t){if(!l(e)||!_.every(({field:o,kind:n})=>T(e[String(o)],n)))return!1;const r=e;return r.scheme!==t?!1:w(r.tokens.map(o=>o.token))&&w(r.adjustedTokens)&&w(r.lints.map(o=>o.id))}function le(e,t){const r=[];for(const n of k)n.compared&&me(r,n,e,t);return(g(W(e))!==g(W(t))||r.length===0&&g(e)!==g(t))&&r.push("fit tables differ outside compared fields"),r}function me(e,t,r,o){const{field:n,kind:s}=t;if(s==="string-array"){const i=r[n],c=o[n];U(e,String(n),i,c),E(e,String(n),i,c);return}if(s==="data-palette-record"){const i=r[n],c=o[n];for(const a of["light","dark"])for(const f of x)J(e,`${a}/${String(n)}/${f}`,i[a][f],c[a][f]);return}if(s==="palette-lint-record"){const i=r[n],c=o[n];for(const a of["light","dark"])ke(e,a,String(n),i[a],c[a]),E(e,`${a}/${String(n)}`,i[a].map(h),c[a].map(h));return}if(s==="report-array"&&(n==="light"||n==="dark")){ge(e,n,r[n],o[n]);return}F(e,"fit tables",String(n),r[n],o[n],s)}function ge(e,t,r,o){const n=new Map(r.map(i=>[i.surface,i])),s=new Map(o.map(i=>[i.surface,i]));E(e,`${t}/reports`,r.map(i=>i.surface),o.map(i=>i.surface));for(const i of L(n.keys(),s.keys())){const c=n.get(i),a=s.get(i),f=`${t}/${i}`;if(!c||!a){e.push(`${f}: surface ${c?"removed":"added"}`);continue}he(e,f,c,a)}}function he(e,t,r,o){for(const n of _){const{compared:s,field:i,kind:c}=n;if(!(!s||i==="scheme"||i==="surface")){if(c==="anchor-record"){Te(e,`${t}/${String(i)}`,r[i],o[i]);continue}if(c==="semantic-array"){const a=r[i],f=o[i];U(e,`${t}/${String(i)}`,a,f),E(e,`${t}/${String(i)}`,a,f);continue}if(c==="lint-array"){const a=r[i],f=o[i];Se(e,t,String(i),a,f),E(e,`${t}/${String(i)}`,a.map(u=>u.id),f.map(u=>u.id));continue}if(c==="token-array"){$e(e,t,String(i),r[i],o[i]);continue}F(e,t,String(i),r[i],o[i],c)}}}function $e(e,t,r,o,n){const s=new Map(o.map(a=>[a.token,a])),i=new Map(n.map(a=>[a.token,a]));E(e,`${t}/${r}`,o.map(a=>a.token),n.map(a=>a.token));const c=r==="tokens"?t:`${t}/${r}`;for(const a of L(s.keys(),i.keys())){const f=s.get(a),u=i.get(a),S=`${c}/${a}`;if(!f||!u){e.push(`${S}: token ${f?"removed":"added"}`);continue}ye(e,S,f,u)}}function ye(e,t,r,o){for(const{compared:n,field:s,kind:i}of I)if(!(!n||s==="token")){if(i==="anchor"){V(e,t,"anchor",r.anchor,o.anchor,N);continue}if(i==="apca"){V(e,t,"apca",r.apca,o.apca,C);continue}F(e,t,String(s),r[s],o[s],i)}}function V(e,t,r,o,n,s){const i=o,c=n;for(const{compared:a,field:f,kind:u}of s)a&&F(e,t,`${r}.${String(f)}`,i?.[f],c?.[f],u)}function Se(e,t,r,o,n){const s=new Map(o.map(c=>[c.id,c])),i=new Map(n.map(c=>[c.id,c]));for(const c of L(s.keys(),i.keys())){const a=s.get(c),f=i.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of R)if(!(!S||d==="id")){if(b==="semantic-array"){Ee(e,u,String(d),a[d],f[d]);continue}F(e,u,String(d),a[d],f[d],b)}}}function ke(e,t,r,o,n){const s=new Map(o.map(c=>[h(c),c])),i=new Map(n.map(c=>[h(c),c]));for(const c of L(s.keys(),i.keys())){const a=s.get(c),f=i.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of M)!S||d==="id"||d==="series"||d==="simulation"||F(e,u,String(d),a[d],f[d],b)}}function h(e){return`${e.id}/${e.series[0]}+${e.series[1]}/${e.simulation}`}function Te(e,t,r,o){for(const n of L(Object.keys(r),Object.keys(o)))J(e,`${t}/${n}`,r[n],o[n])}function U(e,t,r,o){const n=new Set(r),s=new Set(o);for(const i of L(n,s))n.has(i)!==s.has(i)&&e.push(`${t}/${i}: ${n.has(i)?"removed":"added"}`)}function E(e,t,r,o){const n=new Set(r),s=new Set(o),i=r.filter(a=>s.has(a)),c=o.filter(a=>n.has(a));i.some((a,f)=>a!==c[f])&&e.push(`${t}: order changed`)}function Ee(e,t,r,o,n){const s=Math.max(o.length,n.length);for(let i=0;i<s;i+=1)K(e,t,`${r}[${i}]`,o[i],n[i])}function J(e,t,r,o){r!==o&&e.push(`${t}: ${j(r)} \u2192 ${j(o)}`)}function K(e,t,r,o,n,s){if(!Object.is(o,n)){if(s==="message"){e.push(`${t}: message changed`);return}e.push(`${t}: ${r} ${j(o)} \u2192 ${j(n)}`)}}function Fe(e,t,r,o,n){g(o)!==g(n)&&e.push(`${t}: ${r} changed`)}function F(e,t,r,o,n,s){if(_e(s)){K(e,t,r,o,n,s);return}Fe(e,t,r,o,n)}const Le={anchor:!1,"anchor-record":!1,apca:!1,boolean:!0,"data-palette-record":!1,explicit:!0,"fit-lint-id":!0,"lint-array":!1,message:!0,number:!0,pairing:!0,"palette-lint-id":!0,"palette-lint-record":!1,"report-array":!1,scheme:!0,semantic:!0,"semantic-array":!1,"series-pair":!1,simulation:!0,string:!0,"string-array":!1,"token-array":!1,warning:!0};function _e(e){return Le[e]===!0}function j(e){return e===void 0?"(absent)":e===""?'""':String(e)}function L(e,t){return[...new Set([...e,...t])].sort()}function g(e){return Array.isArray(e)?`[${e.map(g).join(",")}]`:l(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${g(e[t])}`).join(",")}}`:JSON.stringify(e)??"undefined"}function W(e){const t=m(e,$(k)),r=["light","dark"];if(y(k,"dataPalette")){const o=m(e.dataPalette,r);for(const n of r)p(o,n,m(e.dataPalette[n],x));p(t,"dataPalette",o)}if(y(k,"paletteLints")){const o=m(e.paletteLints,r);for(const n of r)p(o,n,z(e.paletteLints[n],h,$(M)));p(t,"paletteLints",o)}for(const o of r){if(!y(k,o))continue;const n=O();for(const s of e[o]){const i=m(s,$(_));if(y(_,"tokens")){const c=O();for(const a of s.tokens){const f=m(a,$(I));a.anchor&&y(I,"anchor")&&p(f,"anchor",m(a.anchor,$(N))),a.apca&&y(I,"apca")&&p(f,"apca",m(a.apca,$(C))),p(c,a.token,f)}p(i,"tokens",c)}y(_,"lints")&&p(i,"lints",z(s.lints,c=>c.id,$(R))),p(n,s.surface,i)}p(t,o,n)}return t}function z(e,t,r){const o=O();for(const n of e)p(o,t(n),m(n,r));return o}function $(e){return e.filter(({compared:t})=>t).map(({field:t})=>t)}function y(e,t){return e.some(r=>r.field===t&&r.compared)}function m(e,t){const r=new Set(t.map(String)),o=O();for(const[n,s]of Object.entries(e))r.has(n)||(o[n]=s);return o}function O(){return Object.create(null)}function p(e,t,r){Object.keys(r).length>0&&(e[t]=r)}function Ie(e,t,r){for(const o of["light","dark"]){for(const n of e.paletteLints[o])r.log(` ${o} lint(${n.id}): ${n.message}`);for(const n of e[o]){r.log(be(o,n));for(const s of n.lints)r.log(` lint(${s.id}): ${s.message}`)}}r.log(`Checked ${e.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(t===0?"no lints.":`${t} lint(s), listed above.`))}function xe(e,t,r){r.error(`${t} theme lint(s) are standing while fit-table drift is present:`);for(const o of["light","dark"]){for(const n of e.paletteLints[o])r.error(`lint: ${o}/paletteLints/${h(n)}: ${n.message}`);for(const n of e[o])for(const s of n.lints)r.error(`lint: ${o}/${n.surface}/lints/${s.id}: ${s.message}`)}}function Ae(e){return[...e.light,...e.dark].reduce((r,o)=>r+o.lints.length,0)+e.paletteLints.light.length+e.paletteLints.dark.length}function we(e,t){return["light","dark"].some(r=>{const o=`${r}: `;if(!e.startsWith(o))return!1;const n=e.slice(o.length);return t.paletteLints[r].some(s=>ee(n,s))})}function be(e,t){const r=t.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${t.adjustedTokens.join(", ")}`,o=t.tokens.filter(s=>s.explicit==="inherited").length,n=o===0?"":`; ${o} inherited explicit pin(s) \u2014 see the fit tables`;return`${e}/${t.surface}: ${t.tokens.length} tokens, ${r}${n}.`}export{Me as runEspalierCli};
@@ -1,4 +1,4 @@
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`
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 F}from"lit/directives/repeat.js";import{EspalierElementBase as P}from"../shared/esp-element-base.js";import{PopoverController as x}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 I,MINUTES_60 as q,MONTH_GRID_COLS as T,MONTH_NAMES as w,MONTH_SHORT_NAMES as W,WEEKDAY_LABELS as H}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 x({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)}setFormItemInvalid(e){this.formItemDescription.setInvalid(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
@@ -83,7 +83,7 @@ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnP
83
83
  </button></span
84
84
  >`}_renderDaySurface(){const e=this._getGrid(),t=`${w[this.viewDate.month-1]} ${this.viewDate.year}`;return l`
85
85
  <div class="weekday-row" role="row">
86
- ${I.map(i=>l`<abbr class="weekday-label" title=${i}>${i}</abbr>`)}
86
+ ${H.map(i=>l`<abbr class="weekday-label" title=${i}>${i}</abbr>`)}
87
87
  </div>
88
88
 
89
89
  <div class="day-grid" role="grid" aria-label=${t}>${this._renderGridRows(e)}</div>
@@ -95,7 +95,7 @@ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnP
95
95
  aria-label=${`Months of ${e}`}
96
96
  @keydown=${t=>this._handleMonthKeyDown(t)}
97
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`
98
+ ${W.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
99
  <button
100
100
  type="button"
101
101
  role="option"
@@ -138,7 +138,7 @@ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnP
138
138
  </div>
139
139
  `}_renderGridRows(e){const t=[];for(let i=0;i<j;i++){const s=e.slice(i*R,(i+1)*R);t.push(l`
140
140
  <div class="day-row" role="row">
141
- ${x(s,a=>a.date.toString(),a=>this._renderDayCell(a))}
141
+ ${F(s,a=>a.date.toString(),a=>this._renderDayCell(a))}
142
142
  </div>
143
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`
144
144
  <button
@@ -165,7 +165,7 @@ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnP
165
165
  .value=${String(this._hour)}
166
166
  @esp-value-changed=${e=>{e.stopPropagation(),e.detail?.value&&(this._hour=Number(e.detail.value),this._commitTime())}}
167
167
  >
168
- ${q.map(e=>l`
168
+ ${I.map(e=>l`
169
169
  <esp-picker-item
170
170
  text=${String(e)}
171
171
  value=${String(e)}
@@ -183,7 +183,7 @@ var n=function(y,e,t,i){var s=arguments.length,a=s<3?e:i===null?i=Object.getOwnP
183
183
  .value=${String(this._minute)}
184
184
  @esp-value-changed=${e=>{e.stopPropagation(),e.detail?.value&&(this._minute=Number(e.detail.value),this._commitTime())}}
185
185
  >
186
- ${W.map(e=>l`
186
+ ${q.map(e=>l`
187
187
  <esp-picker-item
188
188
  text=${String(e).padStart(2,"0")}
189
189
  value=${String(e)}
@@ -193,7 +193,7 @@ import { type FlyoutCloseReason } from "../shared/flyout-events.js";
193
193
  * ```html
194
194
  * <style>
195
195
  * esp-page.flyout-bus-demo {
196
- * --esp-page-max-width: 420px;
196
+ * --esp-page-main-max-width: 420px;
197
197
  * &::part(wrapper) {
198
198
  * min-height: 320px;
199
199
  * }
@@ -19,7 +19,7 @@ var l=function(u,e,t,s){var o=arguments.length,r=o<3?e:s===null?s=Object.getOwnP
19
19
  inset-inline-end: 0;
20
20
  block-size: auto;
21
21
  max-block-size: none;
22
- width: min(var(--esp-page-flyout-width, var(--esp-page-flyout-max-width, 30rem)), 85vw);
22
+ width: min(var(--esp-page-flyout-max-width, 30rem), 85vw);
23
23
  overflow-y: auto;
24
24
 
25
25
  border-start-end-radius: 0;
@@ -58,10 +58,7 @@ var l=function(u,e,t,s){var o=arguments.length,r=o<3?e:s===null?s=Object.getOwnP
58
58
  :host([open]) {
59
59
  display: block;
60
60
 
61
- width: var(
62
- --_esp-flyout-used-width,
63
- var(--esp-page-flyout-width, var(--esp-page-flyout-min-width, 20rem))
64
- );
61
+ width: var(--_esp-flyout-used-width, var(--esp-page-flyout-min-width, 20rem));
65
62
  margin-block-start: calc(
66
63
  var(--_esp-flyout-anchor-offset, 0px) - var(--_esp-flyout-viewport-shift, 0px)
67
64
  );
@@ -74,10 +71,7 @@ var l=function(u,e,t,s){var o=arguments.length,r=o<3?e:s===null?s=Object.getOwnP
74
71
  .panel {
75
72
  background: var(--esp-flyout-background, var(--esp-color-background));
76
73
 
77
- width: var(
78
- --_esp-flyout-used-width,
79
- var(--esp-page-flyout-width, var(--esp-page-flyout-min-width, 20rem))
80
- );
74
+ width: var(--_esp-flyout-used-width, var(--esp-page-flyout-min-width, 20rem));
81
75
  display: flex;
82
76
  flex-direction: column;
83
77
  position: relative;
@@ -1,9 +1,9 @@
1
- var h=function(e,t,o,i){var s=arguments.length,n=s<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,o):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")n=Reflect.decorate(e,t,o,i);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(n=(s<3?a(n):s>3?a(t,o,n):a(t,o))||n);return s>3&&n&&Object.defineProperty(t,o,n),n};import"../pickers/esp-pick-one.js";import"../tooltip/esp-tooltip.js";import{customElement as A,property as F,state as L}from"lit/decorators.js";import{EspalierElementBase as x}from"../shared/esp-element-base.js";import{html as N}from"lit";import{extractFamily as U,getFallbackFont as B,removeRuntimeGoogleFontLink as O,syncRuntimeGoogleFontLink as q}from"../shared/font-helpers.js";import{fontFallbackAliases as W}from"../shared/font-plan.js";import{customWebSafeFont as I,matchWebSafeFont as j}from"../shared/font-stacks.js";import{getIconHrefForHost as P}from"../shared/intent-values.js";import{WEB_SAFE_FONTS as E,isSystemPreset as _}from"./font-types.js";import{DEVICE_DEFAULT_WEIGHTS as ft,SYSTEM_TEXT_WEIGHTS as dt,WEB_SAFE_FONTS as ht}from"./font-types.js";let y,m;const M=async()=>{const e=document.getElementsByTagName("esp-root")[0];if(!e)throw new Error("<esp-font-picker> requires an <esp-root> ancestor. Wrap your application in <esp-root> to use the font picker.");const t=e.fontDefinitionsUrl||`${e.fontCSSRoot}font-definitions.json`,o=await fetch(t);if(!o.ok)throw new Error(`Failed to load font definitions from ${t} (${o.status}). Run 'npm run build-fonts' to generate the font catalog.`);return await o.json()},z=async()=>{if(y)return y;if(!m){const e=M().then(t=>(y=t,t),t=>{throw m===e&&(m=void 0),t});m=e}return m},k="esp-preview-",H=e=>`${k}${e}`,g=new Map,v=async e=>{if(g.has(e))return!0;try{const t=document.getElementsByTagName("esp-root")[0];if(!t)return!1;const o=e.replaceAll(" ","-"),i=await fetch(`${t.fontCSSRoot}${o}.css`);if(!i.ok)return!1;let s=await i.text();s=s.replace(/font-family:\s*'([^']+)'/g,(a,l)=>`font-family: '${k}${l}'`);const n=document.createElement("style");return n.textContent=s,n.dataset.font=e,document.head.appendChild(n),g.set(e,n),!0}catch(t){return console.warn(`Failed to load CSS for font ${e}:`,t),!1}},S=e=>{const t=g.get(e);t&&(t.remove(),g.delete(e))},w="data-esp-font-picker",R="data-esp-font-picker-root",$=e=>e.closest("esp-root"),V=e=>$(e)?.correlationId??"",X=(e,t)=>`link[${w}="${CSS.escape(e)}"][${R}="${CSS.escape(t)}"]`,C=(e,t)=>`picker:${t}:${e}`,b=(e,t)=>{if(!t)return;const o=$(e),i=o?.correlationId??"";if(o?.googleFontLoading==="none"){p(e,t);return}q({owner:C(t,i),family:t,enabled:!0,attributes:{[w]:t,[R]:i}})},p=(e,t)=>{if(!t)return;const o=V(e);Array.from(document.getElementsByTagName("esp-font-picker")).some(s=>V(s)===o&&s.selectedGoogleFamily===t)||(O(C(t,o)),document.head.querySelector(X(t,o))?.remove())},f=e=>e.kind!=="web-safe",G="http://www.w3.org/2000/svg",K=(e,t)=>{const o=document.createElement("esp-tooltip");o.setAttribute("text",t==="device"?"Device font, no download":"Google font"),o.setAttribute("trigger-tabindex","-1"),o.setAttribute("style","display: grid; place-self: center;");const i=document.createElementNS(G,"svg");i.setAttribute("aria-hidden","true"),i.setAttribute("style","display: block; width: var(--esp-size-medium); height: var(--esp-size-medium); margin: var(--esp-size-tiny);");const s=document.createElementNS(G,"use");return s.setAttribute("href",P(t==="device"?"device-desktop":"brand-google",e)),i.append(s),o.append(i),o},T=e=>f(e)?e.family:e.stack,Y=e=>{if(!f(e))return e.stack;const t=W(e.family,400,e.category);return[`"${e.family}"`,...t,`"${H(e.family)}"`,B(e.category)].join(", ")},D=(e,t)=>e.filter(o=>{switch(t){case"not-display":return o.category!=="display";default:return o.category===t}});let d=class extends x{constructor(){super(...arguments),this.loadedFonts=new Set,this.formItemDescription=null,this.formItemLabel=null,this._rangeGeneration=0,this._initGeneration=0,this._fontsReady=Promise.resolve(),this.fonts=[],this.category=null,this.fontSource="google",this.value="",this.placeholder="Choose a font...",this.handleItemsInViewEvent=t=>{t.stopPropagation(),this.handleItemsInView(t.detail)}}focus(){this.shadowRoot?.querySelector("esp-pick-one")?.focus()}setFormItemDescription(t){this.formItemDescription=t,this.syncFormItemDescription()}setFormItemLabel(t){this.formItemLabel=t,this.syncFormItemDescription()}syncFormItemDescription(){const t=this.shadowRoot?.querySelector("esp-pick-one");t?.setFormItemDescription?.(this.formItemDescription),t?.setFormItemLabel?.(this.formItemLabel)}async getUpdateComplete(){const t=await super.getUpdateComplete();return await this._fontsReady,t}firstUpdated(t){super.firstUpdated(t),this._fontsReady=this.initFonts()}updated(t){super.updated(t),this.syncFormItemDescription();const o=t.has("fontSource")&&t.get("fontSource")!==void 0,i=t.has("category")&&t.get("category")!==void 0;if(o||i){if(o&&this.fontSource==="web-safe"){const s=this.value;for(const n of this.loadedFonts)S(n);this.loadedFonts.clear(),this.value="",s&&p(this,s)}this._fontsReady=this.initFonts()}if(t.has("value")&&this.value&&this.fontSource!=="web-safe"){const s=t.get("value"),n=this.googleFamilyFor(this.value),a=s?this.googleFamilyFor(s)??void 0:void 0;n&&s!==this.value?this.ensureFontLoaded(n,this.value,a):!n&&a&&p(this,a)}}get selectedGoogleFamily(){return this.fontSource==="web-safe"?null:this.googleFamilyFor(this.value)}googleFamilyFor(t){if(!t)return null;const o=this.fonts.filter(f);if(o.some(s=>s.family===t))return t;const i=U(t);return o.some(s=>s.family===i)?i:null}resolveSelection(){const t=this.value;if(!t||this.fonts.length===0)return{font:null,rowValue:t};const o=this.fontSource==="web-safe"?null:this.googleFamilyFor(t);if(o)return{font:this.fonts.find(l=>f(l)&&l.family===o)??null,rowValue:o};if(this.fontSource==="google")return{font:null,rowValue:t};const i=this.fonts.filter(a=>!f(a)),s=j(t,i);if(s)return{font:s,rowValue:s.stack};const n=I(t);return{font:n,rowValue:n?.stack??t}}async ensureFontLoaded(t,o,i){await v(t)&&this.loadedFonts.add(t),this.value===o&&(b(this,t),i&&i!==t&&p(this,i))}async initFonts(){const t=++this._initGeneration,o=this.fontSource,i=this.category?D(E,this.category):E;if(o==="web-safe"){this.fonts=i;return}const s=[...i.filter(_),...i.filter(u=>!_(u))];o==="all"&&(this.fonts=s);let n;try{n=await z()}catch(u){if(o!=="all")throw u;console.warn("esp-font-picker: the Google catalog is unavailable; listing device fonts only.",u);return}if(t!==this._initGeneration||this.fontSource!==o)return;const a=this.category?D(n,this.category):n;this.fonts=o==="all"?[...s,...a]:a;const l=this.value,c=this.googleFamilyFor(l);if(c){if(await v(c)){if(t!==this._initGeneration||this.fontSource!==o||this.value!==l){S(c);return}this.loadedFonts.add(c)}if(t!==this._initGeneration||this.fontSource!==o||this.value!==l)return;b(this,c)}}async handleItemsInView(t){if(this.fontSource==="web-safe")return;const o=++this._rangeGeneration,i=3,s=t.items??[],n=new Set,a=new Set(this.fonts.filter(f).map(r=>r.family)),l=Math.max(0,t.first),c=Math.min(t.last+i,s.length);for(let r=l;r<c;r++)a.has(s[r].value)&&n.add(s[r].value);for(const r of n)this.loadedFonts.has(r)||await v(r)&&this.loadedFonts.add(r);if(o!==this._rangeGeneration)return;const u=new Set(Array.from(document.getElementsByTagName("esp-font-picker")).map(r=>r.selectedGoogleFamily).filter(r=>!!r));for(const r of this.loadedFonts)u.has(r)||n.has(r)||(this.loadedFonts.delete(r),S(r))}render(){const t=this.resolveSelection(),o=this.fontSource==="all",s=[...t.font&&!this.fonts.includes(t.font)?[t.font]:[],...this.fonts].map(n=>({text:n.family,value:T(n),selected:t.font===n,styles:{fontFamily:Y(n)},...o?{slotNodes:[K(this,f(n)?"google":"device")]}:{}}));return N`<esp-pick-one
1
+ var h=function(e,t,o,i){var s=arguments.length,n=s<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,o):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")n=Reflect.decorate(e,t,o,i);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(n=(s<3?a(n):s>3?a(t,o,n):a(t,o))||n);return s>3&&n&&Object.defineProperty(t,o,n),n};import"../pickers/esp-pick-one.js";import"../tooltip/esp-tooltip.js";import{customElement as x,property as y,state as A}from"lit/decorators.js";import{EspalierElementBase as T}from"../shared/esp-element-base.js";import{html as D}from"lit";import{extractFamily as L,getFallbackFont as N,removeRuntimeGoogleFontLink as B,removeRuntimeGoogleFontLinks as U,syncRuntimeGoogleFontLink as W}from"../shared/font-helpers.js";import{fontFallbackAliases as j}from"../shared/font-plan.js";import{customWebSafeFont as E,matchWebSafeFont as O}from"../shared/font-stacks.js";import{getIconHrefForHost as q}from"../shared/intent-values.js";import{WEB_SAFE_FONTS as I,isSystemPreset as b}from"./font-types.js";import{FormItemRelay as P}from"../shared/form-item-relay.js";import{DEVICE_DEFAULT_WEIGHTS as ut,SYSTEM_TEXT_WEIGHTS as dt,WEB_SAFE_FONTS as ht}from"./font-types.js";let F,m;const M=async()=>{const e=document.getElementsByTagName("esp-root")[0];if(!e)throw new Error("<esp-font-picker> requires an <esp-root> ancestor. Wrap your application in <esp-root> to use the font picker.");const t=e.fontDefinitionsUrl||`${e.fontCSSRoot}font-definitions.json`,o=await fetch(t);if(!o.ok)throw new Error(`Failed to load font definitions from ${t} (${o.status}). Run 'npm run build-fonts' to generate the font catalog.`);return await o.json()},z=async()=>{if(F)return F;if(!m){const e=M().then(t=>(F=t,t),t=>{throw m===e&&(m=void 0),t});m=e}return m},R="esp-preview-",H=e=>`${R}${e}`,g=new Map,v=async e=>{if(g.has(e))return!0;try{const t=document.getElementsByTagName("esp-root")[0];if(!t)return!1;const o=e.replaceAll(" ","-"),i=await fetch(`${t.fontCSSRoot}${o}.css`);if(!i.ok)return!1;let s=await i.text();s=s.replace(/font-family:\s*'([^']+)'/g,(a,l)=>`font-family: '${R}${l}'`);const n=document.createElement("style");return n.textContent=s,n.dataset.font=e,document.head.appendChild(n),g.set(e,n),!0}catch(t){return console.warn(`Failed to load CSS for font ${e}:`,t),!1}},w=e=>{const t=g.get(e);t&&(t.remove(),g.delete(e))},_=e=>e.closest("esp-root"),k=e=>_(e)?.correlationId??"",G=(e,t)=>`picker:${t}:${e}`,S=(e,t)=>{if(!t)return;const o=_(e),i=o?.correlationId??"";if(o?.googleFontLoading==="none"){p(e,t);return}W({owner:G(t,i),family:t,enabled:!0})},p=(e,t)=>{if(!t)return;const o=k(e);Array.from(document.getElementsByTagName("esp-font-picker")).some(s=>k(s)===o&&s.selectedGoogleFamily===t)||B(G(t,o))},d=e=>e.kind!=="web-safe",V="http://www.w3.org/2000/svg",X=(e,t)=>{const o=document.createElement("esp-tooltip");o.setAttribute("text",t==="device"?"Device font, no download":"Google font"),o.setAttribute("trigger-tabindex","-1"),o.setAttribute("style","display: grid; place-self: center;");const i=document.createElementNS(V,"svg");i.setAttribute("aria-hidden","true"),i.setAttribute("style","display: block; width: var(--esp-size-medium); height: var(--esp-size-medium); margin: var(--esp-size-tiny);");const s=document.createElementNS(V,"use");return s.setAttribute("href",q(t==="device"?"device-desktop":"brand-google",e)),i.append(s),o.append(i),o},C=e=>d(e)?e.family:e.stack,K=e=>{if(!d(e))return e.stack;const t=j(e.family,400,e.category);return[`"${e.family}"`,...t,`"${H(e.family)}"`,N(e.category)].join(", ")},$=(e,t)=>e.filter(o=>{switch(t){case"not-display":return o.category!=="display";default:return o.category===t}});let u=class extends T{constructor(){super(...arguments),this.loadedFonts=new Set,this.formItemRelay=new P(()=>this.shadowRoot?.querySelector("esp-pick-one")),this._rangeGeneration=0,this._initGeneration=0,this._fontsReady=Promise.resolve(),this.fonts=[],this.category=null,this.fontSource="google",this.value="",this.placeholder="Choose a font...",this.handleItemsInViewEvent=t=>{t.stopPropagation(),this.handleItemsInView(t.detail)}}focus(){this.shadowRoot?.querySelector("esp-pick-one")?.focus()}setFormItemDescription(t){this.formItemRelay.setDescription(t)}setFormItemLabel(t){this.formItemRelay.setLabel(t)}setFormItemInvalid(t){this.formItemRelay.setInvalid(t)}async getUpdateComplete(){const t=await super.getUpdateComplete();return await this._fontsReady,t}firstUpdated(t){super.firstUpdated(t),this._fontsReady=this.initFonts()}updated(t){super.updated(t),this.formItemRelay.apply();const o=t.has("fontSource")&&t.get("fontSource")!==void 0,i=t.has("category")&&t.get("category")!==void 0;if(o||i){if(o&&this.fontSource==="web-safe"){const s=this.value;for(const n of this.loadedFonts)w(n);this.loadedFonts.clear(),this.value="",s&&p(this,s)}this._fontsReady=this.initFonts()}if(t.has("value")&&this.value&&this.fontSource!=="web-safe"){const s=t.get("value"),n=this.googleFamilyFor(this.value),a=s?this.googleFamilyFor(s)??void 0:void 0;n&&s!==this.value?this.ensureFontLoaded(n,this.value,a):!n&&a&&p(this,a)}}get selectedGoogleFamily(){return this.fontSource==="web-safe"?null:this.googleFamilyFor(this.value)}googleFamilyFor(t){if(!t)return null;const o=this.fonts.filter(d);if(o.some(s=>s.family===t))return t;const i=L(t);return o.some(s=>s.family===i)?i:null}resolveSelection(){const t=this.value;if(!t||this.fonts.length===0)return{font:null,rowValue:t};const o=this.fontSource==="web-safe"?null:this.googleFamilyFor(t);if(o)return{font:this.fonts.find(l=>d(l)&&l.family===o)??null,rowValue:o};if(this.fontSource==="google")return{font:null,rowValue:t};const i=this.fonts.filter(a=>!d(a)),s=O(t,i);if(s)return{font:s,rowValue:s.stack};const n=E(t);return{font:n,rowValue:n?.stack??t}}async ensureFontLoaded(t,o,i){await v(t)&&this.loadedFonts.add(t),this.value===o&&(S(this,t),i&&i!==t&&p(this,i))}async initFonts(){const t=++this._initGeneration,o=this.fontSource,i=this.category?$(I,this.category):I;if(o==="web-safe"){this.fonts=i;return}const s=[...i.filter(b),...i.filter(f=>!b(f))];o==="all"&&(this.fonts=s);let n;try{n=await z()}catch(f){if(o!=="all")throw f;console.warn("esp-font-picker: the Google catalog is unavailable; listing device fonts only.",f);return}if(t!==this._initGeneration||this.fontSource!==o)return;const a=this.category?$(n,this.category):n;this.fonts=o==="all"?[...s,...a]:a;const l=this.value,c=this.googleFamilyFor(l);if(c){if(await v(c)){if(t!==this._initGeneration||this.fontSource!==o||this.value!==l){w(c);return}this.loadedFonts.add(c)}if(t!==this._initGeneration||this.fontSource!==o||this.value!==l)return;S(this,c)}}async handleItemsInView(t){if(this.fontSource==="web-safe")return;const o=++this._rangeGeneration,i=3,s=t.items??[],n=new Set,a=new Set(this.fonts.filter(d).map(r=>r.family)),l=Math.max(0,t.first),c=Math.min(t.last+i,s.length);for(let r=l;r<c;r++)a.has(s[r].value)&&n.add(s[r].value);for(const r of n)this.loadedFonts.has(r)||await v(r)&&this.loadedFonts.add(r);if(o!==this._rangeGeneration)return;const f=new Set(Array.from(document.getElementsByTagName("esp-font-picker")).map(r=>r.selectedGoogleFamily).filter(r=>!!r));for(const r of this.loadedFonts)f.has(r)||n.has(r)||(this.loadedFonts.delete(r),w(r))}render(){const t=this.resolveSelection(),o=this.fontSource==="all",s=[...t.font&&!this.fonts.includes(t.font)?[t.font]:[],...this.fonts].map(n=>({text:n.family,value:C(n),selected:t.font===n,styles:{fontFamily:K(n)},...o?{slotNodes:[X(this,d(n)?"google":"device")]}:{}}));return D`<esp-pick-one
2
2
  typeahead
3
3
  .pickerItems=${s}
4
4
  .value=${t.rowValue}
5
5
  .placeholder=${this.placeholder}
6
6
  @esp-picker-menu-range-changed=${this.handleItemsInViewEvent}
7
- @esp-value-changed=${async n=>{n.stopPropagation();const a=this.value;if(!n.detail){const r=a?this.googleFamilyFor(a):null;this.value="",r&&p(this,r),this.emitValueChanged(void 0);return}const l=this.fonts.find(r=>T(r)===n.detail.value)??(this.fontSource==="all"?I(n.detail.value)??void 0:void 0),c=n.detail.value;this.value=c,this.emitValueChanged(l);const u=a?this.googleFamilyFor(a):null;if(u&&u!==c&&p(this,u),l&&f(l)){if(await v(c)&&this.loadedFonts.add(c),this.value!==c)return;b(this,c)}}}
7
+ @esp-value-changed=${async n=>{n.stopPropagation();const a=this.value;if(!n.detail){const r=a?this.googleFamilyFor(a):null;this.value="",r&&p(this,r),this.emitValueChanged(void 0);return}const l=this.fonts.find(r=>C(r)===n.detail.value)??(this.fontSource==="all"?E(n.detail.value)??void 0:void 0),c=n.detail.value;this.value=c,this.emitValueChanged(l);const f=a?this.googleFamilyFor(a):null;if(f&&f!==c&&p(this,f),l&&d(l)){if(await v(c)&&this.loadedFonts.add(c),this.value!==c)return;S(this,c)}}}
8
8
  >
9
- </esp-pick-one>`}};h([L()],d.prototype,"fonts",void 0),h([F({attribute:"category",type:String})],d.prototype,"category",void 0),h([F({attribute:"font-source",type:String})],d.prototype,"fontSource",void 0),h([F({type:String})],d.prototype,"value",void 0),h([F({type:String})],d.prototype,"placeholder",void 0),d=h([A("esp-font-picker")],d);const lt=()=>{y=void 0,m=void 0;for(const e of document.head.querySelectorAll("style[data-font]"))e.remove();g.clear();for(const e of document.head.querySelectorAll(`link[${w}]`))e.remove()};export{ft as DEVICE_DEFAULT_WEIGHTS,d as EspalierFontPicker,dt as SYSTEM_TEXT_WEIGHTS,ht as WEB_SAFE_FONTS,Y as getFontPreviewFamily,z as getGoogleFonts,H as previewFontFamily,lt as resetFontCache};
9
+ </esp-pick-one>`}};u.clearsFormItemErrorOnChange=!0,h([A()],u.prototype,"fonts",void 0),h([y({attribute:"category",type:String})],u.prototype,"category",void 0),h([y({attribute:"font-source",type:String})],u.prototype,"fontSource",void 0),h([y({type:String})],u.prototype,"value",void 0),h([y({type:String})],u.prototype,"placeholder",void 0),u=h([x("esp-font-picker")],u);const lt=()=>{F=void 0,m=void 0;for(const e of document.head.querySelectorAll("style[data-font]"))e.remove();g.clear(),U("picker:")};export{ut as DEVICE_DEFAULT_WEIGHTS,u as EspalierFontPicker,dt as SYSTEM_TEXT_WEIGHTS,ht as WEB_SAFE_FONTS,K as getFontPreviewFamily,z as getGoogleFonts,H as previewFontFamily,lt as resetFontCache};
@@ -124,7 +124,7 @@ export type FooterColumns = "auto" | "1" | "2" | "3" | "4" | "5" | "6";
124
124
  * footer's content should also span the entire bar:
125
125
  *
126
126
  * ```html
127
- * <esp-page align="center" style="--esp-page-max-width: 36rem;">
127
+ * <esp-page align="center" style="--esp-page-main-max-width: 36rem;">
128
128
  * <main>Surface-aligned page content</main>
129
129
  * <esp-footer slot="footer" brand-text="Aligned Studio" columns="3">
130
130
  * <esp-footer-link-group heading="Explore">
@@ -37,6 +37,40 @@ export type EspalierFormField = {
37
37
  * </esp-box>
38
38
  * ```
39
39
  *
40
+ * ### Errors and assistive technology
41
+ *
42
+ * While an error shows — from `error`, the bound `errorPool`, or the
43
+ * control's own validation — the control's real focus target carries
44
+ * `aria-invalid="true"` and the error joins its accessible description,
45
+ * after the hint. A new or changed error is announced once through a polite
46
+ * status message; re-renders and clearing the error announce nothing. A
47
+ * warning joins the description the same way, without `aria-invalid` or an
48
+ * announcement. None of this changes how the error looks, and the required
49
+ * marker is unchanged.
50
+ *
51
+ * Choice controls (the radio-button and checkbox groups, `esp-checkbox`,
52
+ * `esp-switch`, and the pickers) clear an error from `error` or `errorPool`
53
+ * as soon as the visitor changes them, because the change answers the
54
+ * question the error asked. Text controls, the date picker, and the slider
55
+ * keep it until its owner changes it.
56
+ *
57
+ * ```html
58
+ * <esp-box class="demo-form">
59
+ * <esp-form-item
60
+ * label="Employer ID"
61
+ * hint="Use the format XX-XXXXXXX."
62
+ * error="Enter the ID in the format XX-XXXXXXX.">
63
+ * <esp-input value="12345"></esp-input>
64
+ * </esp-form-item>
65
+ * </esp-box>
66
+ * ```
67
+ *
68
+ * A screen reader on that field hears its name, "Employer ID", that it is
69
+ * invalid, and the description "Use the format XX-XXXXXXX. Enter the ID in
70
+ * the format XX-XXXXXXX." Plain native fields get the same treatment
71
+ * through IDREFs in their own tree; Espalier controls get it on the element
72
+ * inside their shadow root that takes focus.
73
+ *
40
74
  * @slot - The single form control the item wraps.
41
75
  * @slot hint - Rich hint content; replaces the `hint` attribute text when present.
42
76
  *
@@ -201,6 +235,7 @@ export declare class EspalierFormItem extends LitElement {
201
235
  get errorPool(): Array<ValidationError>;
202
236
  set errorPool(errors: Array<ValidationError>);
203
237
  protected firstUpdated(): void;
238
+ protected willUpdate(changed: PropertyValues): void;
204
239
  protected updated(changed: PropertyValues): void;
205
240
  connectedCallback(): void;
206
241
  disconnectedCallback(): void;