@api-client/ui 0.5.5 → 0.5.7

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 (114) hide show
  1. package/.cursor/rules/html-and-css-best-practices.mdc +63 -0
  2. package/.cursor/rules/lit-best-practices.mdc +78 -0
  3. package/.github/instructions/html-and-css-best-practices.instructions.md +70 -0
  4. package/.github/instructions/lit-best-practices.instructions.md +86 -0
  5. package/build/src/elements/currency/currency-picker.d.ts +10 -0
  6. package/build/src/elements/currency/currency-picker.d.ts.map +1 -0
  7. package/build/src/elements/currency/currency-picker.js +27 -0
  8. package/build/src/elements/currency/currency-picker.js.map +1 -0
  9. package/build/src/elements/currency/internals/Picker.d.ts +311 -0
  10. package/build/src/elements/currency/internals/Picker.d.ts.map +1 -0
  11. package/build/src/elements/currency/internals/Picker.js +857 -0
  12. package/build/src/elements/currency/internals/Picker.js.map +1 -0
  13. package/build/src/elements/currency/internals/Picker.styles.d.ts +3 -0
  14. package/build/src/elements/currency/internals/Picker.styles.d.ts.map +1 -0
  15. package/build/src/elements/currency/internals/Picker.styles.js +58 -0
  16. package/build/src/elements/currency/internals/Picker.styles.js.map +1 -0
  17. package/build/src/elements/highlight/MarkdownStyles.d.ts.map +1 -1
  18. package/build/src/elements/highlight/MarkdownStyles.js +0 -13
  19. package/build/src/elements/highlight/MarkdownStyles.js.map +1 -1
  20. package/build/src/elements/http/BodyEditor.d.ts +0 -13
  21. package/build/src/elements/http/BodyEditor.d.ts.map +1 -1
  22. package/build/src/elements/http/BodyEditor.js +0 -13
  23. package/build/src/elements/http/BodyEditor.js.map +1 -1
  24. package/build/src/elements/http/BodyTextEditor.d.ts +0 -13
  25. package/build/src/elements/http/BodyTextEditor.d.ts.map +1 -1
  26. package/build/src/elements/http/BodyTextEditor.js +0 -13
  27. package/build/src/elements/http/BodyTextEditor.js.map +1 -1
  28. package/build/src/elements/http/BodyUrlEncodedEditor.d.ts +0 -13
  29. package/build/src/elements/http/BodyUrlEncodedEditor.d.ts.map +1 -1
  30. package/build/src/elements/http/BodyUrlEncodedEditor.js +0 -13
  31. package/build/src/elements/http/BodyUrlEncodedEditor.js.map +1 -1
  32. package/build/src/elements/http/UrlInput.d.ts +0 -13
  33. package/build/src/elements/http/UrlInput.d.ts.map +1 -1
  34. package/build/src/elements/http/UrlInput.js +0 -13
  35. package/build/src/elements/http/UrlInput.js.map +1 -1
  36. package/build/src/index.d.ts +2 -0
  37. package/build/src/index.d.ts.map +1 -1
  38. package/build/src/index.js +2 -0
  39. package/build/src/index.js.map +1 -1
  40. package/build/src/md/button/internals/base.d.ts +1 -0
  41. package/build/src/md/button/internals/base.d.ts.map +1 -1
  42. package/build/src/md/button/internals/base.js +7 -0
  43. package/build/src/md/button/internals/base.js.map +1 -1
  44. package/build/src/md/button/internals/button.styles.js +1 -1
  45. package/build/src/md/button/internals/button.styles.js.map +1 -1
  46. package/build/src/md/date/internals/DateTime.d.ts +0 -13
  47. package/build/src/md/date/internals/DateTime.d.ts.map +1 -1
  48. package/build/src/md/date/internals/DateTime.js +0 -13
  49. package/build/src/md/date/internals/DateTime.js.map +1 -1
  50. package/build/src/md/date-picker/index.d.ts +13 -0
  51. package/build/src/md/date-picker/index.d.ts.map +1 -0
  52. package/build/src/md/date-picker/index.js +13 -0
  53. package/build/src/md/date-picker/index.js.map +1 -0
  54. package/build/src/md/date-picker/internals/DatePicker.styles.d.ts +4 -0
  55. package/build/src/md/date-picker/internals/DatePicker.styles.d.ts.map +1 -0
  56. package/build/src/md/date-picker/internals/DatePicker.styles.js +409 -0
  57. package/build/src/md/date-picker/internals/DatePicker.styles.js.map +1 -0
  58. package/build/src/md/date-picker/internals/DatePickerCalendar.d.ts +272 -0
  59. package/build/src/md/date-picker/internals/DatePickerCalendar.d.ts.map +1 -0
  60. package/build/src/md/date-picker/internals/DatePickerCalendar.js +1062 -0
  61. package/build/src/md/date-picker/internals/DatePickerCalendar.js.map +1 -0
  62. package/build/src/md/date-picker/internals/DatePickerUtils.d.ts +93 -0
  63. package/build/src/md/date-picker/internals/DatePickerUtils.d.ts.map +1 -0
  64. package/build/src/md/date-picker/internals/DatePickerUtils.js +221 -0
  65. package/build/src/md/date-picker/internals/DatePickerUtils.js.map +1 -0
  66. package/build/src/md/date-picker/ui-date-picker-input.d.ts +160 -0
  67. package/build/src/md/date-picker/ui-date-picker-input.d.ts.map +1 -0
  68. package/build/src/md/date-picker/ui-date-picker-input.js +464 -0
  69. package/build/src/md/date-picker/ui-date-picker-input.js.map +1 -0
  70. package/build/src/md/date-picker/ui-date-picker-modal-input.d.ts +178 -0
  71. package/build/src/md/date-picker/ui-date-picker-modal-input.d.ts.map +1 -0
  72. package/build/src/md/date-picker/ui-date-picker-modal-input.js +538 -0
  73. package/build/src/md/date-picker/ui-date-picker-modal-input.js.map +1 -0
  74. package/build/src/md/date-picker/ui-date-picker-modal.d.ts +156 -0
  75. package/build/src/md/date-picker/ui-date-picker-modal.d.ts.map +1 -0
  76. package/build/src/md/date-picker/ui-date-picker-modal.js +423 -0
  77. package/build/src/md/date-picker/ui-date-picker-modal.js.map +1 -0
  78. package/build/src/md/dialog/internals/Dialog.styles.d.ts.map +1 -1
  79. package/build/src/md/dialog/internals/Dialog.styles.js +1 -0
  80. package/build/src/md/dialog/internals/Dialog.styles.js.map +1 -1
  81. package/demo/elements/currency/index.html +91 -0
  82. package/demo/elements/currency/index.ts +272 -0
  83. package/demo/elements/har/har2.json +1 -1
  84. package/demo/elements/index.html +3 -0
  85. package/demo/md/date-picker/date-picker.ts +336 -0
  86. package/demo/md/date-picker/index.html +171 -0
  87. package/demo/md/index.html +2 -0
  88. package/package.json +1 -1
  89. package/src/elements/currency/currency-picker.ts +14 -0
  90. package/src/elements/currency/internals/Picker.styles.ts +58 -0
  91. package/src/elements/currency/internals/Picker.ts +846 -0
  92. package/src/elements/highlight/MarkdownStyles.ts +0 -13
  93. package/src/elements/http/BodyEditor.ts +0 -13
  94. package/src/elements/http/BodyTextEditor.ts +0 -13
  95. package/src/elements/http/BodyUrlEncodedEditor.ts +0 -13
  96. package/src/elements/http/UrlInput.ts +0 -13
  97. package/src/index.ts +17 -0
  98. package/src/md/button/internals/base.ts +7 -0
  99. package/src/md/button/internals/button.styles.ts +1 -1
  100. package/src/md/date/internals/DateTime.ts +0 -14
  101. package/src/md/date-picker/README.md +184 -0
  102. package/src/md/date-picker/index.ts +17 -0
  103. package/src/md/date-picker/internals/DatePicker.styles.ts +411 -0
  104. package/src/md/date-picker/internals/DatePickerCalendar.ts +1031 -0
  105. package/src/md/date-picker/internals/DatePickerUtils.ts +288 -0
  106. package/src/md/date-picker/ui-date-picker-input.ts +333 -0
  107. package/src/md/date-picker/ui-date-picker-modal-input.ts +440 -0
  108. package/src/md/date-picker/ui-date-picker-modal.ts +346 -0
  109. package/src/md/dialog/internals/Dialog.styles.ts +1 -0
  110. package/test/README.md +3 -2
  111. package/test/elements/currency/CurrencyPicker.accessibility.test.ts +328 -0
  112. package/test/elements/currency/CurrencyPicker.core.test.ts +318 -0
  113. package/test/elements/currency/CurrencyPicker.integration.test.ts +482 -0
  114. package/test/elements/currency/CurrencyPicker.test.ts +486 -0
