@pitchfork-ui/elements 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/control-label-C0eK8bPh.js +36 -0
- package/dist/cjs/control-label-C0eK8bPh.js.map +1 -0
- package/dist/cjs/index-CIskGKk1.js +4 -4
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/pf-checkbox.cjs.entry.js +3 -1
- package/dist/cjs/pf-checkbox.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-combobox.cjs.entry.js +4 -3
- package/dist/cjs/pf-combobox.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-date-picker.cjs.entry.js +3 -2
- package/dist/cjs/pf-date-picker.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-date-range-picker.cjs.entry.js +6 -5
- package/dist/cjs/pf-date-range-picker.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-header-navigation.cjs.entry.js +15 -3
- package/dist/cjs/pf-header-navigation.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-input.cjs.entry.js +3 -1
- package/dist/cjs/pf-input.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-modal.cjs.entry.js +89 -1
- package/dist/cjs/pf-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-multi-select.cjs.entry.js +4 -3
- package/dist/cjs/pf-multi-select.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-nav-item.cjs.entry.js +29 -4
- package/dist/cjs/pf-nav-item.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-number-input.cjs.entry.js +2 -1
- package/dist/cjs/pf-number-input.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-select.cjs.entry.js +4 -3
- package/dist/cjs/pf-select.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-sidebar-navigation.cjs.entry.js +11 -8
- package/dist/cjs/pf-sidebar-navigation.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-slider.cjs.entry.js +4 -2
- package/dist/cjs/pf-slider.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-switch.cjs.entry.js +3 -1
- package/dist/cjs/pf-switch.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-tag-input.cjs.entry.js +3 -2
- package/dist/cjs/pf-tag-input.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-textarea.cjs.entry.js +2 -1
- package/dist/cjs/pf-textarea.cjs.entry.js.map +1 -1
- package/dist/cjs/pf-time-picker.cjs.entry.js +3 -2
- package/dist/cjs/pf-time-picker.cjs.entry.js.map +1 -1
- package/dist/cjs/pitchfork.cjs.js +1 -1
- package/dist/collection/components/pf-accordion/pf-accordion.js +2 -2
- package/dist/collection/components/pf-alert/pf-alert.js +1 -1
- package/dist/collection/components/pf-avatar/pf-avatar.js +2 -2
- package/dist/collection/components/pf-badge/pf-badge.js +1 -1
- package/dist/collection/components/pf-badge-group/pf-badge-group.js +3 -3
- package/dist/collection/components/pf-button/pf-button.js +3 -3
- package/dist/collection/components/pf-checkbox/pf-checkbox.js +4 -1
- package/dist/collection/components/pf-checkbox/pf-checkbox.js.map +1 -1
- package/dist/collection/components/pf-combobox/pf-combobox.js +4 -3
- package/dist/collection/components/pf-combobox/pf-combobox.js.map +1 -1
- package/dist/collection/components/pf-content-divider/pf-content-divider.js +1 -1
- package/dist/collection/components/pf-credit-card/pf-credit-card.js +1 -1
- package/dist/collection/components/pf-date-picker/pf-date-picker.js +3 -2
- package/dist/collection/components/pf-date-picker/pf-date-picker.js.map +1 -1
- package/dist/collection/components/pf-date-range-picker/pf-date-range-picker.js +6 -5
- package/dist/collection/components/pf-date-range-picker/pf-date-range-picker.js.map +1 -1
- package/dist/collection/components/pf-empty-state/pf-empty-state.js +1 -1
- package/dist/collection/components/pf-header-navigation/pf-header-navigation.js +25 -4
- package/dist/collection/components/pf-header-navigation/pf-header-navigation.js.map +1 -1
- package/dist/collection/components/pf-inline-cta/pf-inline-cta.js +1 -1
- package/dist/collection/components/pf-input/pf-input.js +5 -2
- package/dist/collection/components/pf-input/pf-input.js.map +1 -1
- package/dist/collection/components/pf-kbd/pf-kbd.js +1 -1
- package/dist/collection/components/pf-line-chart/pf-line-chart.js +1 -1
- package/dist/collection/components/pf-loading-dots/pf-loading-dots.js +1 -1
- package/dist/collection/components/pf-metric-card/pf-metric-card.js +1 -1
- package/dist/collection/components/pf-modal/pf-modal.js +77 -6
- package/dist/collection/components/pf-modal/pf-modal.js.map +1 -1
- package/dist/collection/components/pf-multi-select/pf-multi-select.js +4 -3
- package/dist/collection/components/pf-multi-select/pf-multi-select.js.map +1 -1
- package/dist/collection/components/pf-nav-item/pf-nav-item.js +50 -5
- package/dist/collection/components/pf-nav-item/pf-nav-item.js.map +1 -1
- package/dist/collection/components/pf-notification/pf-notification.js +1 -1
- package/dist/collection/components/pf-number-input/pf-number-input.js +2 -1
- package/dist/collection/components/pf-number-input/pf-number-input.js.map +1 -1
- package/dist/collection/components/pf-progress-steps/pf-progress-steps.js +1 -1
- package/dist/collection/components/pf-radio-group/pf-radio-group.js +1 -1
- package/dist/collection/components/pf-rating-badge/pf-rating-badge.js +1 -1
- package/dist/collection/components/pf-scroll-area/pf-scroll-area.js +1 -1
- package/dist/collection/components/pf-section-header/pf-section-header.js +1 -1
- package/dist/collection/components/pf-select/pf-select.js +4 -3
- package/dist/collection/components/pf-select/pf-select.js.map +1 -1
- package/dist/collection/components/pf-sidebar-navigation/pf-sidebar-navigation.js +12 -9
- package/dist/collection/components/pf-sidebar-navigation/pf-sidebar-navigation.js.map +1 -1
- package/dist/collection/components/pf-slideout-menu/pf-slideout-menu.js +2 -2
- package/dist/collection/components/pf-slider/pf-slider.js +5 -2
- package/dist/collection/components/pf-slider/pf-slider.js.map +1 -1
- package/dist/collection/components/pf-switch/pf-switch.js +4 -1
- package/dist/collection/components/pf-switch/pf-switch.js.map +1 -1
- package/dist/collection/components/pf-tab/pf-tab.js +2 -2
- package/dist/collection/components/pf-table-cell/pf-table-cell.js +1 -1
- package/dist/collection/components/pf-tabs/pf-tabs.js +2 -2
- package/dist/collection/components/pf-tag/pf-tag.js +1 -1
- package/dist/collection/components/pf-tag-input/pf-tag-input.js +3 -2
- package/dist/collection/components/pf-tag-input/pf-tag-input.js.map +1 -1
- package/dist/collection/components/pf-textarea/pf-textarea.js +2 -1
- package/dist/collection/components/pf-textarea/pf-textarea.js.map +1 -1
- package/dist/collection/components/pf-time-picker/pf-time-picker.js +3 -2
- package/dist/collection/components/pf-time-picker/pf-time-picker.js.map +1 -1
- package/dist/collection/components/pf-timeline-item/pf-timeline-item.js +1 -1
- package/dist/collection/components/pf-toaster/pf-toaster.js +2 -2
- package/dist/collection/components/pf-toolbar/pf-toolbar.js +1 -1
- package/dist/collection/components/pf-toolbar-separator/pf-toolbar-separator.js +1 -1
- package/dist/collection/components/pf-utility-button/pf-utility-button.js +2 -2
- package/dist/collection/components/pf-video-player/pf-video-player.js +2 -2
- package/dist/collection/control-label.js +30 -0
- package/dist/collection/control-label.js.map +1 -0
- package/dist/components/p-Cy_kHPeC.js +2 -0
- package/dist/components/p-Cy_kHPeC.js.map +1 -0
- package/dist/components/pf-checkbox.js +1 -1
- package/dist/components/pf-checkbox.js.map +1 -1
- package/dist/components/pf-combobox.js +1 -1
- package/dist/components/pf-combobox.js.map +1 -1
- package/dist/components/pf-date-picker.js +1 -1
- package/dist/components/pf-date-picker.js.map +1 -1
- package/dist/components/pf-date-range-picker.js +1 -1
- package/dist/components/pf-date-range-picker.js.map +1 -1
- package/dist/components/pf-header-navigation.js +1 -1
- package/dist/components/pf-header-navigation.js.map +1 -1
- package/dist/components/pf-input.js +1 -1
- package/dist/components/pf-input.js.map +1 -1
- package/dist/components/pf-modal.js +1 -1
- package/dist/components/pf-modal.js.map +1 -1
- package/dist/components/pf-multi-select.js +1 -1
- package/dist/components/pf-multi-select.js.map +1 -1
- package/dist/components/pf-nav-item.js +1 -1
- package/dist/components/pf-nav-item.js.map +1 -1
- package/dist/components/pf-number-input.js +1 -1
- package/dist/components/pf-number-input.js.map +1 -1
- package/dist/components/pf-select.js +1 -1
- package/dist/components/pf-select.js.map +1 -1
- package/dist/components/pf-sidebar-navigation.js +1 -1
- package/dist/components/pf-sidebar-navigation.js.map +1 -1
- package/dist/components/pf-slider.js +1 -1
- package/dist/components/pf-slider.js.map +1 -1
- package/dist/components/pf-switch.js +1 -1
- package/dist/components/pf-switch.js.map +1 -1
- package/dist/components/pf-tag-input.js +1 -1
- package/dist/components/pf-tag-input.js.map +1 -1
- package/dist/components/pf-textarea.js +1 -1
- package/dist/components/pf-textarea.js.map +1 -1
- package/dist/components/pf-time-picker.js +1 -1
- package/dist/components/pf-time-picker.js.map +1 -1
- package/dist/docs.json +73 -52
- package/dist/elements.json +100 -10
- package/dist/esm/control-label-Cy_kHPeC.js +34 -0
- package/dist/esm/control-label-Cy_kHPeC.js.map +1 -0
- package/dist/esm/index-Bm6UxEit.js +4 -4
- package/dist/esm/loader.js +1 -1
- package/dist/esm/pf-checkbox.entry.js +4 -2
- package/dist/esm/pf-checkbox.entry.js.map +1 -1
- package/dist/esm/pf-combobox.entry.js +4 -3
- package/dist/esm/pf-combobox.entry.js.map +1 -1
- package/dist/esm/pf-date-picker.entry.js +3 -2
- package/dist/esm/pf-date-picker.entry.js.map +1 -1
- package/dist/esm/pf-date-range-picker.entry.js +6 -5
- package/dist/esm/pf-date-range-picker.entry.js.map +1 -1
- package/dist/esm/pf-header-navigation.entry.js +15 -3
- package/dist/esm/pf-header-navigation.entry.js.map +1 -1
- package/dist/esm/pf-input.entry.js +4 -2
- package/dist/esm/pf-input.entry.js.map +1 -1
- package/dist/esm/pf-modal.entry.js +89 -1
- package/dist/esm/pf-modal.entry.js.map +1 -1
- package/dist/esm/pf-multi-select.entry.js +4 -3
- package/dist/esm/pf-multi-select.entry.js.map +1 -1
- package/dist/esm/pf-nav-item.entry.js +30 -5
- package/dist/esm/pf-nav-item.entry.js.map +1 -1
- package/dist/esm/pf-number-input.entry.js +2 -1
- package/dist/esm/pf-number-input.entry.js.map +1 -1
- package/dist/esm/pf-select.entry.js +4 -3
- package/dist/esm/pf-select.entry.js.map +1 -1
- package/dist/esm/pf-sidebar-navigation.entry.js +11 -8
- package/dist/esm/pf-sidebar-navigation.entry.js.map +1 -1
- package/dist/esm/pf-slider.entry.js +5 -3
- package/dist/esm/pf-slider.entry.js.map +1 -1
- package/dist/esm/pf-switch.entry.js +4 -2
- package/dist/esm/pf-switch.entry.js.map +1 -1
- package/dist/esm/pf-tag-input.entry.js +3 -2
- package/dist/esm/pf-tag-input.entry.js.map +1 -1
- package/dist/esm/pf-textarea.entry.js +2 -1
- package/dist/esm/pf-textarea.entry.js.map +1 -1
- package/dist/esm/pf-time-picker.entry.js +3 -2
- package/dist/esm/pf-time-picker.entry.js.map +1 -1
- package/dist/esm/pitchfork.js +1 -1
- package/dist/pitchfork/p-01ed0d56.entry.js +2 -0
- package/dist/pitchfork/p-01ed0d56.entry.js.map +1 -0
- package/dist/pitchfork/p-02e28338.entry.js +2 -0
- package/dist/pitchfork/p-02e28338.entry.js.map +1 -0
- package/dist/pitchfork/p-19c0145c.entry.js +2 -0
- package/dist/pitchfork/p-19c0145c.entry.js.map +1 -0
- package/dist/pitchfork/p-22d8c69d.entry.js +2 -0
- package/dist/pitchfork/p-22d8c69d.entry.js.map +1 -0
- package/dist/pitchfork/p-2add2e98.entry.js +2 -0
- package/dist/pitchfork/p-2add2e98.entry.js.map +1 -0
- package/dist/pitchfork/p-45039de3.entry.js +2 -0
- package/dist/pitchfork/p-45039de3.entry.js.map +1 -0
- package/dist/pitchfork/p-4dfe7e8a.entry.js +2 -0
- package/dist/pitchfork/p-4dfe7e8a.entry.js.map +1 -0
- package/dist/pitchfork/p-51353d53.entry.js +2 -0
- package/dist/pitchfork/p-51353d53.entry.js.map +1 -0
- package/dist/pitchfork/p-5b98848c.entry.js +2 -0
- package/dist/pitchfork/{p-fd5a5ea1.entry.js.map → p-5b98848c.entry.js.map} +1 -1
- package/dist/pitchfork/p-7197ef71.entry.js +2 -0
- package/dist/pitchfork/p-7197ef71.entry.js.map +1 -0
- package/dist/pitchfork/p-Cy_kHPeC.js +2 -0
- package/dist/pitchfork/p-Cy_kHPeC.js.map +1 -0
- package/dist/pitchfork/p-ab6c09e7.entry.js +2 -0
- package/dist/pitchfork/p-ab6c09e7.entry.js.map +1 -0
- package/dist/pitchfork/p-d7ca4026.entry.js +2 -0
- package/dist/pitchfork/p-d7ca4026.entry.js.map +1 -0
- package/dist/pitchfork/p-dd48d94d.entry.js +2 -0
- package/dist/pitchfork/p-dd48d94d.entry.js.map +1 -0
- package/dist/pitchfork/p-ec8df806.entry.js +2 -0
- package/dist/pitchfork/p-ec8df806.entry.js.map +1 -0
- package/dist/pitchfork/p-f5df568f.entry.js +2 -0
- package/dist/pitchfork/p-f5df568f.entry.js.map +1 -0
- package/dist/pitchfork/p-f713c62d.entry.js +2 -0
- package/dist/pitchfork/p-f713c62d.entry.js.map +1 -0
- package/dist/pitchfork/p-fd802631.entry.js +2 -0
- package/dist/pitchfork/p-fd802631.entry.js.map +1 -0
- package/dist/pitchfork/pitchfork.esm.js +1 -1
- package/dist/types/components/pf-checkbox/pf-checkbox.d.ts +1 -0
- package/dist/types/components/pf-header-navigation/pf-header-navigation.d.ts +11 -2
- package/dist/types/components/pf-input/pf-input.d.ts +1 -0
- package/dist/types/components/pf-modal/pf-modal.d.ts +56 -3
- package/dist/types/components/pf-nav-item/pf-nav-item.d.ts +21 -1
- package/dist/types/components/pf-sidebar-navigation/pf-sidebar-navigation.d.ts +10 -7
- package/dist/types/components/pf-slider/pf-slider.d.ts +1 -0
- package/dist/types/components/pf-switch/pf-switch.d.ts +1 -0
- package/dist/types/components.d.ts +57 -18
- package/dist/types/control-label.d.ts +24 -0
- package/package.json +4 -4
- package/dist/pitchfork/p-1dbea97f.entry.js +0 -2
- package/dist/pitchfork/p-1dbea97f.entry.js.map +0 -1
- package/dist/pitchfork/p-23b1be9b.entry.js +0 -2
- package/dist/pitchfork/p-23b1be9b.entry.js.map +0 -1
- package/dist/pitchfork/p-33857f80.entry.js +0 -2
- package/dist/pitchfork/p-33857f80.entry.js.map +0 -1
- package/dist/pitchfork/p-47cabc33.entry.js +0 -2
- package/dist/pitchfork/p-47cabc33.entry.js.map +0 -1
- package/dist/pitchfork/p-48b2d3f7.entry.js +0 -2
- package/dist/pitchfork/p-48b2d3f7.entry.js.map +0 -1
- package/dist/pitchfork/p-5064d2dd.entry.js +0 -2
- package/dist/pitchfork/p-5064d2dd.entry.js.map +0 -1
- package/dist/pitchfork/p-52eef7eb.entry.js +0 -2
- package/dist/pitchfork/p-52eef7eb.entry.js.map +0 -1
- package/dist/pitchfork/p-845c5252.entry.js +0 -2
- package/dist/pitchfork/p-845c5252.entry.js.map +0 -1
- package/dist/pitchfork/p-a24bf2bd.entry.js +0 -2
- package/dist/pitchfork/p-a24bf2bd.entry.js.map +0 -1
- package/dist/pitchfork/p-a9b77dbb.entry.js +0 -2
- package/dist/pitchfork/p-a9b77dbb.entry.js.map +0 -1
- package/dist/pitchfork/p-c6bdd9cd.entry.js +0 -2
- package/dist/pitchfork/p-c6bdd9cd.entry.js.map +0 -1
- package/dist/pitchfork/p-d0d2070b.entry.js +0 -2
- package/dist/pitchfork/p-d0d2070b.entry.js.map +0 -1
- package/dist/pitchfork/p-d248b027.entry.js +0 -2
- package/dist/pitchfork/p-d248b027.entry.js.map +0 -1
- package/dist/pitchfork/p-d6425298.entry.js +0 -2
- package/dist/pitchfork/p-d6425298.entry.js.map +0 -1
- package/dist/pitchfork/p-d7eb6335.entry.js +0 -2
- package/dist/pitchfork/p-d7eb6335.entry.js.map +0 -1
- package/dist/pitchfork/p-e944f504.entry.js +0 -2
- package/dist/pitchfork/p-e944f504.entry.js.map +0 -1
- package/dist/pitchfork/p-fd5a5ea1.entry.js +0 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t,p as e,H as i,c as a,h as s,a as r}from"./index.js";import{c as o}from"./p-DfpCerXM.js";import{K as n}from"./p-g4FlTDZx.js";import{p as c,f as l,c as d,r as p,s as f}from"./p-BmcsJLdy.js";import{a as h}from"./p-Cr6IXrUk.js";import{
|
|
1
|
+
import{t,p as e,H as i,c as a,h as s,a as r}from"./index.js";import{c as o}from"./p-DfpCerXM.js";import{K as n}from"./p-g4FlTDZx.js";import{p as c,f as l,c as d,r as p,s as f}from"./p-BmcsJLdy.js";import{a as h}from"./p-Cr6IXrUk.js";import{c as u}from"./p-Cy_kHPeC.js";import{d as m}from"./p-CkFjPRTe.js";import{d as b}from"./p-Bb-s2aqK.js";const g=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-1)}.label{color:var(--pf-taginput-text);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-taginput-invalid-border);margin-inline-start:var(--space-1)}.control{align-items:center;background:var(--pf-taginput-bg);border:1px solid var(--pf-taginput-border);border-radius:var(--radius-md);display:flex;flex-wrap:wrap;gap:var(--space-1);padding:var(--space-1) var(--space-2)}.control:focus-within{border-color:var(--pf-taginput-focus-border);box-shadow:var(--pf-focus-ring)}.control--invalid{border-color:var(--pf-taginput-invalid-border)}.input{background:none;border:0;color:var(--pf-taginput-text);flex:1 1 6ch;font-family:inherit;font-size:var(--font-size-sm);min-width:6ch;outline:none;padding:var(--space-1)}.input::placeholder{color:var(--pf-taginput-placeholder)}.input:disabled{cursor:not-allowed}.description{color:var(--pf-taginput-placeholder);font-size:var(--font-size-xs);margin:0}.error{color:var(--pf-taginput-invalid-border);font-size:var(--font-size-xs);margin:0}`;const v=e(class t extends i{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.pfChange=a(this,"pfChange");this.internals=this.attachInternals()}get el(){return this}internals;name;value="";label;description;error;placeholder="Add a tag…";max;allowDuplicates=false;tagVariant="neutral";required=false;disabled=false;validate;pfChange;initialValue="";componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}syncFormState(){const t=this.tags();if(t.length===0||!this.name){this.internals.setFormValue(null)}else{const e=new FormData;for(const i of t)e.append(this.name,i);this.internals.setFormValue(e)}h(this.internals,t.length>0,this.required,this.error)}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue;const t=this.input;if(t)t.value=""}tags(){return c(this.value)}get input(){return this.el.shadowRoot?.querySelector('[part="input"]')??null}get options(){return{max:this.max,allowDuplicates:this.allowDuplicates,validate:this.validate}}commit(t){this.value=l(t);this.pfChange.emit({value:this.value,values:t})}addDraft(t){const e=d(this.tags(),t,this.options);const i=this.input;if(e.added){this.commit(e.tags);if(i)i.value="";return}if(e.refusal==="duplicate"&&i)i.value=""}remove(t){if(this.disabled)return;this.commit(p(this.tags(),t));this.input?.focus()}onKeyDown=t=>{if(this.disabled)return;const e=t.target;if(t.key===n.Enter||t.key===","){if(e.value.trim()){t.preventDefault();this.addDraft(e.value)}else if(t.key!==n.Enter){t.preventDefault()}return}if(t.key==="Backspace"&&e.value===""&&this.tags().length>0){t.preventDefault();this.remove(this.tags().length-1)}};onPaste=t=>{if(this.disabled)return;const e=f(t.clipboardData?.getData("text")??"");if(e.length===0)return;t.preventDefault();let i=this.tags();for(const t of e)i=d(i,t,this.options).tags;this.commit(i);const a=this.input;if(a)a.value=""};render(){const t=o(this.description&&"description",this.error&&"error");const e=this.tags();const i=this.max!==undefined&&e.length>=this.max;return s(r,{key:"fcd65f00fd3c83168d4aa60792eb082f2f34846b"},s("div",{key:"9d2660af1fd754840ec49eb1a8d4882e5fd1fc34",class:"field",part:"field"},this.label&&s("label",{key:"4bce4bfd9258b72f95dc038be8ad8a34f0684c0c",class:"label",part:"label",htmlFor:"input"},this.label,this.required&&s("span",{key:"9c82d014c88b2d5fd4cbd8be60c1a98834baa8a9",class:"required","aria-hidden":"true"},"*")),s("div",{key:"df92aae8117828f5bd11b7f09aaf64b4c19cefa5",class:{control:true,"control--invalid":Boolean(this.error)},part:"control"},e.map(((t,e)=>s("pf-tag",{key:t,part:"tag",variant:this.tagVariant,dismissible:!this.disabled,dismissLabel:`Remove ${t}`,onPfDismiss:()=>this.remove(e)},t))),s("input",{key:"e606fa3fd879dcef2e878e5311b601c4e46860c3",id:"input","aria-label":u(this.el,this.label),part:"input",class:"input",type:"text",autocomplete:"off",disabled:this.disabled||i,required:this.required&&e.length===0,placeholder:i?"":this.placeholder,"aria-invalid":this.error?"true":null,"aria-describedby":t,onKeyDown:this.onKeyDown,onPaste:this.onPaste,onBlur:t=>{const e=t.target;if(e.value.trim())this.addDraft(e.value)}})),this.description&&s("p",{key:"099590e7e19084d8aaaf595bb280ac61118c5a6e",class:"description",part:"description",id:"description"},this.description),this.error&&s("p",{key:"0ab0b8ebc4e94ce1eed0ea57747c3c0b21d7d174",class:"error",part:"error",id:"error"},this.error)))}static get formAssociated(){return true}static get watchers(){return{name:[{syncFormState:0}],value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}}static get style(){return g()}},[577,"pf-tag-input",{name:[513],value:[1537],label:[1],description:[1],error:[1],placeholder:[1],max:[2],allowDuplicates:[4,"allow-duplicates"],tagVariant:[1,"tag-variant"],required:[516],disabled:[516],validate:[16],checkValidity:[64],reportValidity:[64],getValidationMessage:[64]},undefined,{name:[{syncFormState:0}],value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}]);function y(){if(typeof customElements==="undefined"){return}const e=["pf-tag-input","pf-icon","pf-tag"];e.forEach((e=>{switch(e){case"pf-tag-input":if(!customElements.get(t(e))){customElements.define(t(e),v)}break;case"pf-icon":if(!customElements.get(t(e))){m()}break;case"pf-tag":if(!customElements.get(t(e))){b()}break}}))}y();const k=v;const x=y;export{k as PfTagInput,x as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=pf-tag-input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["pfTagInputCss","PfTagInput","__stencil_proxyCustomElement","HTMLElement","internals","name","value","label","description","error","placeholder","max","allowDuplicates","tagVariant","required","disabled","validate","pfChange","initialValue","componentWillLoad","this","syncFormState","tags","length","setFormValue","data","FormData","tag","append","applyControlValidity","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","field","input","parseValueList","el","shadowRoot","querySelector","options","commit","formatValueList","emit","values","addDraft","raw","result","addTag","added","refusal","remove","index","removeTagAt","focus","onKeyDown","event","target","key","Keys","Enter","trim","preventDefault","onPaste","pasted","splitPastedTags","clipboardData","getData","next","candidate","render","describedBy","composeDescribedBy","atMax","undefined","h","Host","class","part","htmlFor","control","Boolean","map","variant","dismissible","dismissLabel","onPfDismiss","id","type","autocomplete","onBlur"],"sources":["src/components/pf-tag-input/pf-tag-input.css?tag=pf-tag-input&encapsulation=shadow","src/components/pf-tag-input/pf-tag-input.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-taginput-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-taginput-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n/*\n * The chips and the draft field share one box that looks like a single input,\n * so clicking anywhere in it lands on the field.\n */\n.control {\n align-items: center;\n background: var(--pf-taginput-bg);\n border: 1px solid var(--pf-taginput-border);\n border-radius: var(--radius-md);\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-1);\n padding: var(--space-1) var(--space-2);\n}\n\n.control:focus-within {\n border-color: var(--pf-taginput-focus-border);\n box-shadow: var(--pf-focus-ring);\n}\n\n.control--invalid {\n border-color: var(--pf-taginput-invalid-border);\n}\n\n.input {\n background: none;\n border: 0;\n color: var(--pf-taginput-text);\n /* Grows to fill the row's remainder, but never forces the box wider. */\n flex: 1 1 6ch;\n font-family: inherit;\n font-size: var(--font-size-sm);\n min-width: 6ch;\n outline: none;\n padding: var(--space-1);\n}\n\n.input::placeholder {\n color: var(--pf-taginput-placeholder);\n}\n\n.input:disabled {\n cursor: not-allowed;\n}\n\n.description {\n color: var(--pf-taginput-placeholder);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-taginput-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n","import {\n addTag,\n composeDescribedBy,\n formatValueList,\n Keys,\n parseValueList,\n removeTagAt,\n splitPastedTags,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport type { PfTagVariant } from '../pf-tag/pf-tag';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated field that collects free-text tags.\n *\n * Unlike the other multi-value controls here the tags are not chosen from a\n * list, so there are no `pf-option` children — the chips are `pf-tag`\n * elements this component renders, and `pf-tag` already has the dismiss\n * button and the event for it.\n *\n * The rules are core's: trimming, the case-insensitive dedup (`React` and\n * `react` are one tag), the maximum, and `validate`. So is the paste split.\n * What stays here is what to do with the draft, which differs per refusal — a\n * duplicate clears it, because the tag asked for is already there, while\n * hitting the maximum leaves it so nothing is lost.\n *\n * Submits one entry per tag under one name, the same way `pf-multi-select`\n * does.\n *\n * @slot - nothing; the chips are rendered from `value`.\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part control - the box holding the chips and the draft input.\n * @part tag - each chip.\n * @part input - the draft input.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-tag-input',\n styleUrl: 'pf-tag-input.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfTagInput {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name, once per tag. Reflected. */\n @Prop({ reflect: true }) name?: string;\n\n /** The tags, comma-separated. Reflected, so HTML can set it. */\n @Prop({ mutable: true, reflect: true }) value = '';\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Add a tag…';\n\n /** Stop accepting tags once there are this many. */\n @Prop() max?: number;\n\n /** Accept the same tag twice. The comparison is case-insensitive. */\n @Prop() allowDuplicates = false;\n\n /**\n * Visual variant for the chips, passed through to `pf-tag`.\n *\n * The type is imported from `pf-tag` rather than restated, so the two\n * cannot drift apart — a second copy of the union would compile happily\n * while offering a variant `pf-tag` has never heard of.\n */\n @Prop() tagVariant: PfTagVariant = 'neutral';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /**\n * Refuse a candidate tag. A property rather than an attribute, because a\n * function cannot be written in HTML — the generated bindings set props as\n * properties, so a framework consumer passes it like any other.\n */\n @Prop() validate?: (tag: string) => boolean;\n\n /** Fires when the tags change, with both representations. */\n @Event() pfChange!: EventEmitter<{ value: string; values: string[] }>;\n\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n /** See pf-multi-select: the name is built into the FormData, so watch it. */\n @Watch('name')\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n const tags = this.tags();\n\n if (tags.length === 0 || !this.name) {\n this.internals.setFormValue(null);\n } else {\n const data = new FormData();\n for (const tag of tags) data.append(this.name, tag);\n this.internals.setFormValue(data);\n }\n\n applyControlValidity(this.internals, tags.length > 0, this.required, this.error);\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n const field = this.input;\n if (field) field.value = '';\n }\n\n private tags(): string[] {\n return parseValueList(this.value);\n }\n\n private get input() {\n return this.el.shadowRoot?.querySelector<HTMLInputElement>('[part=\"input\"]') ?? null;\n }\n\n private get options() {\n return { max: this.max, allowDuplicates: this.allowDuplicates, validate: this.validate };\n }\n\n private commit(tags: string[]) {\n this.value = formatValueList(tags);\n this.pfChange.emit({ value: this.value, values: tags });\n }\n\n /** Takes the draft as a tag, and decides what to do with the draft itself. */\n private addDraft(raw: string) {\n const result = addTag(this.tags(), raw, this.options);\n const field = this.input;\n\n if (result.added) {\n this.commit(result.tags);\n if (field) field.value = '';\n return;\n }\n\n // Only a duplicate consumes the draft; `max` leaves it so nothing is lost.\n if (result.refusal === 'duplicate' && field) field.value = '';\n }\n\n private remove(index: number) {\n if (this.disabled) return;\n this.commit(removeTagAt(this.tags(), index));\n this.input?.focus();\n }\n\n /**\n * Enter and comma commit; Backspace on an empty draft removes the last tag,\n * which is the gesture every tag field has.\n */\n private onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) return;\n const field = event.target as HTMLInputElement;\n\n if (event.key === Keys.Enter || event.key === ',') {\n // A bare comma with nothing typed is swallowed rather than committing an\n // empty tag; Enter is left alone so a form can still be submitted.\n if (field.value.trim()) {\n event.preventDefault();\n this.addDraft(field.value);\n } else if (event.key !== Keys.Enter) {\n event.preventDefault();\n }\n return;\n }\n\n if (event.key === 'Backspace' && field.value === '' && this.tags().length > 0) {\n event.preventDefault();\n this.remove(this.tags().length - 1);\n }\n };\n\n /**\n * A pasted list is folded, not added one at a time, so the maximum and the\n * dedup see each addition. The React component added them in a loop over\n * stale state and kept only the last — fixed there too, in the same change.\n */\n private onPaste = (event: ClipboardEvent) => {\n if (this.disabled) return;\n const pasted = splitPastedTags(event.clipboardData?.getData('text') ?? '');\n if (pasted.length === 0) return;\n\n event.preventDefault();\n let next = this.tags();\n for (const candidate of pasted) next = addTag(next, candidate, this.options).tags;\n\n this.commit(next);\n const field = this.input;\n if (field) field.value = '';\n };\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const tags = this.tags();\n const atMax = this.max !== undefined && tags.length >= this.max;\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div class={{ control: true, 'control--invalid': Boolean(this.error) }} part=\"control\">\n {tags.map((tag, index) => (\n <pf-tag\n key={tag}\n part=\"tag\"\n variant={this.tagVariant}\n dismissible={!this.disabled}\n dismissLabel={`Remove ${tag}`}\n onPfDismiss={() => this.remove(index)}\n >\n {tag}\n </pf-tag>\n ))}\n\n <input\n id=\"input\"\n part=\"input\"\n class=\"input\"\n type=\"text\"\n autocomplete=\"off\"\n disabled={this.disabled || atMax}\n required={this.required && tags.length === 0}\n placeholder={atMax ? '' : this.placeholder}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onKeyDown={this.onKeyDown}\n onPaste={this.onPaste}\n onBlur={(event) => {\n // Commit on blur, so a typed tag is not lost by clicking away.\n const field = event.target as HTMLInputElement;\n if (field.value.trim()) this.addDraft(field.value);\n }}\n />\n </div>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["pfTagInputCss","PfTagInput","__stencil_proxyCustomElement","HTMLElement","internals","name","value","label","description","error","placeholder","max","allowDuplicates","tagVariant","required","disabled","validate","pfChange","initialValue","componentWillLoad","this","syncFormState","tags","length","setFormValue","data","FormData","tag","append","applyControlValidity","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","field","input","parseValueList","el","shadowRoot","querySelector","options","commit","formatValueList","emit","values","addDraft","raw","result","addTag","added","refusal","remove","index","removeTagAt","focus","onKeyDown","event","target","key","Keys","Enter","trim","preventDefault","onPaste","pasted","splitPastedTags","clipboardData","getData","next","candidate","render","describedBy","composeDescribedBy","atMax","undefined","h","Host","class","part","htmlFor","control","Boolean","map","variant","dismissible","dismissLabel","onPfDismiss","id","controlAriaLabel","type","autocomplete","onBlur"],"sources":["src/components/pf-tag-input/pf-tag-input.css?tag=pf-tag-input&encapsulation=shadow","src/components/pf-tag-input/pf-tag-input.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-taginput-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-taginput-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n/*\n * The chips and the draft field share one box that looks like a single input,\n * so clicking anywhere in it lands on the field.\n */\n.control {\n align-items: center;\n background: var(--pf-taginput-bg);\n border: 1px solid var(--pf-taginput-border);\n border-radius: var(--radius-md);\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-1);\n padding: var(--space-1) var(--space-2);\n}\n\n.control:focus-within {\n border-color: var(--pf-taginput-focus-border);\n box-shadow: var(--pf-focus-ring);\n}\n\n.control--invalid {\n border-color: var(--pf-taginput-invalid-border);\n}\n\n.input {\n background: none;\n border: 0;\n color: var(--pf-taginput-text);\n /* Grows to fill the row's remainder, but never forces the box wider. */\n flex: 1 1 6ch;\n font-family: inherit;\n font-size: var(--font-size-sm);\n min-width: 6ch;\n outline: none;\n padding: var(--space-1);\n}\n\n.input::placeholder {\n color: var(--pf-taginput-placeholder);\n}\n\n.input:disabled {\n cursor: not-allowed;\n}\n\n.description {\n color: var(--pf-taginput-placeholder);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-taginput-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n","import {\n addTag,\n composeDescribedBy,\n formatValueList,\n Keys,\n parseValueList,\n removeTagAt,\n splitPastedTags,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport { controlAriaLabel } from '../../control-label';\nimport type { PfTagVariant } from '../pf-tag/pf-tag';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated field that collects free-text tags.\n *\n * Unlike the other multi-value controls here the tags are not chosen from a\n * list, so there are no `pf-option` children — the chips are `pf-tag`\n * elements this component renders, and `pf-tag` already has the dismiss\n * button and the event for it.\n *\n * The rules are core's: trimming, the case-insensitive dedup (`React` and\n * `react` are one tag), the maximum, and `validate`. So is the paste split.\n * What stays here is what to do with the draft, which differs per refusal — a\n * duplicate clears it, because the tag asked for is already there, while\n * hitting the maximum leaves it so nothing is lost.\n *\n * Submits one entry per tag under one name, the same way `pf-multi-select`\n * does.\n *\n * @slot - nothing; the chips are rendered from `value`.\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part control - the box holding the chips and the draft input.\n * @part tag - each chip.\n * @part input - the draft input.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-tag-input',\n styleUrl: 'pf-tag-input.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfTagInput {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name, once per tag. Reflected. */\n @Prop({ reflect: true }) name?: string;\n\n /** The tags, comma-separated. Reflected, so HTML can set it. */\n @Prop({ mutable: true, reflect: true }) value = '';\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Add a tag…';\n\n /** Stop accepting tags once there are this many. */\n @Prop() max?: number;\n\n /** Accept the same tag twice. The comparison is case-insensitive. */\n @Prop() allowDuplicates = false;\n\n /**\n * Visual variant for the chips, passed through to `pf-tag`.\n *\n * The type is imported from `pf-tag` rather than restated, so the two\n * cannot drift apart — a second copy of the union would compile happily\n * while offering a variant `pf-tag` has never heard of.\n */\n @Prop() tagVariant: PfTagVariant = 'neutral';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /**\n * Refuse a candidate tag. A property rather than an attribute, because a\n * function cannot be written in HTML — the generated bindings set props as\n * properties, so a framework consumer passes it like any other.\n */\n @Prop() validate?: (tag: string) => boolean;\n\n /** Fires when the tags change, with both representations. */\n @Event() pfChange!: EventEmitter<{ value: string; values: string[] }>;\n\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n /** See pf-multi-select: the name is built into the FormData, so watch it. */\n @Watch('name')\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n const tags = this.tags();\n\n if (tags.length === 0 || !this.name) {\n this.internals.setFormValue(null);\n } else {\n const data = new FormData();\n for (const tag of tags) data.append(this.name, tag);\n this.internals.setFormValue(data);\n }\n\n applyControlValidity(this.internals, tags.length > 0, this.required, this.error);\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n const field = this.input;\n if (field) field.value = '';\n }\n\n private tags(): string[] {\n return parseValueList(this.value);\n }\n\n private get input() {\n return this.el.shadowRoot?.querySelector<HTMLInputElement>('[part=\"input\"]') ?? null;\n }\n\n private get options() {\n return { max: this.max, allowDuplicates: this.allowDuplicates, validate: this.validate };\n }\n\n private commit(tags: string[]) {\n this.value = formatValueList(tags);\n this.pfChange.emit({ value: this.value, values: tags });\n }\n\n /** Takes the draft as a tag, and decides what to do with the draft itself. */\n private addDraft(raw: string) {\n const result = addTag(this.tags(), raw, this.options);\n const field = this.input;\n\n if (result.added) {\n this.commit(result.tags);\n if (field) field.value = '';\n return;\n }\n\n // Only a duplicate consumes the draft; `max` leaves it so nothing is lost.\n if (result.refusal === 'duplicate' && field) field.value = '';\n }\n\n private remove(index: number) {\n if (this.disabled) return;\n this.commit(removeTagAt(this.tags(), index));\n this.input?.focus();\n }\n\n /**\n * Enter and comma commit; Backspace on an empty draft removes the last tag,\n * which is the gesture every tag field has.\n */\n private onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) return;\n const field = event.target as HTMLInputElement;\n\n if (event.key === Keys.Enter || event.key === ',') {\n // A bare comma with nothing typed is swallowed rather than committing an\n // empty tag; Enter is left alone so a form can still be submitted.\n if (field.value.trim()) {\n event.preventDefault();\n this.addDraft(field.value);\n } else if (event.key !== Keys.Enter) {\n event.preventDefault();\n }\n return;\n }\n\n if (event.key === 'Backspace' && field.value === '' && this.tags().length > 0) {\n event.preventDefault();\n this.remove(this.tags().length - 1);\n }\n };\n\n /**\n * A pasted list is folded, not added one at a time, so the maximum and the\n * dedup see each addition. The React component added them in a loop over\n * stale state and kept only the last — fixed there too, in the same change.\n */\n private onPaste = (event: ClipboardEvent) => {\n if (this.disabled) return;\n const pasted = splitPastedTags(event.clipboardData?.getData('text') ?? '');\n if (pasted.length === 0) return;\n\n event.preventDefault();\n let next = this.tags();\n for (const candidate of pasted) next = addTag(next, candidate, this.options).tags;\n\n this.commit(next);\n const field = this.input;\n if (field) field.value = '';\n };\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const tags = this.tags();\n const atMax = this.max !== undefined && tags.length >= this.max;\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div class={{ control: true, 'control--invalid': Boolean(this.error) }} part=\"control\">\n {tags.map((tag, index) => (\n <pf-tag\n key={tag}\n part=\"tag\"\n variant={this.tagVariant}\n dismissible={!this.disabled}\n dismissLabel={`Remove ${tag}`}\n onPfDismiss={() => this.remove(index)}\n >\n {tag}\n </pf-tag>\n ))}\n\n <input\n id=\"input\"\n aria-label={controlAriaLabel(this.el, this.label)}\n part=\"input\"\n class=\"input\"\n type=\"text\"\n autocomplete=\"off\"\n disabled={this.disabled || atMax}\n required={this.required && tags.length === 0}\n placeholder={atMax ? '' : this.placeholder}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onKeyDown={this.onKeyDown}\n onPaste={this.onPaste}\n onBlur={(event) => {\n // Commit on blur, so a typed tag is not lost by clicking away.\n const field = event.target as HTMLInputElement;\n if (field.value.trim()) this.addDraft(field.value);\n }}\n />\n </div>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e,p as t,H as r,c as a,h as i,a as s}from"./index.js";import{c as o}from"./p-DfpCerXM.js";import{a as n}from"./p-Cr6IXrUk.js";const
|
|
1
|
+
import{t as e,p as t,H as r,c as a,h as i,a as s}from"./index.js";import{c as o}from"./p-DfpCerXM.js";import{a as n}from"./p-Cr6IXrUk.js";import{c as d}from"./p-Cy_kHPeC.js";const l=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-2)}.label{color:var(--pf-textarea-field-label, var(--pf-field-label));font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-field-required);margin-inline-start:var(--space-1)}.description{color:var(--pf-textarea-field-description, var(--pf-field-description));font-size:var(--font-size-sm);margin:0}.error{color:var(--pf-textarea-field-error, var(--pf-field-error));font-size:var(--font-size-sm);margin:0}.textarea{background:var(--pf-textarea-bg);border:1px solid var(--pf-textarea-border);border-radius:var(--radius-md);color:var(--pf-textarea-text);font:inherit;line-height:1.45;min-height:96px;padding:var(--space-2) var(--space-3);resize:vertical;width:100%}.textarea:focus{outline:none}.textarea:focus-visible{border-color:var(--pf-textarea-focus-border);box-shadow:var(--pf-textarea-focus-ring, var(--pf-focus-ring))}.textarea::placeholder{color:var(--pf-textarea-text-muted)}.textarea--invalid{border-color:var(--pf-textarea-invalid-border)}.textarea:disabled{cursor:not-allowed;opacity:0.6}`;const c=t(class e extends r{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.pfInput=a(this,"pfInput");this.pfChange=a(this,"pfChange");this.internals=this.attachInternals()}get el(){return this}internals;name;value="";rows=4;label;description;error;placeholder;required=false;disabled=false;readonly=false;pfInput;pfChange;initialValue="";componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}syncFormState(){this.internals.setFormValue(this.value??"");n(this.internals,Boolean(this.value),this.required,this.error)}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue}onInput=e=>{this.value=e.target.value;this.pfInput.emit({value:this.value})};onChange=()=>{this.pfChange.emit({value:this.value})};componentDidRender(){const e=this.el.shadowRoot?.querySelector("textarea");if(e&&e.value!==(this.value??"")){e.value=this.value??""}}render(){const e=o(this.description&&"description",this.error&&"error");return i(s,{key:"80a5c7f53163f8336121fb8f37b9523e6bed32ab"},i("div",{key:"fa50dbbd2d5f9320d21abf12ee83edce19aee843",class:"field",part:"field"},this.label&&i("label",{key:"f38ae2638abf5eb7f646dac050fa4a8888c03c31",class:"label",part:"label",htmlFor:"input"},this.label,this.required&&i("span",{key:"e7dbd26e3c88a3ab31eb0f2a578d07354c413efe",class:"required","aria-hidden":"true"},"*")),i("textarea",{key:"88c3b5be8039120c49e76a8099be97f2755f73b7",id:"input","aria-label":d(this.el,this.label),part:"textarea",class:{textarea:true,"textarea--invalid":Boolean(this.error)},name:this.name,rows:this.rows,placeholder:this.placeholder,required:this.required,disabled:this.disabled,readOnly:this.readonly,"aria-invalid":this.error?"true":null,"aria-describedby":e,onInput:this.onInput,onChange:this.onChange}),this.description&&i("p",{key:"4157ccc35337f16ca15b26e4442e260aa7f47019",class:"description",part:"description",id:"description"},this.description),this.error&&i("p",{key:"04a8583bdde73b69402113a4659e00a316b330fc",class:"error",part:"error",id:"error"},this.error)))}static get delegatesFocus(){return true}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}}static get style(){return l()}},[593,"pf-textarea",{name:[513],value:[1025],rows:[2],label:[1],description:[1],error:[1],placeholder:[1],required:[516],disabled:[516],readonly:[516],checkValidity:[64],reportValidity:[64],getValidationMessage:[64]},undefined,{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}]);function f(){if(typeof customElements==="undefined"){return}const t=["pf-textarea"];t.forEach((t=>{switch(t){case"pf-textarea":if(!customElements.get(e(t))){customElements.define(e(t),c)}break}}))}f();const h=c;const p=f;export{h as PfTextarea,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=pf-textarea.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["pfTextareaCss","PfTextarea","__stencil_proxyCustomElement","HTMLElement","internals","name","value","rows","label","description","error","placeholder","required","disabled","readonly","pfInput","pfChange","initialValue","componentWillLoad","this","syncFormState","setFormValue","applyControlValidity","Boolean","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","onInput","event","target","emit","onChange","componentDidRender","control","el","shadowRoot","querySelector","render","describedBy","composeDescribedBy","h","Host","key","class","part","htmlFor","id","textarea","readOnly"],"sources":["src/components/pf-textarea/pf-textarea.css?tag=pf-textarea&encapsulation=shadow","src/components/pf-textarea/pf-textarea.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-2);\n}\n\n.label {\n color: var(--pf-textarea-field-label, var(--pf-field-label));\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-field-required);\n margin-inline-start: var(--space-1);\n}\n\n.description {\n color: var(--pf-textarea-field-description, var(--pf-field-description));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.error {\n color: var(--pf-textarea-field-error, var(--pf-field-error));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.textarea {\n background: var(--pf-textarea-bg);\n border: 1px solid var(--pf-textarea-border);\n border-radius: var(--radius-md);\n color: var(--pf-textarea-text);\n font: inherit;\n line-height: 1.45;\n min-height: 96px;\n padding: var(--space-2) var(--space-3);\n resize: vertical;\n width: 100%;\n}\n\n.textarea:focus {\n outline: none;\n}\n\n.textarea:focus-visible {\n border-color: var(--pf-textarea-focus-border);\n box-shadow: var(--pf-textarea-focus-ring, var(--pf-focus-ring));\n}\n\n.textarea::placeholder {\n color: var(--pf-textarea-text-muted);\n}\n\n.textarea--invalid {\n border-color: var(--pf-textarea-invalid-border);\n}\n\n.textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n","import { composeDescribedBy } from '@pitchfork-ui/core';\nimport { applyControlValidity } from '../../form-validity';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated multi-line text control.\n *\n * Shares `pf-input`'s field anatomy and form wiring; the control is a\n * `<textarea>` rather than an `<input>`, so it takes `rows` and resizes.\n *\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part textarea - the native textarea.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-textarea',\n styleUrl: 'pf-textarea.css',\n formAssociated: true,\n shadow: { delegatesFocus: true },\n})\nexport class PfTextarea {\n @Element() el!: HTMLElement;\n\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Submitted under this name.\n *\n * Reflected, because a form-associated custom element takes its submission\n * name from the `name` *content attribute* -- not from this property. A\n * framework wrapper that sets properties rather than attributes (the\n * generated React bindings do) would otherwise leave the control nameless\n * and absent from the submission, with every other sign of working.\n */\n @Prop({ reflect: true }) name?: string;\n\n /** The control's value. */\n @Prop({ mutable: true }) value = '';\n\n /** Visible rows. Mirrors the native attribute. */\n @Prop() rows = 4;\n\n /** Visible label. Rendered in the same root as the input, so `for` works. */\n @Prop() label?: string;\n\n /** Hint text below the control. */\n @Prop() description?: string;\n\n /** Error message. Its presence is what marks the control invalid. */\n @Prop() error?: string;\n\n @Prop() placeholder?: string;\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n @Prop({ reflect: true }) readonly = false;\n\n /** Fires on every keystroke, like the native `input` event. */\n @Event() pfInput!: EventEmitter<{ value: string }>;\n\n /** Fires when the value is committed, like the native `change` event. */\n @Event() pfChange!: EventEmitter<{ value: string }>;\n\n /**\n * The value the control had when it was created, which is what a form reset\n * restores. Captured here because `value` has been overwritten by then.\n */\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value ?? '');\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n /**\n * Whether the control currently satisfies its constraints.\n *\n * A form-associated custom element does not inherit `checkValidity` from\n * anywhere -- the spec puts it on ElementInternals, so the element has to\n * forward it or consumers cannot ask.\n */\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n /** As `checkValidity`, but also shows the browser's validation message. */\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n /** The message explaining why the control is invalid, or an empty string. */\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /**\n * A reset restores the value the control started with, not an empty string —\n * verified against a native `<input value=\"initial\">`, which comes back to\n * \"initial\" rather than to \"\". Clearing it was a real defect: a\n * `<pf-textarea value=\"…\">` in a form lost its value on any reset.\n */\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n private onInput = (event: Event) => {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.pfInput.emit({ value: this.value });\n };\n\n private onChange = () => {\n this.pfChange.emit({ value: this.value });\n };\n\n /**\n * A textarea's value is its text content, not an attribute, so it cannot be\n * rendered as a JSX child without Stencil replacing that text node on every\n * keystroke. It is written through the DOM property instead, which is what\n * the browser itself does.\n *\n * Guarded on inequality: assigning the same string still moves the caret to\n * the end in some engines, which would make typing into the middle of a\n * paragraph jump the cursor away on every character.\n */\n componentDidRender() {\n const control = this.el.shadowRoot?.querySelector('textarea');\n if (control && control.value !== (this.value ?? '')) {\n control.value = this.value ?? '';\n }\n }\n\n render() {\n // IDs are scoped to this shadow root, so they can be literal -- the useId()\n // the React component needs has no counterpart here.\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <textarea\n id=\"input\"\n part=\"textarea\"\n class={{ textarea: true, 'textarea--invalid': Boolean(this.error) }}\n name={this.name}\n rows={this.rows}\n placeholder={this.placeholder}\n required={this.required}\n disabled={this.disabled}\n readOnly={this.readonly}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onInput={this.onInput}\n onChange={this.onChange}\n />\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"0IAAA,MAAMA,EAAgB,IAAM,smC,MCiCfC,EAAUC,EAAA,MAAAD,UAAAE,E,4MAGFC,UAWMC,KAGAC,MAAQ,GAGzBC,KAAO,EAGPC,MAGAC,YAGAC,MAEAC,YAEiBC,SAAW,MAEXC,SAAW,MAEXC,SAAW,MAG3BC,QAGAC,SAMDC,aAAe,GAEvB,iBAAAC,GACEC,KAAKF,aAAeE,KAAKb,OAAS,GAClCa,KAAKC,e,CAMP,aAAAA,GACED,KAAKf,UAAUiB,aAAaF,KAAKb,OAAS,IAC1CgB,EAAqBH,KAAKf,UAAWmB,QAAQJ,KAAKb,OAAQa,KAAKP,SAAUO,KAAKT,M,CAWhF,mBAAMc,GACJ,OAAOL,KAAKf,UAAUoB,e,CAKxB,oBAAMC,GACJ,OAAON,KAAKf,UAAUqB,gB,CAKxB,0BAAMC,GACJ,OAAOP,KAAKf,UAAUuB,iB,CASxB,iBAAAC,GACET,KAAKb,MAAQa,KAAKF,Y,CAGZY,QAAWC,IACjBX,KAAKb,MAASwB,EAAMC,OAA+BzB,MACnDa,KAAKJ,QAAQiB,KAAK,CAAE1B,MAAOa,KAAKb,OAAQ,EAGlC2B,SAAW,KACjBd,KAAKH,SAASgB,KAAK,CAAE1B,MAAOa,KAAKb,OAAQ,EAa3C,kBAAA4B,GACE,MAAMC,EAAUhB,KAAKiB,GAAGC,YAAYC,cAAc,YAClD,GAAIH,GAAWA,EAAQ7B,SAAWa,KAAKb,OAAS,IAAK,CACnD6B,EAAQ7B,MAAQa,KAAKb,OAAS,E,EAIlC,MAAAiC,GAGE,MAAMC,EAAcC,EAClBtB,KAAKV,aAAe,cACpBU,KAAKT,OAAS,SAGhB,OACEgC,EAACC,EAAI,CAAAC,IAAA,4CACHF,EAAA,OAAAE,IAAA,2CAAKC,MAAM,QAAQC,KAAK,SACrB3B,KAAKX,OACJkC,EAAA,SAAAE,IAAA,2CAAOC,MAAM,QAAQC,KAAK,QAAQC,QAAQ,SACvC5B,KAAKX,MACLW,KAAKP,UACJ8B,EAAA,QAAAE,IAAA,2CAAMC,MAAM,WAAU,cAAa,QAAM,MAM/CH,EAAA,YAAAE,IAAA,2CACEI,GAAG,QACHF,KAAK,WACLD,MAAO,CAAEI,SAAU,KAAM,oBAAqB1B,QAAQJ,KAAKT,QAC3DL,KAAMc,KAAKd,KACXE,KAAMY,KAAKZ,KACXI,YAAaQ,KAAKR,YAClBC,SAAUO,KAAKP,SACfC,SAAUM,KAAKN,SACfqC,SAAU/B,KAAKL,SAAQ,eACTK,KAAKT,MAAQ,OAAS,KAAI,mBACtB8B,EAClBX,QAASV,KAAKU,QACdI,SAAUd,KAAKc,WAEhBd,KAAKV,aACJiC,EAAA,KAAAE,IAAA,2CAAGC,MAAM,cAAcC,KAAK,cAAcE,GAAG,eAC1C7B,KAAKV,aAGTU,KAAKT,OACJgC,EAAA,KAAAE,IAAA,2CAAGC,MAAM,QAAQC,KAAK,QAAQE,GAAG,SAC9B7B,KAAKT,Q","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["pfTextareaCss","PfTextarea","__stencil_proxyCustomElement","HTMLElement","internals","name","value","rows","label","description","error","placeholder","required","disabled","readonly","pfInput","pfChange","initialValue","componentWillLoad","this","syncFormState","setFormValue","applyControlValidity","Boolean","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","onInput","event","target","emit","onChange","componentDidRender","control","el","shadowRoot","querySelector","render","describedBy","composeDescribedBy","h","Host","key","class","part","htmlFor","id","controlAriaLabel","textarea","readOnly"],"sources":["src/components/pf-textarea/pf-textarea.css?tag=pf-textarea&encapsulation=shadow","src/components/pf-textarea/pf-textarea.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-2);\n}\n\n.label {\n color: var(--pf-textarea-field-label, var(--pf-field-label));\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-field-required);\n margin-inline-start: var(--space-1);\n}\n\n.description {\n color: var(--pf-textarea-field-description, var(--pf-field-description));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.error {\n color: var(--pf-textarea-field-error, var(--pf-field-error));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.textarea {\n background: var(--pf-textarea-bg);\n border: 1px solid var(--pf-textarea-border);\n border-radius: var(--radius-md);\n color: var(--pf-textarea-text);\n font: inherit;\n line-height: 1.45;\n min-height: 96px;\n padding: var(--space-2) var(--space-3);\n resize: vertical;\n width: 100%;\n}\n\n.textarea:focus {\n outline: none;\n}\n\n.textarea:focus-visible {\n border-color: var(--pf-textarea-focus-border);\n box-shadow: var(--pf-textarea-focus-ring, var(--pf-focus-ring));\n}\n\n.textarea::placeholder {\n color: var(--pf-textarea-text-muted);\n}\n\n.textarea--invalid {\n border-color: var(--pf-textarea-invalid-border);\n}\n\n.textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n","import { composeDescribedBy } from '@pitchfork-ui/core';\nimport { applyControlValidity } from '../../form-validity';\nimport { controlAriaLabel } from '../../control-label';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated multi-line text control.\n *\n * Shares `pf-input`'s field anatomy and form wiring; the control is a\n * `<textarea>` rather than an `<input>`, so it takes `rows` and resizes.\n *\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part textarea - the native textarea.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-textarea',\n styleUrl: 'pf-textarea.css',\n formAssociated: true,\n shadow: { delegatesFocus: true },\n})\nexport class PfTextarea {\n @Element() el!: HTMLElement;\n\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Submitted under this name.\n *\n * Reflected, because a form-associated custom element takes its submission\n * name from the `name` *content attribute* -- not from this property. A\n * framework wrapper that sets properties rather than attributes (the\n * generated React bindings do) would otherwise leave the control nameless\n * and absent from the submission, with every other sign of working.\n */\n @Prop({ reflect: true }) name?: string;\n\n /** The control's value. */\n @Prop({ mutable: true }) value = '';\n\n /** Visible rows. Mirrors the native attribute. */\n @Prop() rows = 4;\n\n /** Visible label. Rendered in the same root as the input, so `for` works. */\n @Prop() label?: string;\n\n /** Hint text below the control. */\n @Prop() description?: string;\n\n /** Error message. Its presence is what marks the control invalid. */\n @Prop() error?: string;\n\n @Prop() placeholder?: string;\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n @Prop({ reflect: true }) readonly = false;\n\n /** Fires on every keystroke, like the native `input` event. */\n @Event() pfInput!: EventEmitter<{ value: string }>;\n\n /** Fires when the value is committed, like the native `change` event. */\n @Event() pfChange!: EventEmitter<{ value: string }>;\n\n /**\n * The value the control had when it was created, which is what a form reset\n * restores. Captured here because `value` has been overwritten by then.\n */\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value ?? '');\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n /**\n * Whether the control currently satisfies its constraints.\n *\n * A form-associated custom element does not inherit `checkValidity` from\n * anywhere -- the spec puts it on ElementInternals, so the element has to\n * forward it or consumers cannot ask.\n */\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n /** As `checkValidity`, but also shows the browser's validation message. */\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n /** The message explaining why the control is invalid, or an empty string. */\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /**\n * A reset restores the value the control started with, not an empty string —\n * verified against a native `<input value=\"initial\">`, which comes back to\n * \"initial\" rather than to \"\". Clearing it was a real defect: a\n * `<pf-textarea value=\"…\">` in a form lost its value on any reset.\n */\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n private onInput = (event: Event) => {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.pfInput.emit({ value: this.value });\n };\n\n private onChange = () => {\n this.pfChange.emit({ value: this.value });\n };\n\n /**\n * A textarea's value is its text content, not an attribute, so it cannot be\n * rendered as a JSX child without Stencil replacing that text node on every\n * keystroke. It is written through the DOM property instead, which is what\n * the browser itself does.\n *\n * Guarded on inequality: assigning the same string still moves the caret to\n * the end in some engines, which would make typing into the middle of a\n * paragraph jump the cursor away on every character.\n */\n componentDidRender() {\n const control = this.el.shadowRoot?.querySelector('textarea');\n if (control && control.value !== (this.value ?? '')) {\n control.value = this.value ?? '';\n }\n }\n\n render() {\n // IDs are scoped to this shadow root, so they can be literal -- the useId()\n // the React component needs has no counterpart here.\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <textarea\n id=\"input\"\n aria-label={controlAriaLabel(this.el, this.label)}\n part=\"textarea\"\n class={{ textarea: true, 'textarea--invalid': Boolean(this.error) }}\n name={this.name}\n rows={this.rows}\n placeholder={this.placeholder}\n required={this.required}\n disabled={this.disabled}\n readOnly={this.readonly}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onInput={this.onInput}\n onChange={this.onChange}\n />\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"8KAAA,MAAMA,EAAgB,IAAM,smC,MCkCfC,EAAUC,EAAA,MAAAD,UAAAE,E,4MAGFC,UAWMC,KAGAC,MAAQ,GAGzBC,KAAO,EAGPC,MAGAC,YAGAC,MAEAC,YAEiBC,SAAW,MAEXC,SAAW,MAEXC,SAAW,MAG3BC,QAGAC,SAMDC,aAAe,GAEvB,iBAAAC,GACEC,KAAKF,aAAeE,KAAKb,OAAS,GAClCa,KAAKC,e,CAMP,aAAAA,GACED,KAAKf,UAAUiB,aAAaF,KAAKb,OAAS,IAC1CgB,EAAqBH,KAAKf,UAAWmB,QAAQJ,KAAKb,OAAQa,KAAKP,SAAUO,KAAKT,M,CAWhF,mBAAMc,GACJ,OAAOL,KAAKf,UAAUoB,e,CAKxB,oBAAMC,GACJ,OAAON,KAAKf,UAAUqB,gB,CAKxB,0BAAMC,GACJ,OAAOP,KAAKf,UAAUuB,iB,CASxB,iBAAAC,GACET,KAAKb,MAAQa,KAAKF,Y,CAGZY,QAAWC,IACjBX,KAAKb,MAASwB,EAAMC,OAA+BzB,MACnDa,KAAKJ,QAAQiB,KAAK,CAAE1B,MAAOa,KAAKb,OAAQ,EAGlC2B,SAAW,KACjBd,KAAKH,SAASgB,KAAK,CAAE1B,MAAOa,KAAKb,OAAQ,EAa3C,kBAAA4B,GACE,MAAMC,EAAUhB,KAAKiB,GAAGC,YAAYC,cAAc,YAClD,GAAIH,GAAWA,EAAQ7B,SAAWa,KAAKb,OAAS,IAAK,CACnD6B,EAAQ7B,MAAQa,KAAKb,OAAS,E,EAIlC,MAAAiC,GAGE,MAAMC,EAAcC,EAClBtB,KAAKV,aAAe,cACpBU,KAAKT,OAAS,SAGhB,OACEgC,EAACC,EAAI,CAAAC,IAAA,4CACHF,EAAA,OAAAE,IAAA,2CAAKC,MAAM,QAAQC,KAAK,SACrB3B,KAAKX,OACJkC,EAAA,SAAAE,IAAA,2CAAOC,MAAM,QAAQC,KAAK,QAAQC,QAAQ,SACvC5B,KAAKX,MACLW,KAAKP,UACJ8B,EAAA,QAAAE,IAAA,2CAAMC,MAAM,WAAU,cAAa,QAAM,MAM/CH,EAAA,YAAAE,IAAA,2CACEI,GAAG,QAAO,aACEC,EAAiB9B,KAAKiB,GAAIjB,KAAKX,OAC3CsC,KAAK,WACLD,MAAO,CAAEK,SAAU,KAAM,oBAAqB3B,QAAQJ,KAAKT,QAC3DL,KAAMc,KAAKd,KACXE,KAAMY,KAAKZ,KACXI,YAAaQ,KAAKR,YAClBC,SAAUO,KAAKP,SACfC,SAAUM,KAAKN,SACfsC,SAAUhC,KAAKL,SAAQ,eACTK,KAAKT,MAAQ,OAAS,KAAI,mBACtB8B,EAClBX,QAASV,KAAKU,QACdI,SAAUd,KAAKc,WAEhBd,KAAKV,aACJiC,EAAA,KAAAE,IAAA,2CAAGC,MAAM,cAAcC,KAAK,cAAcE,GAAG,eAC1C7B,KAAKV,aAGTU,KAAKT,OACJgC,EAAA,KAAAE,IAAA,2CAAGC,MAAM,QAAQC,KAAK,QAAQE,GAAG,SAC9B7B,KAAKT,Q","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e,p as t,H as i,c as r,h as n,a as o}from"./index.js";import{o as s,p as a}from"./p-CC7AyfOt.js";import{c}from"./p-DfpCerXM.js";import{K as l}from"./p-g4FlTDZx.js";import{a as p}from"./p-Cr6IXrUk.js";import{d as u}from"./p-CkFjPRTe.js";var
|
|
1
|
+
import{t as e,p as t,H as i,c as r,h as n,a as o}from"./index.js";import{o as s,p as a}from"./p-CC7AyfOt.js";import{c}from"./p-DfpCerXM.js";import{K as l}from"./p-g4FlTDZx.js";import{a as p}from"./p-Cr6IXrUk.js";import{c as d}from"./p-Cy_kHPeC.js";import{d as u}from"./p-CkFjPRTe.js";var h=e=>String(e).padStart(2,"0");function f(e){const t=/^(\d{1,2}):(\d{2})$/.exec((e??"").trim());if(!t)return{hour:null,minute:null};const i=Number(t[1]);const r=Number(t[2]);if(i>23||r>59)return{hour:null,minute:null};return{hour:i,minute:r}}function m(e){if(e.hour===null||e.minute===null)return"";return`${h(e.hour)}:${h(e.minute)}`}function b(e,t){if(e.hour===null||e.minute===null)return"";if(t===24)return`${h(e.hour)}:${h(e.minute)}`;return`${v(e.hour)}:${h(e.minute)} ${g(e.hour)}`}function g(e){return e<12?"AM":"PM"}function v(e){const t=e%12;return t===0?12:t}function y(e,t){const i=e%12;return t==="PM"?i+12:i}function k(e,t=1){const i=Math.max(1,Math.floor(t));const r=Math.ceil(e/i);return Array.from({length:r},((e,t)=>t*i))}function x(e){return e===24?k(24):k(12).map((e=>e+1))}const w=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-1)}.label{color:var(--pf-timepicker-text);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-timepicker-invalid-border);margin-inline-start:var(--space-1)}.trigger{align-items:center;background:var(--pf-timepicker-bg);border:1px solid var(--pf-timepicker-border);border-radius:var(--radius-md);color:var(--pf-timepicker-text);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-size-sm);gap:var(--space-2);justify-content:space-between;padding:var(--space-2) var(--space-3);text-align:start;width:100%}.trigger:focus-visible{border-color:var(--pf-timepicker-focus-border);box-shadow:var(--pf-focus-ring);outline:none}.trigger:disabled{cursor:not-allowed;opacity:0.6}.trigger--invalid{border-color:var(--pf-timepicker-invalid-border)}.value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.value--placeholder{color:var(--pf-timepicker-placeholder)}.description{color:var(--pf-timepicker-text-muted);font-size:var(--font-size-xs);margin:0}.error{color:var(--pf-timepicker-invalid-border);font-size:var(--font-size-xs);margin:0}.panel{inset:auto;margin:0;background:var(--pf-timepicker-menu-bg);border:1px solid var(--pf-timepicker-menu-border);border-radius:var(--radius-md);box-shadow:var(--pf-elevation-popover-shadow);display:flex;gap:var(--space-1);padding:var(--space-1)}.panel:popover-open{animation:pf-time-picker-in var(--pf-transition-enter)}@keyframes pf-time-picker-in{from{opacity:0;transform:translateY(-4px)}}@media (prefers-reduced-motion: reduce){.panel:popover-open{animation:none}}.column{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;scrollbar-width:thin}.column:focus-visible{outline:none}.option{background:none;border:0;border-radius:var(--radius-sm);color:var(--pf-timepicker-text);cursor:pointer;font-family:inherit;font-size:var(--font-size-sm);font-variant-numeric:tabular-nums;padding:var(--space-1) var(--space-3);text-align:center}.option:hover{background:var(--pf-timepicker-option-hover-bg)}.option:focus-visible{box-shadow:var(--pf-focus-ring);outline:none}.option--selected{background:var(--pf-timepicker-option-active-bg);color:var(--pf-timepicker-option-active-text)}`;const C=t(class e extends i{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.pfChange=r(this,"pfChange");this.pfOpenChange=r(this,"pfOpenChange");this.internals=this.attachInternals()}get el(){return this}internals;name;value="";open=false;hourCycle=24;minuteStep=1;label;description;error;placeholder="Select time";required=false;disabled=false;pfChange;pfOpenChange;initialValue="";stopObserving;componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}componentDidRender(){if(this.open)this.scrollSelectedIntoView()}disconnectedCallback(){this.stopObserving?.()}syncFormState(){this.internals.setFormValue(this.value||null);p(this.internals,Boolean(this.value),this.required,this.error)}syncOpen(e,t){if(e)this.showPanel();else this.hidePanel();if(e!==t)this.pfOpenChange.emit({open:e})}async show(){if(!this.disabled)this.open=true}async hide(){this.open=false}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue}get cycle(){return Number(this.hourCycle)===12?12:24}get panel(){return this.el.shadowRoot?.querySelector('[part="panel"]')??null}get trigger(){return this.el.shadowRoot?.querySelector('[part="trigger"]')??null}get parts(){return f(this.value)}showPanel(){const e=this.panel;if(this.disabled||!e||e.matches(":popover-open"))return;e.showPopover();this.stopObserving?.();this.stopObserving=s({getAnchor:()=>this.trigger,getFloating:()=>e,align:"start",matchAnchorWidth:false,flip:true,onChange:({left:t,top:i})=>a(e,t,i)});this.scrollSelectedIntoView();e.querySelector('[data-selected="true"]')?.focus()}hidePanel(){this.stopObserving?.();this.stopObserving=undefined;const e=this.panel;if(e?.matches(":popover-open"))e.hidePopover()}scrollSelectedIntoView(){for(const e of Array.from(this.panel?.querySelectorAll('[data-selected="true"]')??[])){if(typeof e.scrollIntoView==="function"){e.scrollIntoView({block:"center"})}}}onToggle=e=>{const t=e.newState==="open";if(this.open!==t)this.open=t;if(!t)this.trigger?.focus()};commit(e){const t=m(e);if(!t||t===this.value)return;this.value=t;this.pfChange.emit({value:t})}selectHour(e){const t=this.cycle===24?e:y(e,this.selectedMeridiem()??"AM");this.commit({hour:t,minute:this.parts.minute??0})}selectMinute(e){this.commit({hour:this.parts.hour??0,minute:e})}selectMeridiem(e){const{hour:t,minute:i}=this.parts;this.commit({hour:y(v(t??0),e),minute:i??0})}selectedMeridiem(){const{hour:e}=this.parts;return e===null?null:g(e)}onColumnKeyDown=e=>{if(e.key!==l.ArrowDown&&e.key!==l.ArrowUp)return;const t=e.currentTarget;const i=Array.from(t.querySelectorAll("button"));const r=i.indexOf(this.el.shadowRoot?.activeElement);if(r===-1)return;e.preventDefault();const n=e.key===l.ArrowDown?r+1:r-1;i[Math.min(Math.max(n,0),i.length-1)]?.focus()};renderColumn(e,t){return n("div",{class:"column",part:"column",role:"listbox","aria-label":e,tabindex:-1,onKeyDown:this.onColumnKeyDown},t.map((e=>n("button",{key:e.key,type:"button",part:"option",class:{option:true,"option--selected":e.selected},role:"option","aria-selected":e.selected?"true":"false","data-selected":e.selected?"true":"false",onClick:e.onSelect},e.label))))}render(){const e=c(this.description&&"description",this.error&&"error");const{hour:t,minute:i}=this.parts;const r=b(this.parts,this.cycle);const s=t===null?null:this.cycle===24?t:v(t);const a=this.selectedMeridiem();return n(o,{key:"c26f419605ca45c6180180ebce68bec77fe99676"},n("div",{key:"bf975b4f6ef429212d28be61448df62d54322e90",class:"field",part:"field"},this.label&&n("label",{key:"80b0160476b03992991886c1e0c2f06dd1195931",class:"label",part:"label",htmlFor:"trigger"},this.label,this.required&&n("span",{key:"5d52003ddf874d68adcaad65012197a5262fe64c",class:"required","aria-hidden":"true"},"*")),n("button",{key:"842fb04fce12e559fc9f7ef541baa60c118c9f9d",id:"trigger","aria-label":d(this.el,this.label),part:"trigger",class:{trigger:true,"trigger--invalid":Boolean(this.error)},type:"button",disabled:this.disabled,"aria-haspopup":"dialog","aria-expanded":this.open?"true":"false","aria-controls":"panel","aria-invalid":this.error?"true":null,"aria-required":this.required?"true":null,"aria-describedby":e,onClick:()=>{if(!this.disabled)this.open=!this.open}},n("span",{key:"2eefe098a48de552dd6c869b4696ce09960abf5e",class:{value:true,"value--placeholder":!r}},r||this.placeholder),n("pf-icon",{key:"881c2760be97dacb6ffd2df9e46f1c66252ff513",name:"clock"})),this.description&&n("p",{key:"c09274524b28fa88034eba28138d0559cc0b60cf",class:"description",part:"description",id:"description"},this.description),this.error&&n("p",{key:"9a7ac33fc684b137684b6925cf44cb2d26c05aa0",class:"error",part:"error",id:"error"},this.error)),n("div",{key:"1c79f18f2078b4d2ae8c2832f8e49f3a33723354",id:"panel",part:"panel",class:"panel",popover:"auto",role:"dialog","aria-label":"Choose a time",onToggle:this.onToggle},this.renderColumn("Hour",x(this.cycle).map((e=>({key:`h-${e}`,label:h(e),selected:s===e,onSelect:()=>this.selectHour(e)})))),this.renderColumn("Minute",k(60,this.minuteStep).map((e=>({key:`m-${e}`,label:h(e),selected:i===e,onSelect:()=>this.selectMinute(e)})))),this.cycle===12&&this.renderColumn("AM or PM",["AM","PM"].map((e=>({key:e,label:e,selected:a===e,onSelect:()=>this.selectMeridiem(e)}))))))}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}],open:[{syncOpen:0}]}}static get style(){return w()}},[577,"pf-time-picker",{name:[513],value:[1025],open:[1540],hourCycle:[2,"hour-cycle"],minuteStep:[2,"minute-step"],label:[1],description:[1],error:[1],placeholder:[1],required:[516],disabled:[516],show:[64],hide:[64],checkValidity:[64],reportValidity:[64],getValidationMessage:[64]},undefined,{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}],open:[{syncOpen:0}]}]);function M(){if(typeof customElements==="undefined"){return}const t=["pf-time-picker","pf-icon"];t.forEach((t=>{switch(t){case"pf-time-picker":if(!customElements.get(e(t))){customElements.define(e(t),C)}break;case"pf-icon":if(!customElements.get(e(t))){u()}break}}))}M();const S=C;const A=M;export{S as PfTimePicker,A as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=pf-time-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["padTimePart","value","String","padStart","parseTimeValue","match","exec","trim","hour","minute","Number","formatTimeValue","parts","formatTimeDisplay","hourCycle","toHour12","meridiemOf","hour24","face","toHour24","hour12","meridiem","base","timeRange","length","step","safeStep","Math","max","floor","count","ceil","Array","from","_","index","hourOptions","map","pfTimePickerCss","PfTimePicker","__stencil_proxyCustomElement","HTMLElement","internals","name","open","minuteStep","label","description","error","placeholder","required","disabled","pfChange","pfOpenChange","initialValue","stopObserving","componentWillLoad","this","syncFormState","componentDidRender","scrollSelectedIntoView","disconnectedCallback","setFormValue","applyControlValidity","Boolean","syncOpen","next","previous","showPanel","hidePanel","emit","show","hide","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","cycle","panel","el","shadowRoot","querySelector","trigger","matches","showPopover","observeAnchoredPosition","getAnchor","getFloating","align","matchAnchorWidth","flip","onChange","left","top","placePopover","focus","undefined","hidePopover","option","querySelectorAll","scrollIntoView","block","onToggle","event","nowOpen","newState","commit","selectHour","selectedMeridiem","selectMinute","selectMeridiem","onColumnKeyDown","key","Keys","ArrowDown","ArrowUp","column","currentTarget","options","indexOf","activeElement","preventDefault","min","renderColumn","h","class","part","role","tabindex","onKeyDown","type","selected","onClick","onSelect","render","describedBy","composeDescribedBy","display","shownHour","Host","htmlFor","id","popover"],"sources":["../core/dist/time.js","src/components/pf-time-picker/pf-time-picker.css?tag=pf-time-picker&encapsulation=shadow","src/components/pf-time-picker/pf-time-picker.tsx"],"sourcesContent":["//#region src/time.ts\n/**\n* Two digits, which both layers need for the column labels as well as for the\n* canonical value — so it is exported rather than private.\n*/\nvar padTimePart = (value) => String(value).padStart(2, \"0\");\n/**\n* Parses `HH:mm` (or `H:mm`) into hour and minute, or nulls.\n*\n* Out-of-range parts are rejected rather than wrapped: `25:00` is not 1am, it\n* is a mistake, and silently turning it into one hides the mistake.\n*/\nfunction parseTimeValue(value) {\n\tconst match = /^(\\d{1,2}):(\\d{2})$/.exec((value ?? \"\").trim());\n\tif (!match) return {\n\t\thour: null,\n\t\tminute: null\n\t};\n\tconst hour = Number(match[1]);\n\tconst minute = Number(match[2]);\n\tif (hour > 23 || minute > 59) return {\n\t\thour: null,\n\t\tminute: null\n\t};\n\treturn {\n\t\thour,\n\t\tminute\n\t};\n}\n/** The canonical 24-hour `HH:mm`, or `''` when either part is missing. */\nfunction formatTimeValue(parts) {\n\tif (parts.hour === null || parts.minute === null) return \"\";\n\treturn `${padTimePart(parts.hour)}:${padTimePart(parts.minute)}`;\n}\n/** What the trigger shows: `14:30`, or `2:30 PM` on a 12-hour cycle. */\nfunction formatTimeDisplay(parts, hourCycle) {\n\tif (parts.hour === null || parts.minute === null) return \"\";\n\tif (hourCycle === 24) return `${padTimePart(parts.hour)}:${padTimePart(parts.minute)}`;\n\treturn `${toHour12(parts.hour)}:${padTimePart(parts.minute)} ${meridiemOf(parts.hour)}`;\n}\n/** Which half of the day an hour falls in. */\nfunction meridiemOf(hour24) {\n\treturn hour24 < 12 ? \"AM\" : \"PM\";\n}\n/**\n* The 12-hour face of a 24-hour hour: midnight and midday both read as 12,\n* not 0, which is the one case `hour % 12` gets wrong.\n*/\nfunction toHour12(hour24) {\n\tconst face = hour24 % 12;\n\treturn face === 0 ? 12 : face;\n}\n/** The 24-hour hour for a clock face plus a meridiem. 12 AM is 0, 12 PM is 12. */\nfunction toHour24(hour12, meridiem) {\n\tconst base = hour12 % 12;\n\treturn meridiem === \"PM\" ? base + 12 : base;\n}\n/**\n* The options a column offers: `0, step, 2*step, …` below `length`.\n*\n* A step that does not divide the range leaves a short last stride rather\n* than overshooting — `timeRange(60, 25)` is `[0, 25, 50]`, and 50 is a real\n* minute where 75 is not.\n*/\nfunction timeRange(length, step = 1) {\n\tconst safeStep = Math.max(1, Math.floor(step));\n\tconst count = Math.ceil(length / safeStep);\n\treturn Array.from({ length: count }, (_, index) => index * safeStep);\n}\n/** The hours a column offers: 0–23, or the 1–12 clock face. */\nfunction hourOptions(hourCycle) {\n\treturn hourCycle === 24 ? timeRange(24) : timeRange(12).map((hour) => hour + 1);\n}\n//#endregion\nexport { formatTimeDisplay, formatTimeValue, hourOptions, meridiemOf, padTimePart, parseTimeValue, timeRange, toHour12, toHour24 };\n",":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-timepicker-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-timepicker-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n.trigger {\n align-items: center;\n background: var(--pf-timepicker-bg);\n border: 1px solid var(--pf-timepicker-border);\n border-radius: var(--radius-md);\n color: var(--pf-timepicker-text);\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: var(--font-size-sm);\n gap: var(--space-2);\n justify-content: space-between;\n padding: var(--space-2) var(--space-3);\n text-align: start;\n width: 100%;\n}\n\n.trigger:focus-visible {\n border-color: var(--pf-timepicker-focus-border);\n box-shadow: var(--pf-focus-ring);\n outline: none;\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.trigger--invalid {\n border-color: var(--pf-timepicker-invalid-border);\n}\n\n.value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value--placeholder {\n color: var(--pf-timepicker-placeholder);\n}\n\n.description {\n color: var(--pf-timepicker-text-muted);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-timepicker-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n/*\n * See src/place-popover.ts: `inset: auto; margin: 0` are what make the\n * coordinates mean what they say, since the UA stylesheet centres a popover.\n */\n.panel {\n inset: auto;\n margin: 0;\n background: var(--pf-timepicker-menu-bg);\n border: 1px solid var(--pf-timepicker-menu-border);\n border-radius: var(--radius-md);\n box-shadow: var(--pf-elevation-popover-shadow);\n display: flex;\n gap: var(--space-1);\n padding: var(--space-1);\n}\n\n.panel:popover-open {\n animation: pf-time-picker-in var(--pf-transition-enter);\n}\n\n/* Its own copy: @keyframes do not cross a shadow boundary. */\n@keyframes pf-time-picker-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .panel:popover-open {\n animation: none;\n }\n}\n\n.column {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 220px;\n overflow-y: auto;\n scrollbar-width: thin;\n}\n\n.column:focus-visible {\n outline: none;\n}\n\n.option {\n background: none;\n border: 0;\n border-radius: var(--radius-sm);\n color: var(--pf-timepicker-text);\n cursor: pointer;\n font-family: inherit;\n font-size: var(--font-size-sm);\n font-variant-numeric: tabular-nums;\n padding: var(--space-1) var(--space-3);\n text-align: center;\n}\n\n.option:hover {\n background: var(--pf-timepicker-option-hover-bg);\n}\n\n.option:focus-visible {\n box-shadow: var(--pf-focus-ring);\n outline: none;\n}\n\n.option--selected {\n background: var(--pf-timepicker-option-active-bg);\n color: var(--pf-timepicker-option-active-text);\n}\n","import {\n composeDescribedBy,\n formatTimeDisplay,\n formatTimeValue,\n hourOptions,\n Keys,\n meridiemOf,\n observeAnchoredPosition,\n padTimePart,\n parseTimeValue,\n timeRange,\n toHour12,\n toHour24,\n type HourCycle,\n type Meridiem,\n type TimeParts,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport { placePopover } from '../../place-popover';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated time field: a trigger that opens hour, minute and (on a\n * 12-hour cycle) meridiem columns in a popover.\n *\n * The submitted value is always canonical 24-hour `HH:mm`, whatever\n * `hour-cycle` displays. A control whose submitted value changed with its\n * display would be unusable on a server, so the cycle is a rendering choice\n * and nothing more — all of that arithmetic is core's.\n *\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part trigger - the button that opens the columns.\n * @part panel - the floating panel.\n * @part column - each of the scrolling columns.\n * @part option - every option button.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-time-picker',\n styleUrl: 'pf-time-picker.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfTimePicker {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name. Reflected; the submission reads the attribute. */\n @Prop({ reflect: true }) name?: string;\n\n /** Canonical 24-hour `HH:mm`, or empty. */\n @Prop({ mutable: true }) value = '';\n\n /** Whether the panel is showing. Reflected for the stylesheet. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /**\n * 12- or 24-hour display. The value stays 24-hour either way.\n *\n * Read through `cycle` below, never directly: Stencil coerces an attribute\n * using the prop's type as *written*, and it cannot resolve a name it had\n * to import. Measured: with `HourCycle` imported from core,\n * `hour-cycle=\"12\"` arrives as the **string** `\"12\"`, so `=== 12` is\n * false, while `minute-step=\"15\"` — declared `number` — arrives as `15`.\n * Writing `0 | 1` out inline *is* coerced, which `pf-heatmap.weekStartsOn`\n * shows; the alias is kept here because it is the shared type, and the\n * getter costs nothing.\n */\n @Prop() hourCycle: HourCycle = 24;\n\n /** Granularity of the minutes column. */\n @Prop() minuteStep = 1;\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Select time';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /** Fires when the time changes, with the canonical `HH:mm`. */\n @Event() pfChange!: EventEmitter<{ value: string }>;\n\n /** Fires whenever the panel opens or closes, whoever caused it. */\n @Event() pfOpenChange!: EventEmitter<{ open: boolean }>;\n\n private initialValue = '';\n private stopObserving?: () => void;\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n componentDidRender() {\n if (this.open) this.scrollSelectedIntoView();\n }\n\n disconnectedCallback() {\n this.stopObserving?.();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value || null);\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n @Watch('open')\n syncOpen(next: boolean, previous: boolean) {\n if (next) this.showPanel();\n else this.hidePanel();\n if (next !== previous) this.pfOpenChange.emit({ open: next });\n }\n\n @Method()\n async show(): Promise<void> {\n if (!this.disabled) this.open = true;\n }\n\n @Method()\n async hide(): Promise<void> {\n this.open = false;\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /** A reset restores the value the field started with, not an empty one. */\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n /** `hourCycle` with the attribute case coerced; see the prop's comment. */\n private get cycle(): HourCycle {\n return Number(this.hourCycle) === 12 ? 12 : 24;\n }\n\n private get panel() {\n return this.el.shadowRoot?.querySelector<HTMLElement>('[part=\"panel\"]') ?? null;\n }\n\n private get trigger() {\n return this.el.shadowRoot?.querySelector<HTMLButtonElement>('[part=\"trigger\"]') ?? null;\n }\n\n private get parts(): TimeParts {\n return parseTimeValue(this.value);\n }\n\n private showPanel() {\n const panel = this.panel;\n if (this.disabled || !panel || panel.matches(':popover-open')) return;\n\n panel.showPopover();\n this.stopObserving?.();\n this.stopObserving = observeAnchoredPosition({\n getAnchor: () => this.trigger,\n getFloating: () => panel,\n align: 'start',\n matchAnchorWidth: false,\n flip: true,\n onChange: ({ left, top }) => placePopover(panel, left, top),\n });\n\n this.scrollSelectedIntoView();\n // Focus the first column's selected option, so the arrows work at once.\n panel.querySelector<HTMLButtonElement>('[data-selected=\"true\"]')?.focus();\n }\n\n private hidePanel() {\n this.stopObserving?.();\n this.stopObserving = undefined;\n const panel = this.panel;\n if (panel?.matches(':popover-open')) panel.hidePopover();\n }\n\n /**\n * Centres each column on its chosen option.\n *\n * `block: 'nearest'` would leave a column that is already scrolled roughly\n * right alone, which reads as the wrong hour being selected.\n */\n private scrollSelectedIntoView() {\n for (const option of Array.from(\n this.panel?.querySelectorAll<HTMLElement>('[data-selected=\"true\"]') ?? [],\n )) {\n if (typeof option.scrollIntoView === 'function') {\n option.scrollIntoView({ block: 'center' });\n }\n }\n }\n\n private onToggle = (event: ToggleEvent) => {\n const nowOpen = event.newState === 'open';\n if (this.open !== nowOpen) this.open = nowOpen;\n if (!nowOpen) this.trigger?.focus();\n };\n\n private commit(next: TimeParts) {\n const value = formatTimeValue(next);\n if (!value || value === this.value) return;\n this.value = value;\n this.pfChange.emit({ value });\n }\n\n private selectHour(hour: number) {\n const hour24 = this.cycle === 24 ? hour : toHour24(hour, this.selectedMeridiem() ?? 'AM');\n this.commit({ hour: hour24, minute: this.parts.minute ?? 0 });\n }\n\n private selectMinute(minute: number) {\n this.commit({ hour: this.parts.hour ?? 0, minute });\n }\n\n private selectMeridiem(meridiem: Meridiem) {\n const { hour, minute } = this.parts;\n this.commit({ hour: toHour24(toHour12(hour ?? 0), meridiem), minute: minute ?? 0 });\n }\n\n private selectedMeridiem(): Meridiem | null {\n const { hour } = this.parts;\n return hour === null ? null : meridiemOf(hour);\n }\n\n /**\n * Up and down move within a column, and stop at its ends rather than\n * wrapping — a wrap in a scrolling column of 60 minutes reads as the list\n * having jumped rather than moved.\n *\n * The focused option is read from `shadowRoot.activeElement`, because\n * `document.activeElement` is this host: focus inside a shadow root is\n * reported as the host from the outside.\n */\n private onColumnKeyDown = (event: KeyboardEvent) => {\n if (event.key !== Keys.ArrowDown && event.key !== Keys.ArrowUp) return;\n\n const column = event.currentTarget as HTMLElement;\n const options = Array.from(column.querySelectorAll<HTMLButtonElement>('button'));\n const index = options.indexOf(this.el.shadowRoot?.activeElement as HTMLButtonElement);\n if (index === -1) return;\n\n event.preventDefault();\n const next = event.key === Keys.ArrowDown ? index + 1 : index - 1;\n options[Math.min(Math.max(next, 0), options.length - 1)]?.focus();\n };\n\n private renderColumn(\n name: string,\n options: Array<{ key: string; label: string; selected: boolean; onSelect: () => void }>,\n ) {\n return (\n <div\n class=\"column\"\n part=\"column\"\n role=\"listbox\"\n aria-label={name}\n tabindex={-1}\n onKeyDown={this.onColumnKeyDown}\n >\n {options.map((option) => (\n <button\n key={option.key}\n type=\"button\"\n part=\"option\"\n class={{ option: true, 'option--selected': option.selected }}\n role=\"option\"\n aria-selected={option.selected ? 'true' : 'false'}\n data-selected={option.selected ? 'true' : 'false'}\n onClick={option.onSelect}\n >\n {option.label}\n </button>\n ))}\n </div>\n );\n }\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const { hour, minute } = this.parts;\n const display = formatTimeDisplay(this.parts, this.cycle);\n const shownHour = hour === null ? null : this.cycle === 24 ? hour : toHour12(hour);\n const meridiem = this.selectedMeridiem();\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"trigger\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <button\n id=\"trigger\"\n part=\"trigger\"\n class={{ trigger: true, 'trigger--invalid': Boolean(this.error) }}\n type=\"button\"\n disabled={this.disabled}\n aria-haspopup=\"dialog\"\n aria-expanded={this.open ? 'true' : 'false'}\n /* Same shadow root as the panel, so this IDREF resolves. */\n aria-controls=\"panel\"\n aria-invalid={this.error ? 'true' : null}\n aria-required={this.required ? 'true' : null}\n aria-describedby={describedBy}\n onClick={() => {\n if (!this.disabled) this.open = !this.open;\n }}\n >\n <span class={{ value: true, 'value--placeholder': !display }}>\n {display || this.placeholder}\n </span>\n <pf-icon name=\"clock\"></pf-icon>\n </button>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n\n <div\n id=\"panel\"\n part=\"panel\"\n class=\"panel\"\n popover=\"auto\"\n role=\"dialog\"\n aria-label=\"Choose a time\"\n onToggle={this.onToggle}\n >\n {this.renderColumn(\n 'Hour',\n hourOptions(this.cycle).map((option) => ({\n key: `h-${option}`,\n label: padTimePart(option),\n selected: shownHour === option,\n onSelect: () => this.selectHour(option),\n })),\n )}\n\n {this.renderColumn(\n 'Minute',\n timeRange(60, this.minuteStep).map((option) => ({\n key: `m-${option}`,\n label: padTimePart(option),\n selected: minute === option,\n onSelect: () => this.selectMinute(option),\n })),\n )}\n\n {this.cycle === 12 &&\n this.renderColumn(\n 'AM or PM',\n (['AM', 'PM'] as Meridiem[]).map((option) => ({\n key: option,\n label: option,\n selected: meridiem === option,\n onSelect: () => this.selectMeridiem(option),\n })),\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["padTimePart","value","String","padStart","parseTimeValue","match","exec","trim","hour","minute","Number","formatTimeValue","parts","formatTimeDisplay","hourCycle","toHour12","meridiemOf","hour24","face","toHour24","hour12","meridiem","base","timeRange","length","step","safeStep","Math","max","floor","count","ceil","Array","from","_","index","hourOptions","map","pfTimePickerCss","PfTimePicker","__stencil_proxyCustomElement","HTMLElement","internals","name","open","minuteStep","label","description","error","placeholder","required","disabled","pfChange","pfOpenChange","initialValue","stopObserving","componentWillLoad","this","syncFormState","componentDidRender","scrollSelectedIntoView","disconnectedCallback","setFormValue","applyControlValidity","Boolean","syncOpen","next","previous","showPanel","hidePanel","emit","show","hide","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","cycle","panel","el","shadowRoot","querySelector","trigger","matches","showPopover","observeAnchoredPosition","getAnchor","getFloating","align","matchAnchorWidth","flip","onChange","left","top","placePopover","focus","undefined","hidePopover","option","querySelectorAll","scrollIntoView","block","onToggle","event","nowOpen","newState","commit","selectHour","selectedMeridiem","selectMinute","selectMeridiem","onColumnKeyDown","key","Keys","ArrowDown","ArrowUp","column","currentTarget","options","indexOf","activeElement","preventDefault","min","renderColumn","h","class","part","role","tabindex","onKeyDown","type","selected","onClick","onSelect","render","describedBy","composeDescribedBy","display","shownHour","Host","htmlFor","id","controlAriaLabel","popover"],"sources":["../core/dist/time.js","src/components/pf-time-picker/pf-time-picker.css?tag=pf-time-picker&encapsulation=shadow","src/components/pf-time-picker/pf-time-picker.tsx"],"sourcesContent":["//#region src/time.ts\n/**\n* Two digits, which both layers need for the column labels as well as for the\n* canonical value — so it is exported rather than private.\n*/\nvar padTimePart = (value) => String(value).padStart(2, \"0\");\n/**\n* Parses `HH:mm` (or `H:mm`) into hour and minute, or nulls.\n*\n* Out-of-range parts are rejected rather than wrapped: `25:00` is not 1am, it\n* is a mistake, and silently turning it into one hides the mistake.\n*/\nfunction parseTimeValue(value) {\n\tconst match = /^(\\d{1,2}):(\\d{2})$/.exec((value ?? \"\").trim());\n\tif (!match) return {\n\t\thour: null,\n\t\tminute: null\n\t};\n\tconst hour = Number(match[1]);\n\tconst minute = Number(match[2]);\n\tif (hour > 23 || minute > 59) return {\n\t\thour: null,\n\t\tminute: null\n\t};\n\treturn {\n\t\thour,\n\t\tminute\n\t};\n}\n/** The canonical 24-hour `HH:mm`, or `''` when either part is missing. */\nfunction formatTimeValue(parts) {\n\tif (parts.hour === null || parts.minute === null) return \"\";\n\treturn `${padTimePart(parts.hour)}:${padTimePart(parts.minute)}`;\n}\n/** What the trigger shows: `14:30`, or `2:30 PM` on a 12-hour cycle. */\nfunction formatTimeDisplay(parts, hourCycle) {\n\tif (parts.hour === null || parts.minute === null) return \"\";\n\tif (hourCycle === 24) return `${padTimePart(parts.hour)}:${padTimePart(parts.minute)}`;\n\treturn `${toHour12(parts.hour)}:${padTimePart(parts.minute)} ${meridiemOf(parts.hour)}`;\n}\n/** Which half of the day an hour falls in. */\nfunction meridiemOf(hour24) {\n\treturn hour24 < 12 ? \"AM\" : \"PM\";\n}\n/**\n* The 12-hour face of a 24-hour hour: midnight and midday both read as 12,\n* not 0, which is the one case `hour % 12` gets wrong.\n*/\nfunction toHour12(hour24) {\n\tconst face = hour24 % 12;\n\treturn face === 0 ? 12 : face;\n}\n/** The 24-hour hour for a clock face plus a meridiem. 12 AM is 0, 12 PM is 12. */\nfunction toHour24(hour12, meridiem) {\n\tconst base = hour12 % 12;\n\treturn meridiem === \"PM\" ? base + 12 : base;\n}\n/**\n* The options a column offers: `0, step, 2*step, …` below `length`.\n*\n* A step that does not divide the range leaves a short last stride rather\n* than overshooting — `timeRange(60, 25)` is `[0, 25, 50]`, and 50 is a real\n* minute where 75 is not.\n*/\nfunction timeRange(length, step = 1) {\n\tconst safeStep = Math.max(1, Math.floor(step));\n\tconst count = Math.ceil(length / safeStep);\n\treturn Array.from({ length: count }, (_, index) => index * safeStep);\n}\n/** The hours a column offers: 0–23, or the 1–12 clock face. */\nfunction hourOptions(hourCycle) {\n\treturn hourCycle === 24 ? timeRange(24) : timeRange(12).map((hour) => hour + 1);\n}\n//#endregion\nexport { formatTimeDisplay, formatTimeValue, hourOptions, meridiemOf, padTimePart, parseTimeValue, timeRange, toHour12, toHour24 };\n",":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-timepicker-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-timepicker-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n.trigger {\n align-items: center;\n background: var(--pf-timepicker-bg);\n border: 1px solid var(--pf-timepicker-border);\n border-radius: var(--radius-md);\n color: var(--pf-timepicker-text);\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: var(--font-size-sm);\n gap: var(--space-2);\n justify-content: space-between;\n padding: var(--space-2) var(--space-3);\n text-align: start;\n width: 100%;\n}\n\n.trigger:focus-visible {\n border-color: var(--pf-timepicker-focus-border);\n box-shadow: var(--pf-focus-ring);\n outline: none;\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.trigger--invalid {\n border-color: var(--pf-timepicker-invalid-border);\n}\n\n.value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value--placeholder {\n color: var(--pf-timepicker-placeholder);\n}\n\n.description {\n color: var(--pf-timepicker-text-muted);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-timepicker-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n/*\n * See src/place-popover.ts: `inset: auto; margin: 0` are what make the\n * coordinates mean what they say, since the UA stylesheet centres a popover.\n */\n.panel {\n inset: auto;\n margin: 0;\n background: var(--pf-timepicker-menu-bg);\n border: 1px solid var(--pf-timepicker-menu-border);\n border-radius: var(--radius-md);\n box-shadow: var(--pf-elevation-popover-shadow);\n display: flex;\n gap: var(--space-1);\n padding: var(--space-1);\n}\n\n.panel:popover-open {\n animation: pf-time-picker-in var(--pf-transition-enter);\n}\n\n/* Its own copy: @keyframes do not cross a shadow boundary. */\n@keyframes pf-time-picker-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .panel:popover-open {\n animation: none;\n }\n}\n\n.column {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 220px;\n overflow-y: auto;\n scrollbar-width: thin;\n}\n\n.column:focus-visible {\n outline: none;\n}\n\n.option {\n background: none;\n border: 0;\n border-radius: var(--radius-sm);\n color: var(--pf-timepicker-text);\n cursor: pointer;\n font-family: inherit;\n font-size: var(--font-size-sm);\n font-variant-numeric: tabular-nums;\n padding: var(--space-1) var(--space-3);\n text-align: center;\n}\n\n.option:hover {\n background: var(--pf-timepicker-option-hover-bg);\n}\n\n.option:focus-visible {\n box-shadow: var(--pf-focus-ring);\n outline: none;\n}\n\n.option--selected {\n background: var(--pf-timepicker-option-active-bg);\n color: var(--pf-timepicker-option-active-text);\n}\n","import {\n composeDescribedBy,\n formatTimeDisplay,\n formatTimeValue,\n hourOptions,\n Keys,\n meridiemOf,\n observeAnchoredPosition,\n padTimePart,\n parseTimeValue,\n timeRange,\n toHour12,\n toHour24,\n type HourCycle,\n type Meridiem,\n type TimeParts,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport { controlAriaLabel } from '../../control-label';\nimport { placePopover } from '../../place-popover';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated time field: a trigger that opens hour, minute and (on a\n * 12-hour cycle) meridiem columns in a popover.\n *\n * The submitted value is always canonical 24-hour `HH:mm`, whatever\n * `hour-cycle` displays. A control whose submitted value changed with its\n * display would be unusable on a server, so the cycle is a rendering choice\n * and nothing more — all of that arithmetic is core's.\n *\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part trigger - the button that opens the columns.\n * @part panel - the floating panel.\n * @part column - each of the scrolling columns.\n * @part option - every option button.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-time-picker',\n styleUrl: 'pf-time-picker.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfTimePicker {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name. Reflected; the submission reads the attribute. */\n @Prop({ reflect: true }) name?: string;\n\n /** Canonical 24-hour `HH:mm`, or empty. */\n @Prop({ mutable: true }) value = '';\n\n /** Whether the panel is showing. Reflected for the stylesheet. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /**\n * 12- or 24-hour display. The value stays 24-hour either way.\n *\n * Read through `cycle` below, never directly: Stencil coerces an attribute\n * using the prop's type as *written*, and it cannot resolve a name it had\n * to import. Measured: with `HourCycle` imported from core,\n * `hour-cycle=\"12\"` arrives as the **string** `\"12\"`, so `=== 12` is\n * false, while `minute-step=\"15\"` — declared `number` — arrives as `15`.\n * Writing `0 | 1` out inline *is* coerced, which `pf-heatmap.weekStartsOn`\n * shows; the alias is kept here because it is the shared type, and the\n * getter costs nothing.\n */\n @Prop() hourCycle: HourCycle = 24;\n\n /** Granularity of the minutes column. */\n @Prop() minuteStep = 1;\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Select time';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /** Fires when the time changes, with the canonical `HH:mm`. */\n @Event() pfChange!: EventEmitter<{ value: string }>;\n\n /** Fires whenever the panel opens or closes, whoever caused it. */\n @Event() pfOpenChange!: EventEmitter<{ open: boolean }>;\n\n private initialValue = '';\n private stopObserving?: () => void;\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n componentDidRender() {\n if (this.open) this.scrollSelectedIntoView();\n }\n\n disconnectedCallback() {\n this.stopObserving?.();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value || null);\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n @Watch('open')\n syncOpen(next: boolean, previous: boolean) {\n if (next) this.showPanel();\n else this.hidePanel();\n if (next !== previous) this.pfOpenChange.emit({ open: next });\n }\n\n @Method()\n async show(): Promise<void> {\n if (!this.disabled) this.open = true;\n }\n\n @Method()\n async hide(): Promise<void> {\n this.open = false;\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /** A reset restores the value the field started with, not an empty one. */\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n /** `hourCycle` with the attribute case coerced; see the prop's comment. */\n private get cycle(): HourCycle {\n return Number(this.hourCycle) === 12 ? 12 : 24;\n }\n\n private get panel() {\n return this.el.shadowRoot?.querySelector<HTMLElement>('[part=\"panel\"]') ?? null;\n }\n\n private get trigger() {\n return this.el.shadowRoot?.querySelector<HTMLButtonElement>('[part=\"trigger\"]') ?? null;\n }\n\n private get parts(): TimeParts {\n return parseTimeValue(this.value);\n }\n\n private showPanel() {\n const panel = this.panel;\n if (this.disabled || !panel || panel.matches(':popover-open')) return;\n\n panel.showPopover();\n this.stopObserving?.();\n this.stopObserving = observeAnchoredPosition({\n getAnchor: () => this.trigger,\n getFloating: () => panel,\n align: 'start',\n matchAnchorWidth: false,\n flip: true,\n onChange: ({ left, top }) => placePopover(panel, left, top),\n });\n\n this.scrollSelectedIntoView();\n // Focus the first column's selected option, so the arrows work at once.\n panel.querySelector<HTMLButtonElement>('[data-selected=\"true\"]')?.focus();\n }\n\n private hidePanel() {\n this.stopObserving?.();\n this.stopObserving = undefined;\n const panel = this.panel;\n if (panel?.matches(':popover-open')) panel.hidePopover();\n }\n\n /**\n * Centres each column on its chosen option.\n *\n * `block: 'nearest'` would leave a column that is already scrolled roughly\n * right alone, which reads as the wrong hour being selected.\n */\n private scrollSelectedIntoView() {\n for (const option of Array.from(\n this.panel?.querySelectorAll<HTMLElement>('[data-selected=\"true\"]') ?? [],\n )) {\n if (typeof option.scrollIntoView === 'function') {\n option.scrollIntoView({ block: 'center' });\n }\n }\n }\n\n private onToggle = (event: ToggleEvent) => {\n const nowOpen = event.newState === 'open';\n if (this.open !== nowOpen) this.open = nowOpen;\n if (!nowOpen) this.trigger?.focus();\n };\n\n private commit(next: TimeParts) {\n const value = formatTimeValue(next);\n if (!value || value === this.value) return;\n this.value = value;\n this.pfChange.emit({ value });\n }\n\n private selectHour(hour: number) {\n const hour24 = this.cycle === 24 ? hour : toHour24(hour, this.selectedMeridiem() ?? 'AM');\n this.commit({ hour: hour24, minute: this.parts.minute ?? 0 });\n }\n\n private selectMinute(minute: number) {\n this.commit({ hour: this.parts.hour ?? 0, minute });\n }\n\n private selectMeridiem(meridiem: Meridiem) {\n const { hour, minute } = this.parts;\n this.commit({ hour: toHour24(toHour12(hour ?? 0), meridiem), minute: minute ?? 0 });\n }\n\n private selectedMeridiem(): Meridiem | null {\n const { hour } = this.parts;\n return hour === null ? null : meridiemOf(hour);\n }\n\n /**\n * Up and down move within a column, and stop at its ends rather than\n * wrapping — a wrap in a scrolling column of 60 minutes reads as the list\n * having jumped rather than moved.\n *\n * The focused option is read from `shadowRoot.activeElement`, because\n * `document.activeElement` is this host: focus inside a shadow root is\n * reported as the host from the outside.\n */\n private onColumnKeyDown = (event: KeyboardEvent) => {\n if (event.key !== Keys.ArrowDown && event.key !== Keys.ArrowUp) return;\n\n const column = event.currentTarget as HTMLElement;\n const options = Array.from(column.querySelectorAll<HTMLButtonElement>('button'));\n const index = options.indexOf(this.el.shadowRoot?.activeElement as HTMLButtonElement);\n if (index === -1) return;\n\n event.preventDefault();\n const next = event.key === Keys.ArrowDown ? index + 1 : index - 1;\n options[Math.min(Math.max(next, 0), options.length - 1)]?.focus();\n };\n\n private renderColumn(\n name: string,\n options: Array<{ key: string; label: string; selected: boolean; onSelect: () => void }>,\n ) {\n return (\n <div\n class=\"column\"\n part=\"column\"\n role=\"listbox\"\n aria-label={name}\n tabindex={-1}\n onKeyDown={this.onColumnKeyDown}\n >\n {options.map((option) => (\n <button\n key={option.key}\n type=\"button\"\n part=\"option\"\n class={{ option: true, 'option--selected': option.selected }}\n role=\"option\"\n aria-selected={option.selected ? 'true' : 'false'}\n data-selected={option.selected ? 'true' : 'false'}\n onClick={option.onSelect}\n >\n {option.label}\n </button>\n ))}\n </div>\n );\n }\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const { hour, minute } = this.parts;\n const display = formatTimeDisplay(this.parts, this.cycle);\n const shownHour = hour === null ? null : this.cycle === 24 ? hour : toHour12(hour);\n const meridiem = this.selectedMeridiem();\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"trigger\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <button\n id=\"trigger\"\n aria-label={controlAriaLabel(this.el, this.label)}\n part=\"trigger\"\n class={{ trigger: true, 'trigger--invalid': Boolean(this.error) }}\n type=\"button\"\n disabled={this.disabled}\n aria-haspopup=\"dialog\"\n aria-expanded={this.open ? 'true' : 'false'}\n /* Same shadow root as the panel, so this IDREF resolves. */\n aria-controls=\"panel\"\n aria-invalid={this.error ? 'true' : null}\n aria-required={this.required ? 'true' : null}\n aria-describedby={describedBy}\n onClick={() => {\n if (!this.disabled) this.open = !this.open;\n }}\n >\n <span class={{ value: true, 'value--placeholder': !display }}>\n {display || this.placeholder}\n </span>\n <pf-icon name=\"clock\"></pf-icon>\n </button>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n\n <div\n id=\"panel\"\n part=\"panel\"\n class=\"panel\"\n popover=\"auto\"\n role=\"dialog\"\n aria-label=\"Choose a time\"\n onToggle={this.onToggle}\n >\n {this.renderColumn(\n 'Hour',\n hourOptions(this.cycle).map((option) => ({\n key: `h-${option}`,\n label: padTimePart(option),\n selected: shownHour === option,\n onSelect: () => this.selectHour(option),\n })),\n )}\n\n {this.renderColumn(\n 'Minute',\n timeRange(60, this.minuteStep).map((option) => ({\n key: `m-${option}`,\n label: padTimePart(option),\n selected: minute === option,\n onSelect: () => this.selectMinute(option),\n })),\n )}\n\n {this.cycle === 12 &&\n this.renderColumn(\n 'AM or PM',\n (['AM', 'PM'] as Meridiem[]).map((option) => ({\n key: option,\n label: option,\n selected: meridiem === option,\n onSelect: () => this.selectMeridiem(option),\n })),\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|