@universal-material/web 3.7.2 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/app-bar/top-app-bar.d.ts +15 -0
  2. package/app-bar/top-app-bar.d.ts.map +1 -1
  3. package/app-bar/top-app-bar.js +15 -0
  4. package/app-bar/top-app-bar.js.map +1 -1
  5. package/badge/badge.d.ts +3 -0
  6. package/badge/badge.d.ts.map +1 -1
  7. package/badge/badge.js +3 -0
  8. package/badge/badge.js.map +1 -1
  9. package/bundle.min.js +600 -482
  10. package/button/button-base.d.ts +7 -0
  11. package/button/button-base.d.ts.map +1 -1
  12. package/button/button-base.js +7 -0
  13. package/button/button-base.js.map +1 -1
  14. package/button/button.d.ts +3 -0
  15. package/button/button.d.ts.map +1 -1
  16. package/button/button.js +3 -0
  17. package/button/button.js.map +1 -1
  18. package/button/icon-button.d.ts +6 -0
  19. package/button/icon-button.d.ts.map +1 -1
  20. package/button/icon-button.js +6 -0
  21. package/button/icon-button.js.map +1 -1
  22. package/button-field/button-field.d.ts +3 -0
  23. package/button-field/button-field.d.ts.map +1 -1
  24. package/button-field/button-field.js +3 -0
  25. package/button-field/button-field.js.map +1 -1
  26. package/calendar/calendar-adapter.d.ts +3 -0
  27. package/calendar/calendar-adapter.d.ts.map +1 -1
  28. package/calendar/calendar-adapter.js.map +1 -1
  29. package/calendar/calendar-base.d.ts +17 -0
  30. package/calendar/calendar-base.d.ts.map +1 -1
  31. package/calendar/calendar-base.js +182 -19
  32. package/calendar/calendar-base.js.map +1 -1
  33. package/calendar/calendar.d.ts +4 -0
  34. package/calendar/calendar.d.ts.map +1 -1
  35. package/calendar/calendar.js +4 -0
  36. package/calendar/calendar.js.map +1 -1
  37. package/calendar/default-calendar-adapter.d.ts +3 -0
  38. package/calendar/default-calendar-adapter.d.ts.map +1 -1
  39. package/calendar/default-calendar-adapter.js +17 -5
  40. package/calendar/default-calendar-adapter.js.map +1 -1
  41. package/card/card-content.d.ts +5 -0
  42. package/card/card-content.d.ts.map +1 -1
  43. package/card/card-content.js +5 -0
  44. package/card/card-content.js.map +1 -1
  45. package/card/card-media.d.ts +3 -0
  46. package/card/card-media.d.ts.map +1 -1
  47. package/card/card-media.js +3 -0
  48. package/card/card-media.js.map +1 -1
  49. package/checkbox/checkbox.d.ts +7 -0
  50. package/checkbox/checkbox.d.ts.map +1 -1
  51. package/checkbox/checkbox.js +7 -0
  52. package/checkbox/checkbox.js.map +1 -1
  53. package/chip/chip.d.ts +3 -0
  54. package/chip/chip.d.ts.map +1 -1
  55. package/chip/chip.js +3 -0
  56. package/chip/chip.js.map +1 -1
  57. package/chip-field/chip-field.d.ts +3 -0
  58. package/chip-field/chip-field.d.ts.map +1 -1
  59. package/chip-field/chip-field.js.map +1 -1
  60. package/custom-elements.json +12881 -9853
  61. package/datepicker/datepicker.d.ts +51 -2
  62. package/datepicker/datepicker.d.ts.map +1 -1
  63. package/datepicker/datepicker.js +185 -3
  64. package/datepicker/datepicker.js.map +1 -1
  65. package/datepicker/format.d.ts +19 -0
  66. package/datepicker/format.d.ts.map +1 -0
  67. package/datepicker/format.js +47 -0
  68. package/datepicker/format.js.map +1 -0
  69. package/datepicker/range-datepicker.d.ts +56 -0
  70. package/datepicker/range-datepicker.d.ts.map +1 -0
  71. package/datepicker/range-datepicker.js +198 -0
  72. package/datepicker/range-datepicker.js.map +1 -0
  73. package/dialog/dialog.d.ts +8 -0
  74. package/dialog/dialog.d.ts.map +1 -1
  75. package/dialog/dialog.js +8 -0
  76. package/dialog/dialog.js.map +1 -1
  77. package/field/field-base.d.ts +14 -0
  78. package/field/field-base.d.ts.map +1 -1
  79. package/field/field-base.js +10 -0
  80. package/field/field-base.js.map +1 -1
  81. package/field/field.d.ts +4 -0
  82. package/field/field.d.ts.map +1 -1
  83. package/field/field.js +4 -0
  84. package/field/field.js.map +1 -1
  85. package/index.d.ts +5 -0
  86. package/index.d.ts.map +1 -1
  87. package/index.js +5 -0
  88. package/index.js.map +1 -1
  89. package/list/list-item.d.ts +3 -0
  90. package/list/list-item.d.ts.map +1 -1
  91. package/list/list-item.js +3 -0
  92. package/list/list-item.js.map +1 -1
  93. package/menu/menu-item.d.ts +6 -0
  94. package/menu/menu-item.d.ts.map +1 -1
  95. package/menu/menu-item.js +6 -0
  96. package/menu/menu-item.js.map +1 -1
  97. package/menu/menu.d.ts +16 -0
  98. package/menu/menu.d.ts.map +1 -1
  99. package/menu/menu.js +24 -5
  100. package/menu/menu.js.map +1 -1
  101. package/menu/menu.styles.d.ts.map +1 -1
  102. package/menu/menu.styles.js +5 -0
  103. package/menu/menu.styles.js.map +1 -1
  104. package/navigation/drawer-headline.styles.js +1 -1
  105. package/navigation/drawer-headline.styles.js.map +1 -1
  106. package/overflow-menu/overflow-menu-item.d.ts +8 -0
  107. package/overflow-menu/overflow-menu-item.d.ts.map +1 -1
  108. package/overflow-menu/overflow-menu-item.js +8 -0
  109. package/overflow-menu/overflow-menu-item.js.map +1 -1
  110. package/package.json +3 -3
  111. package/progress/circular-progress.d.ts +7 -0
  112. package/progress/circular-progress.d.ts.map +1 -1
  113. package/progress/circular-progress.js +3 -0
  114. package/progress/circular-progress.js.map +1 -1
  115. package/progress/progress-bar.d.ts +7 -0
  116. package/progress/progress-bar.d.ts.map +1 -1
  117. package/progress/progress-bar.js +3 -0
  118. package/progress/progress-bar.js.map +1 -1
  119. package/radio/radio.d.ts +3 -0
  120. package/radio/radio.d.ts.map +1 -1
  121. package/radio/radio.js +3 -0
  122. package/radio/radio.js.map +1 -1
  123. package/search/search.d.ts +3 -0
  124. package/search/search.d.ts.map +1 -1
  125. package/search/search.js +3 -0
  126. package/search/search.js.map +1 -1
  127. package/select/option.d.ts +6 -0
  128. package/select/option.d.ts.map +1 -1
  129. package/select/option.js +6 -0
  130. package/select/option.js.map +1 -1
  131. package/select/select.d.ts +4 -0
  132. package/select/select.d.ts.map +1 -1
  133. package/select/select.js +4 -0
  134. package/select/select.js.map +1 -1
  135. package/shared/button-wrapper.d.ts +3 -0
  136. package/shared/button-wrapper.d.ts.map +1 -1
  137. package/shared/button-wrapper.js.map +1 -1
  138. package/shared/char-count-text-field/native-text-field-wrapper.d.ts +13 -0
  139. package/shared/char-count-text-field/native-text-field-wrapper.d.ts.map +1 -1
  140. package/shared/char-count-text-field/native-text-field-wrapper.js +10 -0
  141. package/shared/char-count-text-field/native-text-field-wrapper.js.map +1 -1
  142. package/shared/selection-control/selection-control-list-item.d.ts.map +1 -1
  143. package/shared/selection-control/selection-control-list-item.js +4 -0
  144. package/shared/selection-control/selection-control-list-item.js.map +1 -1
  145. package/shared/selection-control/selection-control.d.ts +9 -0
  146. package/shared/selection-control/selection-control.d.ts.map +1 -1
  147. package/shared/selection-control/selection-control.js +9 -0
  148. package/shared/selection-control/selection-control.js.map +1 -1
  149. package/shared/text-field-base/text-field-base.d.ts +3 -0
  150. package/shared/text-field-base/text-field-base.d.ts.map +1 -1
  151. package/shared/text-field-base/text-field-base.js +3 -0
  152. package/shared/text-field-base/text-field-base.js.map +1 -1
  153. package/snackbar/snackbar.d.ts +9 -0
  154. package/snackbar/snackbar.d.ts.map +1 -1
  155. package/snackbar/snackbar.js +9 -0
  156. package/snackbar/snackbar.js.map +1 -1
  157. package/tab-bar/tab-bar.d.ts +3 -0
  158. package/tab-bar/tab-bar.d.ts.map +1 -1
  159. package/tab-bar/tab-bar.js +3 -0
  160. package/tab-bar/tab-bar.js.map +1 -1
  161. package/tab-bar/tab.d.ts +5 -0
  162. package/tab-bar/tab.d.ts.map +1 -1
  163. package/tab-bar/tab.js +5 -0
  164. package/tab-bar/tab.js.map +1 -1
  165. package/text-area/text-area.d.ts +3 -0
  166. package/text-area/text-area.d.ts.map +1 -1
  167. package/text-area/text-area.js +3 -0
  168. package/text-area/text-area.js.map +1 -1
  169. package/text-field/text-field.d.ts +16 -0
  170. package/text-field/text-field.d.ts.map +1 -1
  171. package/text-field/text-field.js +7 -0
  172. package/text-field/text-field.js.map +1 -1
  173. package/typeahead/typeahead-template-render.d.ts +4 -0
  174. package/typeahead/typeahead-template-render.d.ts.map +1 -1
  175. package/typeahead/typeahead-template-render.js +4 -0
  176. package/typeahead/typeahead-template-render.js.map +1 -1
  177. package/typeahead/typeahead.d.ts +7 -0
  178. package/typeahead/typeahead.d.ts.map +1 -1
  179. package/typeahead/typeahead.js +7 -0
  180. package/typeahead/typeahead.js.map +1 -1
  181. package/vscode.html-custom-data.json +661 -230