@@ -0,0 +1,1062 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { LitElement, html, nothing } from 'lit';
3
+ import { customElement, property, state } from 'lit/decorators.js';
4
+ import { classMap } from 'lit/directives/class-map.js';
5
+ import { calendarStyles } from './DatePicker.styles.js';
6
+ import { generateCalendarMonth, addMonths, getMonthNames, isSameDay, formatDate, addDays, } from './DatePickerUtils.js';
7
+ import '../../../md/icons/ui-icon.js';
8
+ import '../../../md/button/ui-button.js';
9
+ import '../../../md/icon-button/ui-icon-button.js';
10
+ /**
11
+ * A calendar grid component for date selection.
12
+ * Supports single date selection and date range selection with full keyboard navigation.
13
+ *
14
+ * ## Features
15
+ * - Single date and date range selection
16
+ * - Keyboard navigation support (arrow keys, home, end, page up/down)
17
+ * - Configurable date restrictions (min/max dates, disabled dates)
18
+ * - Localization support for date formatting and month/day names
19
+ * - Optional action buttons for pending selections
20
+ * - Accessible design with proper ARIA attributes
21
+ *
22
+ * ## Events
23
+ * - `date-select`: Fired when a single date is selected/confirmed
24
+ * - `date-range-select`: Fired when a date range is completed (immediate mode)
25
+ * - `date-range-confirm`: Fired when a date range is confirmed (pending mode)
26
+ * - `date-cancel`: Fired when a pending selection is cancelled
27
+ *
28
+ * ## Usage
29
+ *
30
+ * ```html
31
+ * <ui-date-picker-calendar></ui-date-picker-calendar>
32
+ * ```
33
+ *
34
+ * ### Single date selection
35
+ * ```html
36
+ * <ui-date-picker-calendar
37
+ * .selectedDate=${new Date()}
38
+ * @date-select=${this.handleDateSelect}
39
+ * ></ui-date-picker-calendar>
40
+ * ```
41
+ *
42
+ * ### Date range selection
43
+ * ```html
44
+ * <ui-date-picker-calendar
45
+ * rangeSelection
46
+ * .rangeStart=${new Date()}
47
+ * .rangeEnd=${null}
48
+ * @date-range-select=${this.handleRangeSelect}
49
+ * ></ui-date-picker-calendar>
50
+ * ```
51
+ *
52
+ * ### With action buttons and restrictions
53
+ * ```html
54
+ * <ui-date-picker-calendar
55
+ * rangeSelection
56
+ * showActions
57
+ * .minDate=${new Date()}
58
+ * .maxDate=${new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)}
59
+ * @date-range-confirm=${this.handleRangeConfirm}
60
+ * @date-cancel=${this.handleCancel}
61
+ * ></ui-date-picker-calendar>
62
+ * ```
63
+ */
64
+ let UiDatePickerCalendar = (() => {
65
+ let _classDecorators = [customElement('ui-date-picker-calendar')];
66
+ let _classDescriptor;
67
+ let _classExtraInitializers = [];
68
+ let _classThis;
69
+ let _classSuper = LitElement;
70
+ let _year_decorators;
71
+ let _year_initializers = [];
72
+ let _year_extraInitializers = [];
73
+ let _month_decorators;
74
+ let _month_initializers = [];
75
+ let _month_extraInitializers = [];
76
+ let _selectedDate_decorators;
77
+ let _selectedDate_initializers = [];
78
+ let _selectedDate_extraInitializers = [];
79
+ let _rangeStart_decorators;
80
+ let _rangeStart_initializers = [];
81
+ let _rangeStart_extraInitializers = [];
82
+ let _rangeEnd_decorators;
83
+ let _rangeEnd_initializers = [];
84
+ let _rangeEnd_extraInitializers = [];
85
+ let _rangeSelection_decorators;
86
+ let _rangeSelection_initializers = [];
87
+ let _rangeSelection_extraInitializers = [];
88
+ let _minDate_decorators;
89
+ let _minDate_initializers = [];
90
+ let _minDate_extraInitializers = [];
91
+ let _maxDate_decorators;
92
+ let _maxDate_initializers = [];
93
+ let _maxDate_extraInitializers = [];
94
+ let _disabledDates_decorators;
95
+ let _disabledDates_initializers = [];
96
+ let _disabledDates_extraInitializers = [];
97
+ let _locale_decorators;
98
+ let _locale_initializers = [];
99
+ let _locale_extraInitializers = [];
100
+ let _showNavigation_decorators;
101
+ let _showNavigation_initializers = [];
102
+ let _showNavigation_extraInitializers = [];
103
+ let _showActions_decorators;
104
+ let _showActions_initializers = [];
105
+ let _showActions_extraInitializers = [];
106
+ let _okButtonText_decorators;
107
+ let _okButtonText_initializers = [];
108
+ let _okButtonText_extraInitializers = [];
109
+ let _cancelButtonText_decorators;
110
+ let _cancelButtonText_initializers = [];
111
+ let _cancelButtonText_extraInitializers = [];
112
+ let _calendarData_decorators;
113
+ let _calendarData_initializers = [];
114
+ let _calendarData_extraInitializers = [];
115
+ let _monthNames_decorators;
116
+ let _monthNames_initializers = [];
117
+ let _monthNames_extraInitializers = [];
118
+ let _showMonthDropdown_decorators;
119
+ let _showMonthDropdown_initializers = [];
120
+ let _showMonthDropdown_extraInitializers = [];
121
+ let _showYearDropdown_decorators;
122
+ let _showYearDropdown_initializers = [];
123
+ let _showYearDropdown_extraInitializers = [];
124
+ let _pendingDate_decorators;
125
+ let _pendingDate_initializers = [];
126
+ let _pendingDate_extraInitializers = [];
127
+ let _pendingRangeStart_decorators;
128
+ let _pendingRangeStart_initializers = [];
129
+ let _pendingRangeStart_extraInitializers = [];
130
+ let _pendingRangeEnd_decorators;
131
+ let _pendingRangeEnd_initializers = [];
132
+ let _pendingRangeEnd_extraInitializers = [];
133
+ let _focusedDate_decorators;
134
+ let _focusedDate_initializers = [];
135
+ let _focusedDate_extraInitializers = [];
136
+ var UiDatePickerCalendar = class extends _classSuper {
137
+ static { _classThis = this; }
138
+ static {
139
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
140
+ _year_decorators = [property({ type: Number })];
141
+ _month_decorators = [property({ type: Number })];
142
+ _selectedDate_decorators = [property({ type: Object })];
143
+ _rangeStart_decorators = [property({ type: Object })];
144
+ _rangeEnd_decorators = [property({ type: Object })];
145
+ _rangeSelection_decorators = [property({ type: Boolean })];
146
+ _minDate_decorators = [property({ type: Object })];
147
+ _maxDate_decorators = [property({ type: Object })];
148
+ _disabledDates_decorators = [property({ type: Array })];
149
+ _locale_decorators = [property({ type: String })];
150
+ _showNavigation_decorators = [property({ type: Boolean })];
151
+ _showActions_decorators = [property({ type: Boolean })];
152
+ _okButtonText_decorators = [property({ type: String })];
153
+ _cancelButtonText_decorators = [property({ type: String })];
154
+ _calendarData_decorators = [state()];
155
+ _monthNames_decorators = [state()];
156
+ _showMonthDropdown_decorators = [state()];
157
+ _showYearDropdown_decorators = [state()];
158
+ _pendingDate_decorators = [state()];
159
+ _pendingRangeStart_decorators = [state()];
160
+ _pendingRangeEnd_decorators = [state()];
161
+ _focusedDate_decorators = [state()];
162
+ __esDecorate(this, null, _year_decorators, { kind: "accessor", name: "year", static: false, private: false, access: { has: obj => "year" in obj, get: obj => obj.year, set: (obj, value) => { obj.year = value; } }, metadata: _metadata }, _year_initializers, _year_extraInitializers);
163
+ __esDecorate(this, null, _month_decorators, { kind: "accessor", name: "month", static: false, private: false, access: { has: obj => "month" in obj, get: obj => obj.month, set: (obj, value) => { obj.month = value; } }, metadata: _metadata }, _month_initializers, _month_extraInitializers);
164
+ __esDecorate(this, null, _selectedDate_decorators, { kind: "accessor", name: "selectedDate", static: false, private: false, access: { has: obj => "selectedDate" in obj, get: obj => obj.selectedDate, set: (obj, value) => { obj.selectedDate = value; } }, metadata: _metadata }, _selectedDate_initializers, _selectedDate_extraInitializers);
165
+ __esDecorate(this, null, _rangeStart_decorators, { kind: "accessor", name: "rangeStart", static: false, private: false, access: { has: obj => "rangeStart" in obj, get: obj => obj.rangeStart, set: (obj, value) => { obj.rangeStart = value; } }, metadata: _metadata }, _rangeStart_initializers, _rangeStart_extraInitializers);
166
+ __esDecorate(this, null, _rangeEnd_decorators, { kind: "accessor", name: "rangeEnd", static: false, private: false, access: { has: obj => "rangeEnd" in obj, get: obj => obj.rangeEnd, set: (obj, value) => { obj.rangeEnd = value; } }, metadata: _metadata }, _rangeEnd_initializers, _rangeEnd_extraInitializers);
167
+ __esDecorate(this, null, _rangeSelection_decorators, { kind: "accessor", name: "rangeSelection", static: false, private: false, access: { has: obj => "rangeSelection" in obj, get: obj => obj.rangeSelection, set: (obj, value) => { obj.rangeSelection = value; } }, metadata: _metadata }, _rangeSelection_initializers, _rangeSelection_extraInitializers);
168
+ __esDecorate(this, null, _minDate_decorators, { kind: "accessor", name: "minDate", static: false, private: false, access: { has: obj => "minDate" in obj, get: obj => obj.minDate, set: (obj, value) => { obj.minDate = value; } }, metadata: _metadata }, _minDate_initializers, _minDate_extraInitializers);
169
+ __esDecorate(this, null, _maxDate_decorators, { kind: "accessor", name: "maxDate", static: false, private: false, access: { has: obj => "maxDate" in obj, get: obj => obj.maxDate, set: (obj, value) => { obj.maxDate = value; } }, metadata: _metadata }, _maxDate_initializers, _maxDate_extraInitializers);
170
+ __esDecorate(this, null, _disabledDates_decorators, { kind: "accessor", name: "disabledDates", static: false, private: false, access: { has: obj => "disabledDates" in obj, get: obj => obj.disabledDates, set: (obj, value) => { obj.disabledDates = value; } }, metadata: _metadata }, _disabledDates_initializers, _disabledDates_extraInitializers);
171
+ __esDecorate(this, null, _locale_decorators, { kind: "accessor", name: "locale", static: false, private: false, access: { has: obj => "locale" in obj, get: obj => obj.locale, set: (obj, value) => { obj.locale = value; } }, metadata: _metadata }, _locale_initializers, _locale_extraInitializers);
172
+ __esDecorate(this, null, _showNavigation_decorators, { kind: "accessor", name: "showNavigation", static: false, private: false, access: { has: obj => "showNavigation" in obj, get: obj => obj.showNavigation, set: (obj, value) => { obj.showNavigation = value; } }, metadata: _metadata }, _showNavigation_initializers, _showNavigation_extraInitializers);
173
+ __esDecorate(this, null, _showActions_decorators, { kind: "accessor", name: "showActions", static: false, private: false, access: { has: obj => "showActions" in obj, get: obj => obj.showActions, set: (obj, value) => { obj.showActions = value; } }, metadata: _metadata }, _showActions_initializers, _showActions_extraInitializers);
174
+ __esDecorate(this, null, _okButtonText_decorators, { kind: "accessor", name: "okButtonText", static: false, private: false, access: { has: obj => "okButtonText" in obj, get: obj => obj.okButtonText, set: (obj, value) => { obj.okButtonText = value; } }, metadata: _metadata }, _okButtonText_initializers, _okButtonText_extraInitializers);
175
+ __esDecorate(this, null, _cancelButtonText_decorators, { kind: "accessor", name: "cancelButtonText", static: false, private: false, access: { has: obj => "cancelButtonText" in obj, get: obj => obj.cancelButtonText, set: (obj, value) => { obj.cancelButtonText = value; } }, metadata: _metadata }, _cancelButtonText_initializers, _cancelButtonText_extraInitializers);
176
+ __esDecorate(this, null, _calendarData_decorators, { kind: "accessor", name: "calendarData", static: false, private: false, access: { has: obj => "calendarData" in obj, get: obj => obj.calendarData, set: (obj, value) => { obj.calendarData = value; } }, metadata: _metadata }, _calendarData_initializers, _calendarData_extraInitializers);
177
+ __esDecorate(this, null, _monthNames_decorators, { kind: "accessor", name: "monthNames", static: false, private: false, access: { has: obj => "monthNames" in obj, get: obj => obj.monthNames, set: (obj, value) => { obj.monthNames = value; } }, metadata: _metadata }, _monthNames_initializers, _monthNames_extraInitializers);
178
+ __esDecorate(this, null, _showMonthDropdown_decorators, { kind: "accessor", name: "showMonthDropdown", static: false, private: false, access: { has: obj => "showMonthDropdown" in obj, get: obj => obj.showMonthDropdown, set: (obj, value) => { obj.showMonthDropdown = value; } }, metadata: _metadata }, _showMonthDropdown_initializers, _showMonthDropdown_extraInitializers);
179
+ __esDecorate(this, null, _showYearDropdown_decorators, { kind: "accessor", name: "showYearDropdown", static: false, private: false, access: { has: obj => "showYearDropdown" in obj, get: obj => obj.showYearDropdown, set: (obj, value) => { obj.showYearDropdown = value; } }, metadata: _metadata }, _showYearDropdown_initializers, _showYearDropdown_extraInitializers);
180
+ __esDecorate(this, null, _pendingDate_decorators, { kind: "accessor", name: "pendingDate", static: false, private: false, access: { has: obj => "pendingDate" in obj, get: obj => obj.pendingDate, set: (obj, value) => { obj.pendingDate = value; } }, metadata: _metadata }, _pendingDate_initializers, _pendingDate_extraInitializers);
181
+ __esDecorate(this, null, _pendingRangeStart_decorators, { kind: "accessor", name: "pendingRangeStart", static: false, private: false, access: { has: obj => "pendingRangeStart" in obj, get: obj => obj.pendingRangeStart, set: (obj, value) => { obj.pendingRangeStart = value; } }, metadata: _metadata }, _pendingRangeStart_initializers, _pendingRangeStart_extraInitializers);
182
+ __esDecorate(this, null, _pendingRangeEnd_decorators, { kind: "accessor", name: "pendingRangeEnd", static: false, private: false, access: { has: obj => "pendingRangeEnd" in obj, get: obj => obj.pendingRangeEnd, set: (obj, value) => { obj.pendingRangeEnd = value; } }, metadata: _metadata }, _pendingRangeEnd_initializers, _pendingRangeEnd_extraInitializers);
183
+ __esDecorate(this, null, _focusedDate_decorators, { kind: "accessor", name: "focusedDate", static: false, private: false, access: { has: obj => "focusedDate" in obj, get: obj => obj.focusedDate, set: (obj, value) => { obj.focusedDate = value; } }, metadata: _metadata }, _focusedDate_initializers, _focusedDate_extraInitializers);
184
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
185
+ UiDatePickerCalendar = _classThis = _classDescriptor.value;
186
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
187
+ }
188
+ static styles = calendarStyles;
189
+ #year_accessor_storage = __runInitializers(this, _year_initializers, new Date().getFullYear()
190
+ /**
191
+ * The currently displayed month (0-indexed, where 0 = January)
192
+ */
193
+ );
194
+ /**
195
+ * The currently displayed year
196
+ */
197
+ get year() { return this.#year_accessor_storage; }
198
+ set year(value) { this.#year_accessor_storage = value; }
199
+ #month_accessor_storage = (__runInitializers(this, _year_extraInitializers), __runInitializers(this, _month_initializers, new Date().getMonth()
200
+ /**
201
+ * The currently selected date for single selection mode.
202
+ * Set to null for no selection.
203
+ */
204
+ ));
205
+ /**
206
+ * The currently displayed month (0-indexed, where 0 = January)
207
+ */
208
+ get month() { return this.#month_accessor_storage; }
209
+ set month(value) { this.#month_accessor_storage = value; }
210
+ #selectedDate_accessor_storage = (__runInitializers(this, _month_extraInitializers), __runInitializers(this, _selectedDate_initializers, null
211
+ /**
212
+ * The start date of the selected range for range selection mode.
213
+ * Used in combination with rangeEnd to define a date range.
214
+ */
215
+ ));
216
+ /**
217
+ * The currently selected date for single selection mode.
218
+ * Set to null for no selection.
219
+ */
220
+ get selectedDate() { return this.#selectedDate_accessor_storage; }
221
+ set selectedDate(value) { this.#selectedDate_accessor_storage = value; }
222
+ #rangeStart_accessor_storage = (__runInitializers(this, _selectedDate_extraInitializers), __runInitializers(this, _rangeStart_initializers, null
223
+ /**
224
+ * The end date of the selected range for range selection mode.
225
+ * Used in combination with rangeStart to define a date range.
226
+ */
227
+ ));
228
+ /**
229
+ * The start date of the selected range for range selection mode.
230
+ * Used in combination with rangeEnd to define a date range.
231
+ */
232
+ get rangeStart() { return this.#rangeStart_accessor_storage; }
233
+ set rangeStart(value) { this.#rangeStart_accessor_storage = value; }
234
+ #rangeEnd_accessor_storage = (__runInitializers(this, _rangeStart_extraInitializers), __runInitializers(this, _rangeEnd_initializers, null
235
+ /**
236
+ * Enable range selection mode. When true, users can select date ranges
237
+ * instead of single dates. Affects event dispatching and UI behavior.
238
+ */
239
+ ));
240
+ /**
241
+ * The end date of the selected range for range selection mode.
242
+ * Used in combination with rangeStart to define a date range.
243
+ */
244
+ get rangeEnd() { return this.#rangeEnd_accessor_storage; }
245
+ set rangeEnd(value) { this.#rangeEnd_accessor_storage = value; }
246
+ #rangeSelection_accessor_storage = (__runInitializers(this, _rangeEnd_extraInitializers), __runInitializers(this, _rangeSelection_initializers, false
247
+ /**
248
+ * Minimum selectable date. Dates before this will be disabled.
249
+ * Set to undefined for no minimum restriction.
250
+ */
251
+ ));
252
+ /**
253
+ * Enable range selection mode. When true, users can select date ranges
254
+ * instead of single dates. Affects event dispatching and UI behavior.
255
+ */
256
+ get rangeSelection() { return this.#rangeSelection_accessor_storage; }
257
+ set rangeSelection(value) { this.#rangeSelection_accessor_storage = value; }
258
+ #minDate_accessor_storage = (__runInitializers(this, _rangeSelection_extraInitializers), __runInitializers(this, _minDate_initializers, undefined
259
+ /**
260
+ * Maximum selectable date. Dates after this will be disabled.
261
+ * Set to undefined for no maximum restriction.
262
+ */
263
+ ));
264
+ /**
265
+ * Minimum selectable date. Dates before this will be disabled.
266
+ * Set to undefined for no minimum restriction.
267
+ */
268
+ get minDate() { return this.#minDate_accessor_storage; }
269
+ set minDate(value) { this.#minDate_accessor_storage = value; }
270
+ #maxDate_accessor_storage = (__runInitializers(this, _minDate_extraInitializers), __runInitializers(this, _maxDate_initializers, undefined
271
+ /**
272
+ * Array of specific dates to disable. These dates will not be selectable
273
+ * regardless of minDate and maxDate settings.
274
+ */
275
+ ));
276
+ /**
277
+ * Maximum selectable date. Dates after this will be disabled.
278
+ * Set to undefined for no maximum restriction.
279
+ */
280
+ get maxDate() { return this.#maxDate_accessor_storage; }
281
+ set maxDate(value) { this.#maxDate_accessor_storage = value; }
282
+ #disabledDates_accessor_storage = (__runInitializers(this, _maxDate_extraInitializers), __runInitializers(this, _disabledDates_initializers, undefined
283
+ /**
284
+ * Locale for date formatting and month/day names (e.g., 'en-US', 'fr-FR').
285
+ * Defaults to browser locale if not specified.
286
+ */
287
+ ));
288
+ /**
289
+ * Array of specific dates to disable. These dates will not be selectable
290
+ * regardless of minDate and maxDate settings.
291
+ */
292
+ get disabledDates() { return this.#disabledDates_accessor_storage; }
293
+ set disabledDates(value) { this.#disabledDates_accessor_storage = value; }
294
+ #locale_accessor_storage = (__runInitializers(this, _disabledDates_extraInitializers), __runInitializers(this, _locale_initializers, undefined
295
+ /**
296
+ * Whether to show navigation controls (previous/next month and year buttons).
297
+ * When false, users can only navigate using keyboard or programmatically.
298
+ */
299
+ ));
300
+ /**
301
+ * Locale for date formatting and month/day names (e.g., 'en-US', 'fr-FR').
302
+ * Defaults to browser locale if not specified.
303
+ */
304
+ get locale() { return this.#locale_accessor_storage; }
305
+ set locale(value) { this.#locale_accessor_storage = value; }
306
+ #showNavigation_accessor_storage = (__runInitializers(this, _locale_extraInitializers), __runInitializers(this, _showNavigation_initializers, true
307
+ /**
308
+ * Whether to show action buttons (OK/Cancel). When true, selections are pending
309
+ * until confirmed with the OK button. When false, selections are immediate.
310
+ */
311
+ ));
312
+ /**
313
+ * Whether to show navigation controls (previous/next month and year buttons).
314
+ * When false, users can only navigate using keyboard or programmatically.
315
+ */
316
+ get showNavigation() { return this.#showNavigation_accessor_storage; }
317
+ set showNavigation(value) { this.#showNavigation_accessor_storage = value; }
318
+ #showActions_accessor_storage = (__runInitializers(this, _showNavigation_extraInitializers), __runInitializers(this, _showActions_initializers, false
319
+ /**
320
+ * Text label for the OK/confirm button. Only visible when showActions is true.
321
+ */
322
+ ));
323
+ /**
324
+ * Whether to show action buttons (OK/Cancel). When true, selections are pending
325
+ * until confirmed with the OK button. When false, selections are immediate.
326
+ */
327
+ get showActions() { return this.#showActions_accessor_storage; }
328
+ set showActions(value) { this.#showActions_accessor_storage = value; }
329
+ #okButtonText_accessor_storage = (__runInitializers(this, _showActions_extraInitializers), __runInitializers(this, _okButtonText_initializers, 'OK'
330
+ /**
331
+ * Text label for the Cancel button. Only visible when showActions is true.
332
+ */
333
+ ));
334
+ /**
335
+ * Text label for the OK/confirm button. Only visible when showActions is true.
336
+ */
337
+ get okButtonText() { return this.#okButtonText_accessor_storage; }
338
+ set okButtonText(value) { this.#okButtonText_accessor_storage = value; }
339
+ #cancelButtonText_accessor_storage = (__runInitializers(this, _okButtonText_extraInitializers), __runInitializers(this, _cancelButtonText_initializers, 'Cancel'));
340
+ /**
341
+ * Text label for the Cancel button. Only visible when showActions is true.
342
+ */
343
+ get cancelButtonText() { return this.#cancelButtonText_accessor_storage; }
344
+ set cancelButtonText(value) { this.#cancelButtonText_accessor_storage = value; }
345
+ #calendarData_accessor_storage = (__runInitializers(this, _cancelButtonText_extraInitializers), __runInitializers(this, _calendarData_initializers, undefined));
346
+ get calendarData() { return this.#calendarData_accessor_storage; }
347
+ set calendarData(value) { this.#calendarData_accessor_storage = value; }
348
+ #monthNames_accessor_storage = (__runInitializers(this, _calendarData_extraInitializers), __runInitializers(this, _monthNames_initializers, []));
349
+ get monthNames() { return this.#monthNames_accessor_storage; }
350
+ set monthNames(value) { this.#monthNames_accessor_storage = value; }
351
+ #showMonthDropdown_accessor_storage = (__runInitializers(this, _monthNames_extraInitializers), __runInitializers(this, _showMonthDropdown_initializers, false));
352
+ get showMonthDropdown() { return this.#showMonthDropdown_accessor_storage; }
353
+ set showMonthDropdown(value) { this.#showMonthDropdown_accessor_storage = value; }
354
+ #showYearDropdown_accessor_storage = (__runInitializers(this, _showMonthDropdown_extraInitializers), __runInitializers(this, _showYearDropdown_initializers, false));
355
+ get showYearDropdown() { return this.#showYearDropdown_accessor_storage; }
356
+ set showYearDropdown(value) { this.#showYearDropdown_accessor_storage = value; }
357
+ #pendingDate_accessor_storage = (__runInitializers(this, _showYearDropdown_extraInitializers), __runInitializers(this, _pendingDate_initializers, null));
358
+ get pendingDate() { return this.#pendingDate_accessor_storage; }
359
+ set pendingDate(value) { this.#pendingDate_accessor_storage = value; }
360
+ #pendingRangeStart_accessor_storage = (__runInitializers(this, _pendingDate_extraInitializers), __runInitializers(this, _pendingRangeStart_initializers, null));
361
+ get pendingRangeStart() { return this.#pendingRangeStart_accessor_storage; }
362
+ set pendingRangeStart(value) { this.#pendingRangeStart_accessor_storage = value; }
363
+ #pendingRangeEnd_accessor_storage = (__runInitializers(this, _pendingRangeStart_extraInitializers), __runInitializers(this, _pendingRangeEnd_initializers, null));
364
+ get pendingRangeEnd() { return this.#pendingRangeEnd_accessor_storage; }
365
+ set pendingRangeEnd(value) { this.#pendingRangeEnd_accessor_storage = value; }
366
+ #focusedDate_accessor_storage = (__runInitializers(this, _pendingRangeEnd_extraInitializers), __runInitializers(this, _focusedDate_initializers, null));
367
+ get focusedDate() { return this.#focusedDate_accessor_storage; }
368
+ set focusedDate(value) { this.#focusedDate_accessor_storage = value; }
369
+ connectedCallback() {
370
+ super.connectedCallback();
371
+ this.updateCalendar();
372
+ this.updateMonthNames();
373
+ this.initializeFocusedDate();
374
+ }
375
+ firstUpdated() {
376
+ // Set initial focus to the calendar container
377
+ this.updateFocus();
378
+ }
379
+ disconnectedCallback() {
380
+ super.disconnectedCallback();
381
+ }
382
+ willUpdate(changedProperties) {
383
+ if (changedProperties.has('year') ||
384
+ changedProperties.has('month') ||
385
+ changedProperties.has('selectedDate') ||
386
+ changedProperties.has('rangeStart') ||
387
+ changedProperties.has('rangeEnd') ||
388
+ changedProperties.has('disabledDates') ||
389
+ changedProperties.has('locale')) {
390
+ this.updateCalendar();
391
+ }
392
+ if (changedProperties.has('locale')) {
393
+ this.updateMonthNames();
394
+ }
395
+ // Update focused date when month/year changes via navigation
396
+ if (changedProperties.has('year') || changedProperties.has('month')) {
397
+ this.updateFocusedDateForMonthChange();
398
+ }
399
+ }
400
+ updated(changedProperties) {
401
+ if (changedProperties.has('showYearDropdown') && this.showYearDropdown) {
402
+ // Scroll selected year into view
403
+ this.scrollSelectedYearIntoView();
404
+ }
405
+ if (changedProperties.has('focusedDate')) {
406
+ this.updateFocus();
407
+ }
408
+ }
409
+ updateFocus() {
410
+ if (!this.focusedDate)
411
+ return;
412
+ // Find the button for the focused date and set focus
413
+ const dateString = this.focusedDate.toISOString().split('T')[0];
414
+ const focusedButton = this.shadowRoot?.querySelector(`[data-date="${dateString}"]`);
415
+ if (focusedButton && !focusedButton.hasAttribute('disabled')) {
416
+ // Use requestAnimationFrame to ensure DOM is updated
417
+ requestAnimationFrame(() => {
418
+ focusedButton.focus();
419
+ });
420
+ }
421
+ }
422
+ scrollSelectedYearIntoView() {
423
+ // Wait for next frame to ensure DOM is updated
424
+ requestAnimationFrame(() => {
425
+ const selectedYearButton = this.shadowRoot?.querySelector('.year-option.selected');
426
+ if (selectedYearButton) {
427
+ selectedYearButton.scrollIntoView({
428
+ behavior: 'auto',
429
+ block: 'center',
430
+ });
431
+ }
432
+ });
433
+ }
434
+ updateFocusedDateForMonthChange() {
435
+ if (!this.focusedDate) {
436
+ this.initializeFocusedDate();
437
+ return;
438
+ }
439
+ // Keep the same day of month if possible
440
+ const targetDay = this.focusedDate.getDate();
441
+ const newDate = new Date(this.year, this.month, targetDay);
442
+ // Check if the target date exists in the new month and is not disabled
443
+ if (newDate.getMonth() === this.month && !this.isDateDisabled(newDate)) {
444
+ this.focusedDate = newDate;
445
+ }
446
+ else {
447
+ // Find the closest available date
448
+ this.focusedDate = this.findFirstAvailableDate();
449
+ }
450
+ }
451
+ updateCalendar() {
452
+ const selectedRange = this.rangeStart || this.rangeEnd ? { start: this.rangeStart, end: this.rangeEnd } : null;
453
+ this.calendarData = generateCalendarMonth(this.year, this.month, this.selectedDate, selectedRange, this.disabledDates, this.locale);
454
+ }
455
+ updateMonthNames() {
456
+ this.monthNames = getMonthNames(this.locale);
457
+ }
458
+ navigateMonth(delta) {
459
+ const newDate = addMonths(new Date(this.year, this.month), delta);
460
+ this.year = newDate.getFullYear();
461
+ this.month = newDate.getMonth();
462
+ }
463
+ handlePrevMonth() {
464
+ this.navigateMonth(-1);
465
+ }
466
+ handleNextMonth() {
467
+ this.navigateMonth(1);
468
+ }
469
+ handlePrevYear() {
470
+ this.year = this.year - 1;
471
+ }
472
+ handleNextYear() {
473
+ this.year = this.year + 1;
474
+ }
475
+ handleMonthClick() {
476
+ this.showMonthDropdown = !this.showMonthDropdown;
477
+ this.showYearDropdown = false;
478
+ }
479
+ handleYearClick() {
480
+ this.showYearDropdown = !this.showYearDropdown;
481
+ this.showMonthDropdown = false;
482
+ }
483
+ handleMonthSelect(selectedMonth) {
484
+ this.month = selectedMonth;
485
+ this.showMonthDropdown = false;
486
+ }
487
+ handleYearSelect(selectedYear) {
488
+ this.year = selectedYear;
489
+ this.showYearDropdown = false;
490
+ }
491
+ closeDropdowns() {
492
+ this.showMonthDropdown = false;
493
+ this.showYearDropdown = false;
494
+ }
495
+ navigateDate(delta) {
496
+ if (!this.focusedDate)
497
+ return;
498
+ const newDate = addDays(this.focusedDate, delta);
499
+ // Check if new date is in current month or if we should navigate to next/previous month
500
+ if (newDate.getMonth() !== this.month || newDate.getFullYear() !== this.year) {
501
+ // Navigate to next/previous month
502
+ if (delta > 0) {
503
+ this.navigateMonth(1);
504
+ }
505
+ else {
506
+ this.navigateMonth(-1);
507
+ }
508
+ // Set focused date to the target date in the new month
509
+ this.focusedDate = newDate;
510
+ return;
511
+ }
512
+ // Check if new date is disabled
513
+ if (this.isDateDisabled(newDate)) {
514
+ // Try to find next available date
515
+ const availableDate = this.findNextAvailableDate(newDate, delta > 0);
516
+ if (availableDate) {
517
+ this.focusedDate = availableDate;
518
+ }
519
+ }
520
+ else {
521
+ this.focusedDate = newDate;
522
+ }
523
+ }
524
+ findNextAvailableDate(startDate, forward) {
525
+ const direction = forward ? 1 : -1;
526
+ for (let i = 1; i <= 31; i++) {
527
+ const date = addDays(startDate, i * direction);
528
+ if (date.getMonth() !== this.month)
529
+ break; // Out of current month
530
+ if (!this.isDateDisabled(date)) {
531
+ return date;
532
+ }
533
+ }
534
+ return null;
535
+ }
536
+ focusFirstDayOfMonth() {
537
+ const firstDay = new Date(this.year, this.month, 1);
538
+ if (!this.isDateDisabled(firstDay)) {
539
+ this.focusedDate = firstDay;
540
+ }
541
+ else {
542
+ this.focusedDate = this.findFirstAvailableDate();
543
+ }
544
+ }
545
+ focusLastDayOfMonth() {
546
+ const lastDay = new Date(this.year, this.month + 1, 0);
547
+ if (!this.isDateDisabled(lastDay)) {
548
+ this.focusedDate = lastDay;
549
+ }
550
+ else {
551
+ // Find last available date in month
552
+ for (let i = lastDay.getDate(); i >= 1; i--) {
553
+ const date = new Date(this.year, this.month, i);
554
+ if (!this.isDateDisabled(date)) {
555
+ this.focusedDate = date;
556
+ break;
557
+ }
558
+ }
559
+ }
560
+ }
561
+ selectFocusedDate() {
562
+ if (!this.focusedDate || this.isDateDisabled(this.focusedDate))
563
+ return;
564
+ if (this.rangeSelection) {
565
+ this.handleRangeSelection(this.focusedDate);
566
+ }
567
+ else {
568
+ this.handleSingleSelection(this.focusedDate);
569
+ }
570
+ }
571
+ handleDayClick(day) {
572
+ if (day.isDisabled)
573
+ return;
574
+ // Update focused date to clicked date
575
+ this.focusedDate = day.date;
576
+ if (this.rangeSelection) {
577
+ this.handleRangeSelection(day.date);
578
+ }
579
+ else {
580
+ this.handleSingleSelection(day.date);
581
+ }
582
+ }
583
+ handleSingleSelection(date) {
584
+ if (this.showActions) {
585
+ // Use pending state when actions are enabled
586
+ this.pendingDate = date;
587
+ }
588
+ else {
589
+ // Immediate selection when no actions
590
+ this.selectedDate = date;
591
+ this.dispatchDateEvent(date);
592
+ }
593
+ }
594
+ handleRangeSelection(date) {
595
+ const isImmediate = !this.showActions;
596
+ const { start, end } = this.getCurrentRange();
597
+ // If we have a complete range, start a new one
598
+ if (start && end) {
599
+ this.setRangeValues(date, null, isImmediate);
600
+ return;
601
+ }
602
+ // If we have a start but no end, complete the range
603
+ if (start && !end) {
604
+ const sortedRange = start <= date ? { start, end: date } : { start: date, end: start };
605
+ this.setRangeValues(sortedRange.start, sortedRange.end, isImmediate);
606
+ if (isImmediate) {
607
+ this.dispatchRangeEvent(sortedRange);
608
+ }
609
+ return;
610
+ }
611
+ // Start new range
612
+ this.setRangeValues(date, null, isImmediate);
613
+ }
614
+ /**
615
+ * Helper to get the current range state (either immediate or pending)
616
+ */
617
+ getCurrentRange() {
618
+ const isImmediate = !this.showActions;
619
+ return {
620
+ start: isImmediate ? this.rangeStart : this.pendingRangeStart,
621
+ end: isImmediate ? this.rangeEnd : this.pendingRangeEnd,
622
+ };
623
+ }
624
+ /**
625
+ * Helper to check if we have a complete range in the current mode
626
+ */
627
+ hasCompleteRange() {
628
+ const { start, end } = this.getCurrentRange();
629
+ return !!(start && end);
630
+ }
631
+ setRangeValues(start, end, isImmediate) {
632
+ if (isImmediate) {
633
+ this.rangeStart = start;
634
+ this.rangeEnd = end;
635
+ }
636
+ else {
637
+ this.pendingRangeStart = start;
638
+ this.pendingRangeEnd = end;
639
+ }
640
+ }
641
+ /**
642
+ * Helper to dispatch date selection events
643
+ */
644
+ dispatchDateEvent(date) {
645
+ const event = {
646
+ date,
647
+ formattedDate: formatDate(date, this.locale),
648
+ };
649
+ this.dispatchEvent(new CustomEvent('date-select', {
650
+ detail: event,
651
+ bubbles: true,
652
+ composed: true,
653
+ }));
654
+ }
655
+ /**
656
+ * Helper to dispatch range selection events
657
+ */
658
+ dispatchRangeEvent(range) {
659
+ const event = {
660
+ range,
661
+ formattedRange: {
662
+ start: formatDate(range.start, this.locale),
663
+ end: formatDate(range.end, this.locale),
664
+ },
665
+ };
666
+ this.dispatchEvent(new CustomEvent('date-range-select', {
667
+ detail: event,
668
+ bubbles: true,
669
+ composed: true,
670
+ }));
671
+ }
672
+ /**
673
+ * Helper to dispatch range confirmation events
674
+ */
675
+ dispatchRangeConfirmEvent(range) {
676
+ const event = {
677
+ range,
678
+ formattedRange: {
679
+ start: range?.start ? formatDate(range.start, this.locale) : null,
680
+ end: range?.end ? formatDate(range.end, this.locale) : null,
681
+ },
682
+ };
683
+ this.dispatchEvent(new CustomEvent('date-range-confirm', {
684
+ detail: event,
685
+ bubbles: true,
686
+ composed: true,
687
+ }));
688
+ }
689
+ /**
690
+ * Helper to dispatch cancel events
691
+ */
692
+ dispatchCancelEvent(reason = 'user_cancelled') {
693
+ const event = { reason };
694
+ this.dispatchEvent(new CustomEvent('date-cancel', {
695
+ detail: event,
696
+ bubbles: true,
697
+ composed: true,
698
+ }));
699
+ }
700
+ isDateDisabled(date) {
701
+ if (this.minDate && date < this.minDate)
702
+ return true;
703
+ if (this.maxDate && date > this.maxDate)
704
+ return true;
705
+ if (this.disabledDates?.some((disabledDate) => isSameDay(date, disabledDate)))
706
+ return true;
707
+ return false;
708
+ }
709
+ handleConfirm() {
710
+ if (this.rangeSelection) {
711
+ if (this.pendingRangeStart || this.pendingRangeEnd) {
712
+ this.rangeStart = this.pendingRangeStart;
713
+ this.rangeEnd = this.pendingRangeEnd;
714
+ const range = this.rangeStart || this.rangeEnd ? { start: this.rangeStart, end: this.rangeEnd } : null;
715
+ // Reset pending state after confirmation
716
+ this.pendingRangeStart = null;
717
+ this.pendingRangeEnd = null;
718
+ this.dispatchRangeConfirmEvent(range);
719
+ }
720
+ }
721
+ else {
722
+ if (this.pendingDate) {
723
+ this.selectedDate = this.pendingDate;
724
+ // Reset pending state after confirmation
725
+ this.pendingDate = null;
726
+ this.dispatchDateEvent(this.selectedDate);
727
+ }
728
+ }
729
+ }
730
+ handleCancel() {
731
+ // Reset pending state
732
+ this.pendingDate = null;
733
+ this.pendingRangeStart = null;
734
+ this.pendingRangeEnd = null;
735
+ this.dispatchCancelEvent();
736
+ }
737
+ /**
738
+ * Helper to render navigation buttons
739
+ */
740
+ renderNavButton(direction, onClick, ariaLabel, icon) {
741
+ if (!this.showNavigation || this.showMonthDropdown || this.showYearDropdown) {
742
+ return nothing;
743
+ }
744
+ return html `<ui-icon-button
745
+ class="nav-button"
746
+ size="xs"
747
+ @click=${onClick}
748
+ aria-label=${ariaLabel}
749
+ title=${ariaLabel}
750
+ >
751
+ <ui-icon icon=${icon}></ui-icon>
752
+ </ui-icon-button>`;
753
+ }
754
+ renderNavigation() {
755
+ const monthName = this.monthNames[this.month] || '';
756
+ return html `
757
+ <div class="header">
758
+ <div class="month-year">
759
+ <div class="month-selector">
760
+ ${this.renderNavButton('prev', this.handlePrevMonth, 'Previous month', 'chevronLeft')}
761
+ <ui-button
762
+ class="month-button"
763
+ color="text"
764
+ size="xs"
765
+ @click=${this.handleMonthClick}
766
+ aria-label="Select month"
767
+ aria-expanded=${this.showMonthDropdown}
768
+ trailingIcon
769
+ >
770
+ ${monthName}
771
+ <ui-icon icon="arrowDropDown" slot="icon"></ui-icon>
772
+ </ui-button>
773
+ ${this.renderNavButton('next', this.handleNextMonth, 'Next month', 'chevronRight')}
774
+ </div>
775
+ <div class="year-selector">
776
+ ${this.renderNavButton('prev', this.handlePrevYear, 'Previous year', 'chevronLeft')}
777
+ <ui-button
778
+ class="year-button"
779
+ color="text"
780
+ size="xs"
781
+ @click=${this.handleYearClick}
782
+ aria-label="Select year"
783
+ aria-expanded=${this.showYearDropdown}
784
+ trailingIcon
785
+ >
786
+ ${this.year}
787
+ <ui-icon icon="arrowDropDown" slot="icon"></ui-icon>
788
+ </ui-button>
789
+ ${this.renderNavButton('next', this.handleNextYear, 'Next year', 'chevronRight')}
790
+ </div>
791
+ </div>
792
+ </div>
793
+ `;
794
+ }
795
+ renderWeekdays() {
796
+ if (!this.calendarData)
797
+ return html ``;
798
+ return html `
799
+ <div class="weekdays" role="row">
800
+ ${this.calendarData.weekdays.map((weekday) => html `<div class="weekday" role="columnheader">${weekday}</div>`)}
801
+ </div>
802
+ `;
803
+ }
804
+ /**
805
+ * Helper to determine day selection state for rendering
806
+ */
807
+ getDaySelectionState(day) {
808
+ if (this.showActions) {
809
+ // Use pending state
810
+ const isPendingSelected = this.pendingDate && isSameDay(day.date, this.pendingDate);
811
+ const isPendingRangeStart = this.pendingRangeStart && isSameDay(day.date, this.pendingRangeStart);
812
+ const isPendingRangeEnd = this.pendingRangeEnd && isSameDay(day.date, this.pendingRangeEnd);
813
+ const isPendingInRange = this.pendingRangeStart &&
814
+ this.pendingRangeEnd &&
815
+ day.date >= this.pendingRangeStart &&
816
+ day.date <= this.pendingRangeEnd &&
817
+ !isPendingRangeStart &&
818
+ !isPendingRangeEnd;
819
+ return {
820
+ isSelected: !!isPendingSelected,
821
+ isRangeStart: !!isPendingRangeStart,
822
+ isRangeEnd: !!isPendingRangeEnd,
823
+ isInRange: !!isPendingInRange,
824
+ };
825
+ }
826
+ else {
827
+ // Use immediate state
828
+ return {
829
+ isSelected: day.isSelected,
830
+ isRangeStart: day.isRangeStart,
831
+ isRangeEnd: day.isRangeEnd,
832
+ isInRange: day.isInRange,
833
+ };
834
+ }
835
+ }
836
+ /**
837
+ * Helper to determine button color for a day
838
+ */
839
+ getDayButtonColor(day, selectionState) {
840
+ if (selectionState.isRangeStart || selectionState.isRangeEnd || selectionState.isSelected) {
841
+ return 'filled';
842
+ }
843
+ if (selectionState.isInRange) {
844
+ return 'text';
845
+ }
846
+ if (day.isToday) {
847
+ return 'outlined';
848
+ }
849
+ return 'text';
850
+ }
851
+ renderDay(day) {
852
+ const selectionState = this.getDaySelectionState(day);
853
+ const color = this.getDayButtonColor(day, selectionState);
854
+ const classes = {
855
+ 'day-cell': true,
856
+ 'other-month': !day.isCurrentMonth,
857
+ 'today': day.isToday,
858
+ 'in-range': selectionState.isInRange,
859
+ 'range-start': selectionState.isRangeStart,
860
+ 'range-end': selectionState.isRangeEnd,
861
+ 'has-complete-range': this.hasCompleteRange(),
862
+ };
863
+ const isFocused = this.focusedDate && isSameDay(day.date, this.focusedDate);
864
+ return html `
865
+ <div class=${classMap(classes)} role="gridcell">
866
+ <ui-button
867
+ class="day-button"
868
+ color=${color}
869
+ size="s"
870
+ data-date=${day.date.toISOString().split('T')[0]}
871
+ tabindex=${isFocused && !(day.isDisabled || this.isDateDisabled(day.date)) ? '0' : '-1'}
872
+ aria-label=${formatDate(day.date, this.locale)}
873
+ aria-selected=${selectionState.isSelected || selectionState.isRangeStart || selectionState.isRangeEnd}
874
+ @click=${() => this.handleDayClick(day)}
875
+ ?disabled=${day.isDisabled || this.isDateDisabled(day.date)}
876
+ >
877
+ ${day.date.getDate()}
878
+ </ui-button>
879
+ </div>
880
+ `;
881
+ }
882
+ renderDays() {
883
+ if (!this.calendarData)
884
+ return html ``;
885
+ return html `<div class="days">${this.calendarData.days.map((day) => this.renderDay(day))}</div>`;
886
+ }
887
+ renderActions() {
888
+ if (!this.showActions)
889
+ return nothing;
890
+ const hasSelection = this.rangeSelection ? this.pendingRangeStart : this.pendingDate;
891
+ return html `
892
+ <div class="actions">
893
+ <ui-button size="s" color="text" @click=${this.handleCancel}>${this.cancelButtonText}</ui-button>
894
+ <ui-button size="s" color="text" @click=${this.handleConfirm} ?disabled=${!hasSelection}>
895
+ ${this.okButtonText}
896
+ </ui-button>
897
+ </div>
898
+ `;
899
+ }
900
+ /**
901
+ * Helper to render dropdown option buttons
902
+ */
903
+ renderDropdownOption(value, label, isSelected, onClick, className = '') {
904
+ return html `
905
+ <ui-button
906
+ class="dropdown-option ${className} ${isSelected ? 'selected' : ''}"
907
+ color=${isSelected ? 'filled' : 'text'}
908
+ size="s"
909
+ @click=${onClick}
910
+ aria-label=${label}
911
+ >
912
+ ${label}
913
+ </ui-button>
914
+ `;
915
+ }
916
+ renderMonthDropdown() {
917
+ return html `
918
+ <div class="dropdown-view">
919
+ <div class="month-list">
920
+ ${this.monthNames.map((monthName, index) => this.renderDropdownOption(index, monthName, index === this.month, () => this.handleMonthSelect(index)))}
921
+ </div>
922
+ </div>
923
+ `;
924
+ }
925
+ renderYearDropdown() {
926
+ const currentYear = this.year;
927
+ const startYear = currentYear - 50;
928
+ const endYear = currentYear + 50;
929
+ const years = [];
930
+ for (let year = startYear; year <= endYear; year++) {
931
+ years.push(year);
932
+ }
933
+ return html `
934
+ <div class="dropdown-view">
935
+ <div class="year-grid">
936
+ ${years.map((year) => this.renderDropdownOption(year, year.toString(), year === this.year, () => this.handleYearSelect(year), 'year-option'))}
937
+ </div>
938
+ </div>
939
+ `;
940
+ }
941
+ findFirstAvailableDate() {
942
+ const firstDayOfMonth = new Date(this.year, this.month, 1);
943
+ for (let i = 0; i < 31; i++) {
944
+ const date = addDays(firstDayOfMonth, i);
945
+ if (date.getMonth() !== this.month)
946
+ break; // Next month
947
+ if (!this.isDateDisabled(date)) {
948
+ return date;
949
+ }
950
+ }
951
+ return firstDayOfMonth; // Fallback
952
+ }
953
+ handleKeyDown(event) {
954
+ // Prevent default behavior for navigation keys
955
+ const navigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown', ' '];
956
+ if (navigationKeys.includes(event.key)) {
957
+ event.preventDefault();
958
+ }
959
+ switch (event.key) {
960
+ case 'ArrowLeft':
961
+ this.navigateDate(-1);
962
+ break;
963
+ case 'ArrowRight':
964
+ this.navigateDate(1);
965
+ break;
966
+ case 'ArrowUp':
967
+ this.navigateDate(-7);
968
+ break;
969
+ case 'ArrowDown':
970
+ this.navigateDate(7);
971
+ break;
972
+ case 'Enter':
973
+ case ' ':
974
+ this.selectFocusedDate();
975
+ break;
976
+ case 'Home':
977
+ this.focusFirstDayOfMonth();
978
+ break;
979
+ case 'End':
980
+ this.focusLastDayOfMonth();
981
+ break;
982
+ case 'PageUp':
983
+ if (event.shiftKey) {
984
+ this.handlePrevYear();
985
+ }
986
+ else {
987
+ this.navigateMonth(-1);
988
+ }
989
+ break;
990
+ case 'PageDown':
991
+ if (event.shiftKey) {
992
+ this.handleNextYear();
993
+ }
994
+ else {
995
+ this.navigateMonth(1);
996
+ }
997
+ break;
998
+ case 'Escape':
999
+ this.closeDropdowns();
1000
+ break;
1001
+ }
1002
+ }
1003
+ /**
1004
+ * Helper to check if a date is in the current month and not disabled
1005
+ */
1006
+ isDateAvailable(date) {
1007
+ return date.getMonth() === this.month && date.getFullYear() === this.year && !this.isDateDisabled(date);
1008
+ }
1009
+ initializeFocusedDate() {
1010
+ // Priority: selectedDate, rangeStart, today, first available date
1011
+ const candidates = [this.selectedDate, this.rangeStart, new Date()].filter(Boolean);
1012
+ for (const candidate of candidates) {
1013
+ if (this.isDateAvailable(candidate)) {
1014
+ this.focusedDate = candidate;
1015
+ return;
1016
+ }
1017
+ }
1018
+ // Fallback to first available date in current month
1019
+ this.focusedDate = this.findFirstAvailableDate();
1020
+ }
1021
+ render() {
1022
+ // Show dropdown views instead of calendar when dropdowns are open
1023
+ if (this.showMonthDropdown) {
1024
+ return html `
1025
+ <div class="calendar" role="grid" aria-label="Month selection for ${this.year}">
1026
+ ${this.renderNavigation()} ${this.renderMonthDropdown()}
1027
+ </div>
1028
+ `;
1029
+ }
1030
+ if (this.showYearDropdown) {
1031
+ return html `
1032
+ <div class="calendar" role="grid" aria-label="Year selection">
1033
+ ${this.renderNavigation()} ${this.renderYearDropdown()}
1034
+ </div>
1035
+ `;
1036
+ }
1037
+ // Default calendar view
1038
+ return html `
1039
+ <div
1040
+ class="calendar"
1041
+ role="grid"
1042
+ aria-label="Calendar for ${this.monthNames[this.month]} ${this.year}"
1043
+ aria-roledescription="Calendar grid"
1044
+ tabindex="0"
1045
+ @keydown=${this.handleKeyDown}
1046
+ >
1047
+ ${this.renderNavigation()} ${this.renderWeekdays()} ${this.renderDays()} ${this.renderActions()}
1048
+ </div>
1049
+ `;
1050
+ }
1051
+ constructor() {
1052
+ super(...arguments);
1053
+ __runInitializers(this, _focusedDate_extraInitializers);
1054
+ }
1055
+ static {
1056
+ __runInitializers(_classThis, _classExtraInitializers);
1057
+ }
1058
+ };
1059
+ return UiDatePickerCalendar = _classThis;
1060
+ })();
1061
+ export { UiDatePickerCalendar };
1062
+ //# sourceMappingURL=DatePickerCalendar.js.map