@@ -1,5 +1,54 @@
1
- import { LitElement } from 'lit';
2
- export declare class UmDatepicker extends LitElement {
1
+ import { CSSResultGroup } from '@lit/reactive-element/css-tag';
2
+ import { HTMLTemplateResult } from 'lit';
3
+ import { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';
4
+ import { DatepickerFormat } from './format.js';
5
+ import '../calendar/calendar.js';
6
+ import '../menu/menu.js';
7
+ export declare class UmDatepicker extends UmNativeTextFieldWrapper {
8
+ #private;
9
+ static styles: CSSResultGroup;
10
+ /**
11
+ * The BCP 47 locale tag forwarded to the underlying calendar and used for
12
+ * non-editable display formatting.
13
+ * When `null`, the calendar falls back to the browser's `navigator.language`.
14
+ */
15
+ locale: string | null;
16
+ /**
17
+ * Format used when displaying the value while the field is not editable.
18
+ * Accepts the named presets `'short'`, `'medium'`, `'long'`, `'full'`,
19
+ * the literal `'iso'` (keeps the ISO `YYYY-MM-DD` value), or an
20
+ * `Intl.DateTimeFormatOptions` object for custom formatting.
21
+ * In editable mode the input uses the browser's native `type="date"` mask
22
+ * and ignores this property.
23
+ */
24
+ format: DatepickerFormat;
25
+ /**
26
+ * Whether the input accepts manually-typed dates. When `false` (default),
27
+ * the field is read-only and clicking anywhere opens the calendar popover.
28
+ * When `true`, the input uses native `type="date"` and accepts keyboard input;
29
+ * the calendar popover is opened via the trailing icon.
30
+ */
31
+ editable: boolean;
32
+ /**
33
+ * Whether the input is read-only. When set, manual typing is disabled even
34
+ * if `editable` is `true`; the calendar popover remains available.
35
+ */
36
+ readOnly: boolean;
37
+ /**
38
+ * The positioning strategy used by the calendar popover. Use `'fixed'`
39
+ * when the datepicker is rendered inside a clipped/scrollable container.
40
+ */
41
+ menuPositioning: 'relative' | 'fixed';
42
+ input: HTMLInputElement;
43
+ private _menu;
44
+ private _calendar;
45
+ private _trailingSlot;
46
+ protected renderControl(): HTMLTemplateResult;
47
+ protected renderDefaultTrailingIcon(): import("lit-html").TemplateResult<2>;
48
+ protected renderAfterContent(): import("lit-html").TemplateResult<1>;
49
+ connectedCallback(): void;
50
+ disconnectedCallback(): void;
51
+ protected _handleInput(): void;
3
52
  }
4
53
  declare global {
5
54
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"datepicker.d.ts","sourceRoot":"","sources":["../../src/datepicker/datepicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAGjC,qBACa,YAAa,SAAQ,UAAU;CAE3C;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,YAAY,CAAC;KAC9B;CACF"}
1
+ {"version":3,"file":"datepicker.d.ts","sourceRoot":"","sources":["../../src/datepicker/datepicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAQ,kBAAkB,EAAgB,MAAM,KAAK,CAAC;AAM7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8DAA8D,CAAC;AAKxG,OAAO,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAE9D,OAAO,yBAAyB,CAAC;AACjC,OAAO,iBAAiB,CAAC;AAIzB,qBACa,YAAa,SAAQ,wBAAwB;;IACxD,OAAgB,MAAM,EAAE,cAAc,CAAqD;IAE3F;;;;OAIG;IACS,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEzC;;;;;;;OAOG;IACS,MAAM,EAAE,gBAAgB,CAAW;IAE/C;;;;;OAKG;IACyC,QAAQ,UAAS;IAE7D;;;OAGG;IACyC,QAAQ,UAAS;IAE7D;;;OAGG;IACyD,eAAe,EAAE,UAAU,GAAG,OAAO,CAAc;IAE/F,KAAK,EAAG,gBAAgB,CAAC;IAClB,OAAO,CAAC,KAAK,CAAU;IACnB,OAAO,CAAC,SAAS,CAAc;IAC3B,OAAO,CAAC,aAAa,CAAmB;cAEpD,aAAa,IAAI,kBAAkB;cAmCnC,yBAAyB;cAOzB,kBAAkB;IAkB5B,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB,IAAI,IAAI;cAKlB,YAAY,IAAI,IAAI;CAmDxC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,YAAY,CAAC;KAC9B;CACF"}
@@ -1,8 +1,190 @@
1
1
  import { __decorate } from "tslib";
2
- import { LitElement } from 'lit';
3
- import { customElement } from 'lit/decorators.js';
4
- let UmDatepicker = class UmDatepicker extends LitElement {
2
+ import { html, nothing, svg } from 'lit';
3
+ import { customElement, property, query } from 'lit/decorators.js';
4
+ import { live } from 'lit/directives/live.js';
5
+ import { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';
6
+ import { UmTextFieldBase } from '../shared/text-field-base/text-field-base.js';
7
+ import { styles as textFieldStyles } from '../text-field/text-field.styles.js';
8
+ import { styles } from './datepicker.styles.js';
9
+ import { formatIsoDate } from './format.js';
10
+ import '../calendar/calendar.js';
11
+ import '../menu/menu.js';
12
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
13
+ let UmDatepicker = class UmDatepicker extends UmNativeTextFieldWrapper {
14
+ constructor() {
15
+ super(...arguments);
16
+ /**
17
+ * The BCP 47 locale tag forwarded to the underlying calendar and used for
18
+ * non-editable display formatting.
19
+ * When `null`, the calendar falls back to the browser's `navigator.language`.
20
+ */
21
+ this.locale = null;
22
+ /**
23
+ * Format used when displaying the value while the field is not editable.
24
+ * Accepts the named presets `'short'`, `'medium'`, `'long'`, `'full'`,
25
+ * the literal `'iso'` (keeps the ISO `YYYY-MM-DD` value), or an
26
+ * `Intl.DateTimeFormatOptions` object for custom formatting.
27
+ * In editable mode the input uses the browser's native `type="date"` mask
28
+ * and ignores this property.
29
+ */
30
+ this.format = 'short';
31
+ /**
32
+ * Whether the input accepts manually-typed dates. When `false` (default),
33
+ * the field is read-only and clicking anywhere opens the calendar popover.
34
+ * When `true`, the input uses native `type="date"` and accepts keyboard input;
35
+ * the calendar popover is opened via the trailing icon.
36
+ */
37
+ this.editable = false;
38
+ /**
39
+ * Whether the input is read-only. When set, manual typing is disabled even
40
+ * if `editable` is `true`; the calendar popover remains available.
41
+ */
42
+ this.readOnly = false;
43
+ /**
44
+ * The positioning strategy used by the calendar popover. Use `'fixed'`
45
+ * when the datepicker is rendered inside a clipped/scrollable container.
46
+ */
47
+ this.menuPositioning = 'relative';
48
+ this.#handleKeyDown = (e) => {
49
+ if (e.key === 'ArrowDown' && !this._menu.open) {
50
+ e.preventDefault();
51
+ this._menu.show();
52
+ return;
53
+ }
54
+ if (e.key === 'Escape' && this._menu.open) {
55
+ e.preventDefault();
56
+ this._menu.close();
57
+ return;
58
+ }
59
+ this._handleKeyDown(e);
60
+ };
61
+ this.#handleCalendarInput = (e) => {
62
+ e.stopPropagation();
63
+ const value = e.target.value;
64
+ this.value = value;
65
+ this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
66
+ this.dispatchEvent(new Event('change', { bubbles: true }));
67
+ this._menu.close();
68
+ };
69
+ this.#stopPropagation = (e) => {
70
+ e.stopPropagation();
71
+ };
72
+ this.#toggleMenu = () => {
73
+ if (this.disabled) {
74
+ return;
75
+ }
76
+ this._menu.toggle();
77
+ };
78
+ }
79
+ static { this.styles = [UmTextFieldBase.styles, textFieldStyles, styles]; }
80
+ renderControl() {
81
+ const displayValue = this.editable
82
+ ? this._value
83
+ : formatIsoDate(this._value, this.format, this.locale);
84
+ return html `
85
+ ${this.editable
86
+ ? nothing
87
+ : html `
88
+ <button
89
+ class="trigger"
90
+ type="button"
91
+ aria-haspopup="dialog"
92
+ ?disabled=${this.disabled}
93
+ @click=${this.#toggleMenu}></button>
94
+ `}
95
+ <div class="input">
96
+ <input
97
+ type=${this.editable ? 'date' : 'text'}
98
+ part="input"
99
+ id=${this.id || nothing}
100
+ aria-labelledby="label"
101
+ aria-describedby="supporting-text"
102
+ aria-haspopup="dialog"
103
+ tabindex=${this.editable ? nothing : -1}
104
+ ?readonly=${this.readOnly || !this.editable}
105
+ ?disabled=${this.disabled}
106
+ placeholder=${this.placeholder ?? nothing}
107
+ .value=${live(displayValue)}
108
+ @input=${this._handleInput}
109
+ @keydown=${this.#handleKeyDown} />
110
+ </div>
111
+ `;
112
+ }
113
+ renderDefaultTrailingIcon() {
114
+ return svg `
115
+ <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 -960 960 960" width="1.25em" fill="currentColor">
116
+ <path d="M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Z"/>
117
+ </svg>`;
118
+ }
119
+ renderAfterContent() {
120
+ return html `
121
+ <u-menu
122
+ positioning=${this.menuPositioning}
123
+ autoclose="outside"
124
+ anchor-corner="end-start"
125
+ direction="down-start"
126
+ allow-overflow
127
+ manualFocus
128
+ @click=${this.#stopPropagation}>
129
+ <u-calendar
130
+ .value=${this._value}
131
+ .locale=${this.locale}
132
+ @input=${this.#handleCalendarInput}></u-calendar>
133
+ </u-menu>
134
+ `;
135
+ }
136
+ connectedCallback() {
137
+ super.connectedCallback();
138
+ void this.#attach();
139
+ }
140
+ disconnectedCallback() {
141
+ super.disconnectedCallback();
142
+ this._trailingSlot?.removeEventListener('click', this.#toggleMenu);
143
+ }
144
+ _handleInput() {
145
+ super._handleInput();
146
+ if (ISO_DATE.test(this._value)) {
147
+ this._calendar.value = this._value;
148
+ }
149
+ this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
150
+ }
151
+ #handleKeyDown;
152
+ #handleCalendarInput;
153
+ #stopPropagation;
154
+ #toggleMenu;
155
+ async #attach() {
156
+ await this.updateComplete;
157
+ this._menu.anchorElement = this._container;
158
+ this._trailingSlot.addEventListener('click', this.#toggleMenu);
159
+ }
5
160
  };
161
+ __decorate([
162
+ property()
163
+ ], UmDatepicker.prototype, "locale", void 0);
164
+ __decorate([
165
+ property()
166
+ ], UmDatepicker.prototype, "format", void 0);
167
+ __decorate([
168
+ property({ type: Boolean, reflect: true })
169
+ ], UmDatepicker.prototype, "editable", void 0);
170
+ __decorate([
171
+ property({ type: Boolean, reflect: true })
172
+ ], UmDatepicker.prototype, "readOnly", void 0);
173
+ __decorate([
174
+ property({ reflect: true, attribute: 'menu-positioning' })
175
+ ], UmDatepicker.prototype, "menuPositioning", void 0);
176
+ __decorate([
177
+ query('input')
178
+ ], UmDatepicker.prototype, "input", void 0);
179
+ __decorate([
180
+ query('u-menu', true)
181
+ ], UmDatepicker.prototype, "_menu", void 0);
182
+ __decorate([
183
+ query('u-calendar', true)
184
+ ], UmDatepicker.prototype, "_calendar", void 0);
185
+ __decorate([
186
+ query('.trailing-icon', true)
187
+ ], UmDatepicker.prototype, "_trailingSlot", void 0);
6
188
  UmDatepicker = __decorate([
7
189
  customElement('u-datepicker')
8
190
  ], UmDatepicker);
@@ -1 +1 @@
1
- {"version":3,"file":"datepicker.js","sourceRoot":"","sources":["../../src/datepicker/datepicker.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG3C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;CAE3C,CAAA;AAFY,YAAY;IADxB,aAAa,CAAC,cAAc,CAAC;GACjB,YAAY,CAExB","sourcesContent":["import { LitElement } from 'lit';\nimport { customElement } from 'lit/decorators.js';\n\n@customElement('u-datepicker')\nexport class UmDatepicker extends LitElement {\n\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'u-datepicker': UmDatepicker;\n }\n}\n"]}
1
+ {"version":3,"file":"datepicker.js","sourceRoot":"","sources":["../../src/datepicker/datepicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { CSSResultGroup } from '@lit/reactive-element/css-tag';\n\nimport { html, HTMLTemplateResult, nothing, svg } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\n\nimport { UmCalendar } from '../calendar/calendar.js';\nimport { UmMenu } from '../menu/menu.js';\nimport { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';\nimport { UmTextFieldBase } from '../shared/text-field-base/text-field-base.js';\n\nimport { styles as textFieldStyles } from '../text-field/text-field.styles.js';\nimport { styles } from './datepicker.styles.js';\nimport { DatepickerFormat, formatIsoDate } from './format.js';\n\nimport '../calendar/calendar.js';\nimport '../menu/menu.js';\n\nconst ISO_DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n@customElement('u-datepicker')\nexport class UmDatepicker extends UmNativeTextFieldWrapper {\n static override styles: CSSResultGroup = [UmTextFieldBase.styles, textFieldStyles, styles];\n\n /**\n * The BCP 47 locale tag forwarded to the underlying calendar and used for\n * non-editable display formatting.\n * When `null`, the calendar falls back to the browser's `navigator.language`.\n */\n @property() locale: string | null = null;\n\n /**\n * Format used when displaying the value while the field is not editable.\n * Accepts the named presets `'short'`, `'medium'`, `'long'`, `'full'`,\n * the literal `'iso'` (keeps the ISO `YYYY-MM-DD` value), or an\n * `Intl.DateTimeFormatOptions` object for custom formatting.\n * In editable mode the input uses the browser's native `type=\"date\"` mask\n * and ignores this property.\n */\n @property() format: DatepickerFormat = 'short';\n\n /**\n * Whether the input accepts manually-typed dates. When `false` (default),\n * the field is read-only and clicking anywhere opens the calendar popover.\n * When `true`, the input uses native `type=\"date\"` and accepts keyboard input;\n * the calendar popover is opened via the trailing icon.\n */\n @property({ type: Boolean, reflect: true }) editable = false;\n\n /**\n * Whether the input is read-only. When set, manual typing is disabled even\n * if `editable` is `true`; the calendar popover remains available.\n */\n @property({ type: Boolean, reflect: true }) readOnly = false;\n\n /**\n * The positioning strategy used by the calendar popover. Use `'fixed'`\n * when the datepicker is rendered inside a clipped/scrollable container.\n */\n @property({ reflect: true, attribute: 'menu-positioning' }) menuPositioning: 'relative' | 'fixed' = 'relative';\n\n @query('input') input!: HTMLInputElement;\n @query('u-menu', true) private _menu!: UmMenu;\n @query('u-calendar', true) private _calendar!: UmCalendar;\n @query('.trailing-icon', true) private _trailingSlot!: HTMLSlotElement;\n\n protected override renderControl(): HTMLTemplateResult {\n const displayValue = this.editable\n ? this._value\n : formatIsoDate(this._value, this.format, this.locale);\n\n return html`\n ${this.editable\n ? nothing\n : html`\n <button\n class=\"trigger\"\n type=\"button\"\n aria-haspopup=\"dialog\"\n ?disabled=${this.disabled}\n @click=${this.#toggleMenu}></button>\n `}\n <div class=\"input\">\n <input\n type=${this.editable ? 'date' : 'text'}\n part=\"input\"\n id=${this.id || nothing}\n aria-labelledby=\"label\"\n aria-describedby=\"supporting-text\"\n aria-haspopup=\"dialog\"\n tabindex=${this.editable ? nothing : -1}\n ?readonly=${this.readOnly || !this.editable}\n ?disabled=${this.disabled}\n placeholder=${this.placeholder ?? nothing}\n .value=${live(displayValue)}\n @input=${this._handleInput}\n @keydown=${this.#handleKeyDown} />\n </div>\n `;\n }\n\n protected override renderDefaultTrailingIcon() {\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1.25em\" viewBox=\"0 -960 960 960\" width=\"1.25em\" fill=\"currentColor\">\n <path d=\"M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Z\"/>\n </svg>`;\n }\n\n protected override renderAfterContent() {\n return html`\n <u-menu\n positioning=${this.menuPositioning}\n autoclose=\"outside\"\n anchor-corner=\"end-start\"\n direction=\"down-start\"\n allow-overflow\n manualFocus\n @click=${this.#stopPropagation}>\n <u-calendar\n .value=${this._value}\n .locale=${this.locale}\n @input=${this.#handleCalendarInput}></u-calendar>\n </u-menu>\n `;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n void this.#attach();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._trailingSlot?.removeEventListener('click', this.#toggleMenu);\n }\n\n protected override _handleInput(): void {\n super._handleInput();\n\n if (ISO_DATE.test(this._value)) {\n this._calendar.value = this._value;\n }\n\n this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));\n }\n\n #handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'ArrowDown' && !this._menu.open) {\n e.preventDefault();\n this._menu.show();\n return;\n }\n\n if (e.key === 'Escape' && this._menu.open) {\n e.preventDefault();\n this._menu.close();\n return;\n }\n\n this._handleKeyDown(e);\n };\n\n #handleCalendarInput = (e: Event): void => {\n e.stopPropagation();\n const value = (e.target as UmCalendar).value;\n this.value = value;\n this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true }));\n this._menu.close();\n };\n\n #stopPropagation = (e: Event): void => {\n e.stopPropagation();\n };\n\n #toggleMenu = (): void => {\n if (this.disabled) {\n return;\n }\n this._menu.toggle();\n };\n\n async #attach(): Promise<void> {\n await this.updateComplete;\n this._menu.anchorElement = this._container;\n this._trailingSlot.addEventListener('click', this.#toggleMenu);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'u-datepicker': UmDatepicker;\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ export type DatepickerFormat = 'short' | 'medium' | 'long' | 'full' | 'iso' | Intl.DateTimeFormatOptions;
2
+ /**
3
+ * Parses an ISO `YYYY-MM-DD` string into a `Date` at local midnight,
4
+ * sidestepping the UTC-vs-local parsing ambiguity of the `Date` constructor
5
+ * when given a string.
6
+ */
7
+ export declare function parseIsoDate(iso: string): Date | null;
8
+ /**
9
+ * Formats an ISO date string (`YYYY-MM-DD`) for display, following the
10
+ * datepicker `format` property. Non-ISO inputs are passed through
11
+ * unchanged so partially-typed values aren't mangled.
12
+ */
13
+ export declare function formatIsoDate(value: string, format: DatepickerFormat, locale: string | null): string;
14
+ /**
15
+ * Formats a range value (`YYYY-MM-DD - YYYY-MM-DD`) by formatting each end
16
+ * with `formatIsoDate` and rejoining them with the same separator.
17
+ */
18
+ export declare function formatIsoDateRange(value: string, format: DatepickerFormat, locale: string | null): string;
19
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/datepicker/format.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,MAAM,GACN,KAAK,GACL,IAAI,CAAC,qBAAqB,CAAC;AAI/B;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAOrD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAgBR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAYR"}
@@ -0,0 +1,47 @@
1
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
2
+ /**
3
+ * Parses an ISO `YYYY-MM-DD` string into a `Date` at local midnight,
4
+ * sidestepping the UTC-vs-local parsing ambiguity of the `Date` constructor
5
+ * when given a string.
6
+ */
7
+ export function parseIsoDate(iso) {
8
+ if (!ISO_DATE.test(iso)) {
9
+ return null;
10
+ }
11
+ const [year, month, day] = iso.split('-').map(Number);
12
+ return new Date(year, month - 1, day);
13
+ }
14
+ /**
15
+ * Formats an ISO date string (`YYYY-MM-DD`) for display, following the
16
+ * datepicker `format` property. Non-ISO inputs are passed through
17
+ * unchanged so partially-typed values aren't mangled.
18
+ */
19
+ export function formatIsoDate(value, format, locale) {
20
+ if (!value || format === 'iso') {
21
+ return value;
22
+ }
23
+ const date = parseIsoDate(value);
24
+ if (!date) {
25
+ return value;
26
+ }
27
+ const options = typeof format === 'string'
28
+ ? { dateStyle: format }
29
+ : format;
30
+ return new Intl.DateTimeFormat(locale ?? undefined, options).format(date);
31
+ }
32
+ /**
33
+ * Formats a range value (`YYYY-MM-DD - YYYY-MM-DD`) by formatting each end
34
+ * with `formatIsoDate` and rejoining them with the same separator.
35
+ */
36
+ export function formatIsoDateRange(value, format, locale) {
37
+ if (!value || format === 'iso') {
38
+ return value;
39
+ }
40
+ const parts = value.split(' - ');
41
+ if (parts.length !== 2) {
42
+ return value;
43
+ }
44
+ const [start, end] = parts;
45
+ return `${formatIsoDate(start, format, locale)} - ${formatIsoDate(end, format, locale)}`;
46
+ }
47
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/datepicker/format.ts"],"names":[],"mappings":"AAQA,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AAEvC;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,MAAwB,EACxB,MAAqB;IAErB,IAAI,CAAC,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GACX,OAAO,MAAM,KAAK,QAAQ;QACxB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;QACvB,CAAC,CAAC,MAAM,CAAC;IAEb,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,MAAwB,EACxB,MAAqB;IAErB,IAAI,CAAC,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3B,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;AAC3F,CAAC","sourcesContent":["export type DatepickerFormat =\n | 'short'\n | 'medium'\n | 'long'\n | 'full'\n | 'iso'\n | Intl.DateTimeFormatOptions;\n\nconst ISO_DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Parses an ISO `YYYY-MM-DD` string into a `Date` at local midnight,\n * sidestepping the UTC-vs-local parsing ambiguity of the `Date` constructor\n * when given a string.\n */\nexport function parseIsoDate(iso: string): Date | null {\n if (!ISO_DATE.test(iso)) {\n return null;\n }\n\n const [year, month, day] = iso.split('-').map(Number);\n return new Date(year, month - 1, day);\n}\n\n/**\n * Formats an ISO date string (`YYYY-MM-DD`) for display, following the\n * datepicker `format` property. Non-ISO inputs are passed through\n * unchanged so partially-typed values aren't mangled.\n */\nexport function formatIsoDate(\n value: string,\n format: DatepickerFormat,\n locale: string | null,\n): string {\n if (!value || format === 'iso') {\n return value;\n }\n\n const date = parseIsoDate(value);\n if (!date) {\n return value;\n }\n\n const options: Intl.DateTimeFormatOptions =\n typeof format === 'string'\n ? { dateStyle: format }\n : format;\n\n return new Intl.DateTimeFormat(locale ?? undefined, options).format(date);\n}\n\n/**\n * Formats a range value (`YYYY-MM-DD - YYYY-MM-DD`) by formatting each end\n * with `formatIsoDate` and rejoining them with the same separator.\n */\nexport function formatIsoDateRange(\n value: string,\n format: DatepickerFormat,\n locale: string | null,\n): string {\n if (!value || format === 'iso') {\n return value;\n }\n\n const parts = value.split(' - ');\n if (parts.length !== 2) {\n return value;\n }\n\n const [start, end] = parts;\n return `${formatIsoDate(start, format, locale)} - ${formatIsoDate(end, format, locale)}`;\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import { CSSResultGroup } from '@lit/reactive-element/css-tag';
2
+ import { HTMLTemplateResult } from 'lit';
3
+ import { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';
4
+ import { DatepickerFormat } from './format.js';
5
+ import '../calendar/range-calendar.js';
6
+ import '../menu/menu.js';
7
+ export declare class UmRangeDatepicker extends UmNativeTextFieldWrapper {
8
+ #private;
9
+ static styles: CSSResultGroup;
10
+ /**
11
+ * The BCP 47 locale tag forwarded to the underlying range calendar and used
12
+ * for non-editable display formatting.
13
+ * When `null`, the calendar falls back to the browser's `navigator.language`.
14
+ */
15
+ locale: string | null;
16
+ /**
17
+ * Format used when displaying the value while the field is not editable.
18
+ * Accepts `'short'`, `'medium'`, `'long'`, `'full'`, `'iso'`, or an
19
+ * `Intl.DateTimeFormatOptions` object. Each end of the range is formatted
20
+ * independently and joined with ` - `.
21
+ */
22
+ format: DatepickerFormat;
23
+ /**
24
+ * Whether the input accepts manually-typed ranges. When `false` (default),
25
+ * the field is read-only and clicking anywhere opens the calendar popover.
26
+ * When `true`, the input accepts text in the `YYYY-MM-DD - YYYY-MM-DD` format;
27
+ * the calendar popover is opened via the trailing icon.
28
+ */
29
+ editable: boolean;
30
+ /**
31
+ * Whether the input is read-only. When set, manual typing is disabled even
32
+ * if `editable` is `true`; the calendar popover remains available.
33
+ */
34
+ readOnly: boolean;
35
+ /**
36
+ * The positioning strategy used by the calendar popover. Use `'fixed'`
37
+ * when the datepicker is rendered inside a clipped/scrollable container.
38
+ */
39
+ menuPositioning: 'relative' | 'fixed';
40
+ input: HTMLInputElement;
41
+ private _menu;
42
+ private _calendar;
43
+ private _trailingSlot;
44
+ protected renderControl(): HTMLTemplateResult;
45
+ protected renderDefaultTrailingIcon(): import("lit-html").TemplateResult<2>;
46
+ protected renderAfterContent(): import("lit-html").TemplateResult<1>;
47
+ connectedCallback(): void;
48
+ disconnectedCallback(): void;
49
+ protected _handleInput(): void;
50
+ }
51
+ declare global {
52
+ interface HTMLElementTagNameMap {
53
+ 'u-range-datepicker': UmRangeDatepicker;
54
+ }
55
+ }
56
+ //# sourceMappingURL=range-datepicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-datepicker.d.ts","sourceRoot":"","sources":["../../src/datepicker/range-datepicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAQ,kBAAkB,EAAgB,MAAM,KAAK,CAAC;AAM7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8DAA8D,CAAC;AAKxG,OAAO,EAAE,gBAAgB,EAAsB,MAAM,aAAa,CAAC;AAEnE,OAAO,+BAA+B,CAAC;AACvC,OAAO,iBAAiB,CAAC;AAIzB,qBACa,iBAAkB,SAAQ,wBAAwB;;IAC7D,OAAgB,MAAM,EAAE,cAAc,CAAqD;IAE3F;;;;OAIG;IACS,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEzC;;;;;OAKG;IACS,MAAM,EAAE,gBAAgB,CAAW;IAE/C;;;;;OAKG;IACyC,QAAQ,UAAS;IAE7D;;;OAGG;IACyC,QAAQ,UAAS;IAE7D;;;OAGG;IACyD,eAAe,EAAE,UAAU,GAAG,OAAO,CAAc;IAE/F,KAAK,EAAG,gBAAgB,CAAC;IAClB,OAAO,CAAC,KAAK,CAAU;IACb,OAAO,CAAC,SAAS,CAAmB;IACtC,OAAO,CAAC,aAAa,CAAmB;cAEpD,aAAa,IAAI,kBAAkB;cAmCnC,yBAAyB;cAOzB,kBAAkB;IAmB5B,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB,IAAI,IAAI;cAKlB,YAAY,IAAI,IAAI;CA4DxC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,oBAAoB,EAAE,iBAAiB,CAAC;KACzC;CACF"}
@@ -0,0 +1,198 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, nothing, svg } from 'lit';
3
+ import { customElement, property, query } from 'lit/decorators.js';
4
+ import { live } from 'lit/directives/live.js';
5
+ import { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';
6
+ import { UmTextFieldBase } from '../shared/text-field-base/text-field-base.js';
7
+ import { styles as textFieldStyles } from '../text-field/text-field.styles.js';
8
+ import { styles } from './datepicker.styles.js';
9
+ import { formatIsoDateRange } from './format.js';
10
+ import '../calendar/range-calendar.js';
11
+ import '../menu/menu.js';
12
+ const ISO_DATE_RANGE = /^\d{4}-\d{2}-\d{2} - \d{4}-\d{2}-\d{2}$/;
13
+ let UmRangeDatepicker = class UmRangeDatepicker extends UmNativeTextFieldWrapper {
14
+ constructor() {
15
+ super(...arguments);
16
+ /**
17
+ * The BCP 47 locale tag forwarded to the underlying range calendar and used
18
+ * for non-editable display formatting.
19
+ * When `null`, the calendar falls back to the browser's `navigator.language`.
20
+ */
21
+ this.locale = null;
22
+ /**
23
+ * Format used when displaying the value while the field is not editable.
24
+ * Accepts `'short'`, `'medium'`, `'long'`, `'full'`, `'iso'`, or an
25
+ * `Intl.DateTimeFormatOptions` object. Each end of the range is formatted
26
+ * independently and joined with ` - `.
27
+ */
28
+ this.format = 'short';
29
+ /**
30
+ * Whether the input accepts manually-typed ranges. When `false` (default),
31
+ * the field is read-only and clicking anywhere opens the calendar popover.
32
+ * When `true`, the input accepts text in the `YYYY-MM-DD - YYYY-MM-DD` format;
33
+ * the calendar popover is opened via the trailing icon.
34
+ */
35
+ this.editable = false;
36
+ /**
37
+ * Whether the input is read-only. When set, manual typing is disabled even
38
+ * if `editable` is `true`; the calendar popover remains available.
39
+ */
40
+ this.readOnly = false;
41
+ /**
42
+ * The positioning strategy used by the calendar popover. Use `'fixed'`
43
+ * when the datepicker is rendered inside a clipped/scrollable container.
44
+ */
45
+ this.menuPositioning = 'relative';
46
+ this.#handleKeyDown = (e) => {
47
+ if (e.key === 'ArrowDown' && !this._menu.open) {
48
+ e.preventDefault();
49
+ this._menu.show();
50
+ return;
51
+ }
52
+ if (e.key === 'Escape' && this._menu.open) {
53
+ e.preventDefault();
54
+ this._menu.close();
55
+ return;
56
+ }
57
+ this._handleKeyDown(e);
58
+ };
59
+ this.#handleCalendarInput = (e) => {
60
+ e.stopPropagation();
61
+ const value = e.target.value ?? '';
62
+ this.value = value;
63
+ this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
64
+ };
65
+ this.#handleCalendarChange = (e) => {
66
+ e.stopPropagation();
67
+ if (!ISO_DATE_RANGE.test(this._value)) {
68
+ return;
69
+ }
70
+ this.dispatchEvent(new Event('change', { bubbles: true }));
71
+ this._menu.close();
72
+ };
73
+ this.#stopPropagation = (e) => {
74
+ e.stopPropagation();
75
+ };
76
+ this.#toggleMenu = () => {
77
+ if (this.disabled) {
78
+ return;
79
+ }
80
+ this._menu.toggle();
81
+ };
82
+ }
83
+ static { this.styles = [UmTextFieldBase.styles, textFieldStyles, styles]; }
84
+ renderControl() {
85
+ const displayValue = this.editable
86
+ ? this._value
87
+ : formatIsoDateRange(this._value, this.format, this.locale);
88
+ return html `
89
+ ${this.editable
90
+ ? nothing
91
+ : html `
92
+ <button
93
+ class="trigger"
94
+ type="button"
95
+ aria-haspopup="dialog"
96
+ ?disabled=${this.disabled}
97
+ @click=${this.#toggleMenu}></button>
98
+ `}
99
+ <div class="input">
100
+ <input
101
+ type="text"
102
+ part="input"
103
+ id=${this.id || nothing}
104
+ aria-labelledby="label"
105
+ aria-describedby="supporting-text"
106
+ aria-haspopup="dialog"
107
+ tabindex=${this.editable ? nothing : -1}
108
+ ?readonly=${this.readOnly || !this.editable}
109
+ ?disabled=${this.disabled}
110
+ placeholder=${this.placeholder ?? nothing}
111
+ .value=${live(displayValue)}
112
+ @input=${this._handleInput}
113
+ @keydown=${this.#handleKeyDown} />
114
+ </div>
115
+ `;
116
+ }
117
+ renderDefaultTrailingIcon() {
118
+ return svg `
119
+ <svg xmlns="http://www.w3.org/2000/svg" height="1.25em" viewBox="0 -960 960 960" width="1.25em" fill="currentColor">
120
+ <path d="M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Z"/>
121
+ </svg>`;
122
+ }
123
+ renderAfterContent() {
124
+ return html `
125
+ <u-menu
126
+ positioning=${this.menuPositioning}
127
+ autoclose="outside"
128
+ anchor-corner="end-start"
129
+ direction="down-start"
130
+ allow-overflow
131
+ manualFocus
132
+ @click=${this.#stopPropagation}>
133
+ <u-range-calendar
134
+ .value=${this._value}
135
+ .locale=${this.locale}
136
+ @input=${this.#handleCalendarInput}
137
+ @change=${this.#handleCalendarChange}></u-range-calendar>
138
+ </u-menu>
139
+ `;
140
+ }
141
+ connectedCallback() {
142
+ super.connectedCallback();
143
+ void this.#attach();
144
+ }
145
+ disconnectedCallback() {
146
+ super.disconnectedCallback();
147
+ this._trailingSlot?.removeEventListener('click', this.#toggleMenu);
148
+ }
149
+ _handleInput() {
150
+ super._handleInput();
151
+ if (ISO_DATE_RANGE.test(this._value)) {
152
+ this._calendar.value = this._value;
153
+ }
154
+ this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
155
+ }
156
+ #handleKeyDown;
157
+ #handleCalendarInput;
158
+ #handleCalendarChange;
159
+ #stopPropagation;
160
+ #toggleMenu;
161
+ async #attach() {
162
+ await this.updateComplete;
163
+ this._menu.anchorElement = this._container;
164
+ this._trailingSlot.addEventListener('click', this.#toggleMenu);
165
+ }
166
+ };
167
+ __decorate([
168
+ property()
169
+ ], UmRangeDatepicker.prototype, "locale", void 0);
170
+ __decorate([
171
+ property()
172
+ ], UmRangeDatepicker.prototype, "format", void 0);
173
+ __decorate([
174
+ property({ type: Boolean, reflect: true })
175
+ ], UmRangeDatepicker.prototype, "editable", void 0);
176
+ __decorate([
177
+ property({ type: Boolean, reflect: true })
178
+ ], UmRangeDatepicker.prototype, "readOnly", void 0);
179
+ __decorate([
180
+ property({ reflect: true, attribute: 'menu-positioning' })
181
+ ], UmRangeDatepicker.prototype, "menuPositioning", void 0);
182
+ __decorate([
183
+ query('input')
184
+ ], UmRangeDatepicker.prototype, "input", void 0);
185
+ __decorate([
186
+ query('u-menu', true)
187
+ ], UmRangeDatepicker.prototype, "_menu", void 0);
188
+ __decorate([
189
+ query('u-range-calendar', true)
190
+ ], UmRangeDatepicker.prototype, "_calendar", void 0);
191
+ __decorate([
192
+ query('.trailing-icon', true)
193
+ ], UmRangeDatepicker.prototype, "_trailingSlot", void 0);
194
+ UmRangeDatepicker = __decorate([
195
+ customElement('u-range-datepicker')
196
+ ], UmRangeDatepicker);
197
+ export { UmRangeDatepicker };
198
+ //# sourceMappingURL=range-datepicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-datepicker.js","sourceRoot":"","sources":["../../src/datepicker/range-datepicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { CSSResultGroup } from '@lit/reactive-element/css-tag';\n\nimport { html, HTMLTemplateResult, nothing, svg } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\n\nimport { UmRangeCalendar } from '../calendar/range-calendar.js';\nimport { UmMenu } from '../menu/menu.js';\nimport { UmNativeTextFieldWrapper } from '../shared/char-count-text-field/native-text-field-wrapper.js';\nimport { UmTextFieldBase } from '../shared/text-field-base/text-field-base.js';\n\nimport { styles as textFieldStyles } from '../text-field/text-field.styles.js';\nimport { styles } from './datepicker.styles.js';\nimport { DatepickerFormat, formatIsoDateRange } from './format.js';\n\nimport '../calendar/range-calendar.js';\nimport '../menu/menu.js';\n\nconst ISO_DATE_RANGE = /^\\d{4}-\\d{2}-\\d{2} - \\d{4}-\\d{2}-\\d{2}$/;\n\n@customElement('u-range-datepicker')\nexport class UmRangeDatepicker extends UmNativeTextFieldWrapper {\n static override styles: CSSResultGroup = [UmTextFieldBase.styles, textFieldStyles, styles];\n\n /**\n * The BCP 47 locale tag forwarded to the underlying range calendar and used\n * for non-editable display formatting.\n * When `null`, the calendar falls back to the browser's `navigator.language`.\n */\n @property() locale: string | null = null;\n\n /**\n * Format used when displaying the value while the field is not editable.\n * Accepts `'short'`, `'medium'`, `'long'`, `'full'`, `'iso'`, or an\n * `Intl.DateTimeFormatOptions` object. Each end of the range is formatted\n * independently and joined with ` - `.\n */\n @property() format: DatepickerFormat = 'short';\n\n /**\n * Whether the input accepts manually-typed ranges. When `false` (default),\n * the field is read-only and clicking anywhere opens the calendar popover.\n * When `true`, the input accepts text in the `YYYY-MM-DD - YYYY-MM-DD` format;\n * the calendar popover is opened via the trailing icon.\n */\n @property({ type: Boolean, reflect: true }) editable = false;\n\n /**\n * Whether the input is read-only. When set, manual typing is disabled even\n * if `editable` is `true`; the calendar popover remains available.\n */\n @property({ type: Boolean, reflect: true }) readOnly = false;\n\n /**\n * The positioning strategy used by the calendar popover. Use `'fixed'`\n * when the datepicker is rendered inside a clipped/scrollable container.\n */\n @property({ reflect: true, attribute: 'menu-positioning' }) menuPositioning: 'relative' | 'fixed' = 'relative';\n\n @query('input') input!: HTMLInputElement;\n @query('u-menu', true) private _menu!: UmMenu;\n @query('u-range-calendar', true) private _calendar!: UmRangeCalendar;\n @query('.trailing-icon', true) private _trailingSlot!: HTMLSlotElement;\n\n protected override renderControl(): HTMLTemplateResult {\n const displayValue = this.editable\n ? this._value\n : formatIsoDateRange(this._value, this.format, this.locale);\n\n return html`\n ${this.editable\n ? nothing\n : html`\n <button\n class=\"trigger\"\n type=\"button\"\n aria-haspopup=\"dialog\"\n ?disabled=${this.disabled}\n @click=${this.#toggleMenu}></button>\n `}\n <div class=\"input\">\n <input\n type=\"text\"\n part=\"input\"\n id=${this.id || nothing}\n aria-labelledby=\"label\"\n aria-describedby=\"supporting-text\"\n aria-haspopup=\"dialog\"\n tabindex=${this.editable ? nothing : -1}\n ?readonly=${this.readOnly || !this.editable}\n ?disabled=${this.disabled}\n placeholder=${this.placeholder ?? nothing}\n .value=${live(displayValue)}\n @input=${this._handleInput}\n @keydown=${this.#handleKeyDown} />\n </div>\n `;\n }\n\n protected override renderDefaultTrailingIcon() {\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1.25em\" viewBox=\"0 -960 960 960\" width=\"1.25em\" fill=\"currentColor\">\n <path d=\"M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Z\"/>\n </svg>`;\n }\n\n protected override renderAfterContent() {\n return html`\n <u-menu\n positioning=${this.menuPositioning}\n autoclose=\"outside\"\n anchor-corner=\"end-start\"\n direction=\"down-start\"\n allow-overflow\n manualFocus\n @click=${this.#stopPropagation}>\n <u-range-calendar\n .value=${this._value}\n .locale=${this.locale}\n @input=${this.#handleCalendarInput}\n @change=${this.#handleCalendarChange}></u-range-calendar>\n </u-menu>\n `;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n void this.#attach();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._trailingSlot?.removeEventListener('click', this.#toggleMenu);\n }\n\n protected override _handleInput(): void {\n super._handleInput();\n\n if (ISO_DATE_RANGE.test(this._value)) {\n this._calendar.value = this._value;\n }\n\n this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));\n }\n\n #handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'ArrowDown' && !this._menu.open) {\n e.preventDefault();\n this._menu.show();\n return;\n }\n\n if (e.key === 'Escape' && this._menu.open) {\n e.preventDefault();\n this._menu.close();\n return;\n }\n\n this._handleKeyDown(e);\n };\n\n #handleCalendarInput = (e: Event): void => {\n e.stopPropagation();\n const value = (e.target as UmRangeCalendar).value ?? '';\n this.value = value;\n this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));\n };\n\n #handleCalendarChange = (e: Event): void => {\n e.stopPropagation();\n\n if (!ISO_DATE_RANGE.test(this._value)) {\n return;\n }\n\n this.dispatchEvent(new Event('change', { bubbles: true }));\n this._menu.close();\n };\n\n #stopPropagation = (e: Event): void => {\n e.stopPropagation();\n };\n\n #toggleMenu = (): void => {\n if (this.disabled) {\n return;\n }\n this._menu.toggle();\n };\n\n async #attach(): Promise<void> {\n await this.updateComplete;\n this._menu.anchorElement = this._container;\n this._trailingSlot.addEventListener('click', this.#toggleMenu);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'u-range-datepicker': UmRangeDatepicker;\n }\n}\n"]}