@api-client/ui 0.5.6 → 0.5.8

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 (82) 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/mention-textarea/internals/MentionTextArea.d.ts +216 -0
  18. package/build/src/elements/mention-textarea/internals/MentionTextArea.d.ts.map +1 -0
  19. package/build/src/elements/mention-textarea/internals/MentionTextArea.js +1037 -0
  20. package/build/src/elements/mention-textarea/internals/MentionTextArea.js.map +1 -0
  21. package/build/src/elements/mention-textarea/internals/MentionTextArea.styles.d.ts +3 -0
  22. package/build/src/elements/mention-textarea/internals/MentionTextArea.styles.d.ts.map +1 -0
  23. package/build/src/elements/mention-textarea/internals/MentionTextArea.styles.js +274 -0
  24. package/build/src/elements/mention-textarea/internals/MentionTextArea.styles.js.map +1 -0
  25. package/build/src/elements/mention-textarea/ui-mention-textarea.d.ts +13 -0
  26. package/build/src/elements/mention-textarea/ui-mention-textarea.d.ts.map +1 -0
  27. package/build/src/elements/mention-textarea/ui-mention-textarea.js +28 -0
  28. package/build/src/elements/mention-textarea/ui-mention-textarea.js.map +1 -0
  29. package/build/src/md/button/internals/base.d.ts +1 -0
  30. package/build/src/md/button/internals/base.d.ts.map +1 -1
  31. package/build/src/md/button/internals/base.js +7 -0
  32. package/build/src/md/button/internals/base.js.map +1 -1
  33. package/build/src/md/chip/internals/Chip.styles.d.ts.map +1 -1
  34. package/build/src/md/chip/internals/Chip.styles.js +2 -0
  35. package/build/src/md/chip/internals/Chip.styles.js.map +1 -1
  36. package/build/src/md/date-picker/internals/DatePicker.styles.d.ts.map +1 -1
  37. package/build/src/md/date-picker/internals/DatePicker.styles.js +73 -0
  38. package/build/src/md/date-picker/internals/DatePicker.styles.js.map +1 -1
  39. package/build/src/md/date-picker/internals/DatePickerCalendar.d.ts +164 -51
  40. package/build/src/md/date-picker/internals/DatePickerCalendar.d.ts.map +1 -1
  41. package/build/src/md/date-picker/internals/DatePickerCalendar.js +660 -368
  42. package/build/src/md/date-picker/internals/DatePickerCalendar.js.map +1 -1
  43. package/build/src/md/date-picker/ui-date-picker-input.d.ts +65 -13
  44. package/build/src/md/date-picker/ui-date-picker-input.d.ts.map +1 -1
  45. package/build/src/md/date-picker/ui-date-picker-input.js +143 -76
  46. package/build/src/md/date-picker/ui-date-picker-input.js.map +1 -1
  47. package/build/src/md/date-picker/ui-date-picker-modal-input.d.ts +76 -17
  48. package/build/src/md/date-picker/ui-date-picker-modal-input.d.ts.map +1 -1
  49. package/build/src/md/date-picker/ui-date-picker-modal-input.js +192 -127
  50. package/build/src/md/date-picker/ui-date-picker-modal-input.js.map +1 -1
  51. package/build/src/md/date-picker/ui-date-picker-modal.d.ts +63 -15
  52. package/build/src/md/date-picker/ui-date-picker-modal.d.ts.map +1 -1
  53. package/build/src/md/date-picker/ui-date-picker-modal.js +143 -64
  54. package/build/src/md/date-picker/ui-date-picker-modal.js.map +1 -1
  55. package/demo/elements/currency/index.html +91 -0
  56. package/demo/elements/currency/index.ts +272 -0
  57. package/demo/elements/index.html +6 -0
  58. package/demo/elements/mention-textarea/index.html +19 -0
  59. package/demo/elements/mention-textarea/index.ts +205 -0
  60. package/demo/md/date-picker/date-picker.ts +138 -103
  61. package/package.json +2 -2
  62. package/src/elements/currency/currency-picker.ts +14 -0
  63. package/src/elements/currency/internals/Picker.styles.ts +58 -0
  64. package/src/elements/currency/internals/Picker.ts +846 -0
  65. package/src/elements/mention-textarea/internals/MentionTextArea.styles.ts +274 -0
  66. package/src/elements/mention-textarea/internals/MentionTextArea.ts +1036 -0
  67. package/src/elements/mention-textarea/ui-mention-textarea.ts +18 -0
  68. package/src/md/button/internals/base.ts +7 -0
  69. package/src/md/chip/internals/Chip.styles.ts +2 -0
  70. package/src/md/date-picker/internals/DatePicker.styles.ts +73 -0
  71. package/src/md/date-picker/internals/DatePickerCalendar.ts +643 -309
  72. package/src/md/date-picker/ui-date-picker-input.ts +110 -49
  73. package/src/md/date-picker/ui-date-picker-modal-input.ts +168 -99
  74. package/src/md/date-picker/ui-date-picker-modal.ts +136 -53
  75. package/test/README.md +3 -2
  76. package/test/elements/currency/CurrencyPicker.accessibility.test.ts +328 -0
  77. package/test/elements/currency/CurrencyPicker.core.test.ts +318 -0
  78. package/test/elements/currency/CurrencyPicker.integration.test.ts +482 -0
  79. package/test/elements/currency/CurrencyPicker.test.ts +486 -0
  80. package/test/elements/mention-textarea/MentionTextArea.basic.test.ts +63 -0
  81. package/test/elements/mention-textarea/MentionTextArea.test.ts +321 -0
  82. package/tsconfig.json +1 -1
@@ -11,13 +11,52 @@ import '../../md/icons/ui-icon.js'
11
11
  * A docked date picker that opens from a text field input.
12
12
  * Ideal for forms and date selection in medium to large layouts.
13
13
  *
14
+ * ## Features
15
+ * - Text field input with calendar dropdown
16
+ * - Keyboard navigation support (Arrow Down, Enter, Escape)
17
+ * - Custom date formatting
18
+ * - Input validation and error handling
19
+ * - Min/max date constraints
20
+ * - Disabled dates support
21
+ * - Accessible design with proper ARIA attributes
22
+ * - CSS Anchor Positioning API for dropdown placement
23
+ *
24
+ * ## Events
25
+ *
26
+ * ### `change`
27
+ * Fired when the selected date changes.
28
+ *
29
+ * **Detail:**
30
+ * ```typescript
31
+ * {
32
+ * value: Date | null,
33
+ * formattedValue: string
34
+ * }
35
+ * ```
36
+ *
14
37
  * ## Usage
15
38
  *
39
+ * ### Basic usage
16
40
  * ```html
17
41
  * <ui-date-picker-input
18
42
  * label="Select date"
43
+ * name="birthDate"
19
44
  * placeholder="MM/DD/YYYY"
20
45
  * .value=${new Date()}
46
+ * @change=${this.handleDateChange}
47
+ * ></ui-date-picker-input>
48
+ * ```
49
+ *
50
+ * ### With validation
51
+ * ```html
52
+ * <ui-date-picker-input
53
+ * label="Birth date"
54
+ * name="birthDate"
55
+ * required
56
+ * .error=${this.hasError}
57
+ * .errorMessage=${"Please select a valid date"}
58
+ * .minDate=${new Date('1900-01-01')}
59
+ * .maxDate=${new Date()}
21
60
  * ></ui-date-picker-input>
22
61
  * ```
23
62
  *
@@ -28,6 +67,14 @@ import '../../md/icons/ui-icon.js'
28
67
  * .dateFormat=${date => date.toLocaleDateString('en-GB')}
29
68
  * ></ui-date-picker-input>
30
69
  * ```
70
+ *
71
+ * ### With disabled dates
72
+ * ```html
73
+ * <ui-date-picker-input
74
+ * label="Appointment date"
75
+ * .disabledDates=${[new Date('2024-12-25'), new Date('2024-01-01')]}
76
+ * ></ui-date-picker-input>
77
+ * ```
31
78
  */
32
79
  @customElement('ui-date-picker-input')
33
80
  export class UiDatePickerInput extends LitElement {
@@ -42,6 +89,11 @@ export class UiDatePickerInput extends LitElement {
42
89
  */
43
90
  @property({ type: String }) accessor label = ''
44
91
 
92
+ /**
93
+ * The name attribute for the input field (for form handling)
94
+ */
95
+ @property({ type: String }) accessor name = ''
96
+
45
97
  /**
46
98
  * Placeholder text for the input
47
99
  */
@@ -97,106 +149,114 @@ export class UiDatePickerInput extends LitElement {
97
149
  */
98
150
  @property({ type: Object }) accessor dateFormat: ((date: Date) => string) | undefined = undefined
99
151
 
100
- @state() private accessor _isOpen = false
152
+ @state() private accessor isOpen = false
101
153
 
102
- @state() private accessor _inputValue = ''
154
+ @state() private accessor inputValue = ''
103
155
 
104
- @query('ui-outlined-text-field') private accessor _textField!: HTMLElement
156
+ @query('ui-outlined-text-field') private accessor textField!: HTMLElement
157
+
158
+ constructor() {
159
+ super()
160
+ // Initialize boolean properties to false as per Lit best practices
161
+ this.disabled = false
162
+ this.required = false
163
+ this.error = false
164
+ }
105
165
 
106
166
  override connectedCallback(): void {
107
167
  super.connectedCallback()
108
- this._updateInputValue()
109
- document.addEventListener('click', this._handleDocumentClick.bind(this))
168
+ this.updateInputValue()
169
+ document.addEventListener('click', this.handleDocumentClick.bind(this))
110
170
  }
111
171
 
112
172
  override disconnectedCallback(): void {
113
173
  super.disconnectedCallback()
114
- document.removeEventListener('click', this._handleDocumentClick.bind(this))
174
+ document.removeEventListener('click', this.handleDocumentClick.bind(this))
115
175
  }
116
176
 
117
177
  override willUpdate(changedProperties: Map<string | number | symbol, unknown>): void {
118
178
  if (changedProperties.has('value')) {
119
- this._updateInputValue()
179
+ this.updateInputValue()
120
180
  }
121
181
  }
122
182
 
123
183
  override updated(changedProperties: Map<string | number | symbol, unknown>): void {
124
- if (changedProperties.has('_isOpen') && this._isOpen) {
184
+ if (changedProperties.has('isOpen') && this.isOpen) {
125
185
  // Set anchor name on text field for CSS Anchor Positioning API
126
- if (this._textField) {
186
+ if (this.textField) {
127
187
  // Using setProperty since anchorName is not in TypeScript types yet
128
- this._textField.style.setProperty('anchor-name', '--ui-date-picker-anchor')
188
+ this.textField.style.setProperty('anchor-name', '--ui-date-picker-anchor')
129
189
  }
130
190
  }
131
191
  }
132
192
 
133
- private _updateInputValue(): void {
193
+ private updateInputValue(): void {
134
194
  if (this.value) {
135
- this._inputValue = this.dateFormat ? this.dateFormat(this.value) : formatDate(this.value, this.locale)
195
+ this.inputValue = this.dateFormat ? this.dateFormat(this.value) : formatDate(this.value, this.locale)
136
196
  } else {
137
- this._inputValue = ''
197
+ this.inputValue = ''
138
198
  }
139
199
  }
140
200
 
141
- private _handleDocumentClick(event: Event): void {
201
+ private handleDocumentClick(event: Event): void {
142
202
  if (!this.contains(event.target as Node)) {
143
- this._isOpen = false
203
+ this.isOpen = false
144
204
  }
145
205
  }
146
206
 
147
- private _handleInputClick(): void {
207
+ private handleInputClick(): void {
148
208
  if (!this.disabled) {
149
- this._isOpen = !this._isOpen
209
+ this.isOpen = !this.isOpen
150
210
  }
151
211
  }
152
212
 
153
- private _handleInputChange(event: Event): void {
213
+ private handleInputChange(event: Event): void {
154
214
  const target = event.target as HTMLInputElement
155
- this._inputValue = target.value
215
+ this.inputValue = target.value
156
216
 
157
- const parsedDate = parseDate(this._inputValue)
217
+ const parsedDate = parseDate(this.inputValue)
158
218
  if (parsedDate) {
159
219
  this.value = parsedDate
160
- this._dispatchChangeEvent()
220
+ this.dispatchChangeEvent()
161
221
  }
162
222
  }
163
223
 
164
- private _handleCalendarDateSelect(event: CustomEvent<DateSelectEvent>): void {
224
+ private handleCalendarDateSelect(event: CustomEvent<DateSelectEvent>): void {
165
225
  this.value = event.detail.date
166
- this._isOpen = false
167
- this._dispatchChangeEvent()
226
+ this.isOpen = false
227
+ this.dispatchChangeEvent()
168
228
  }
169
229
 
170
- private _handleCalendarDateCancel(): void {
171
- this._isOpen = false
230
+ private handleCalendarDateCancel(): void {
231
+ this.isOpen = false
172
232
  }
173
233
 
174
- private _handleKeyDown(event: KeyboardEvent): void {
234
+ private handleKeyDown(event: KeyboardEvent): void {
175
235
  switch (event.key) {
176
236
  case 'Escape':
177
- this._isOpen = false
237
+ this.isOpen = false
178
238
  break
179
239
  case 'ArrowDown':
180
- if (!this._isOpen) {
240
+ if (!this.isOpen) {
181
241
  event.preventDefault()
182
- this._isOpen = true
242
+ this.isOpen = true
183
243
  }
184
244
  break
185
245
  case 'Enter':
186
- if (this._isOpen) {
246
+ if (this.isOpen) {
187
247
  event.preventDefault()
188
- this._isOpen = false
248
+ this.isOpen = false
189
249
  }
190
250
  break
191
251
  }
192
252
  }
193
253
 
194
- private _dispatchChangeEvent(): void {
254
+ private dispatchChangeEvent(): void {
195
255
  this.dispatchEvent(
196
256
  new CustomEvent('change', {
197
257
  detail: {
198
258
  value: this.value,
199
- formattedValue: this._inputValue,
259
+ formattedValue: this.inputValue,
200
260
  },
201
261
  bubbles: true,
202
262
  composed: true,
@@ -204,14 +264,14 @@ export class UiDatePickerInput extends LitElement {
204
264
  )
205
265
  }
206
266
 
207
- private _renderCalendarIcon(): TemplateResult {
267
+ private renderCalendarIcon(): TemplateResult {
208
268
  return html`
209
- <ui-icon slot="suffix" icon="calendarToday" @click=${this._handleInputClick} style="cursor: pointer;"></ui-icon>
269
+ <ui-icon slot="suffix" icon="calendarToday" @click=${this.handleInputClick} class="calendar-icon"></ui-icon>
210
270
  `
211
271
  }
212
272
 
213
- private _renderDropdown(): TemplateResult | null {
214
- if (!this._isOpen) return null
273
+ private renderDropdown(): TemplateResult | null {
274
+ if (!this.isOpen) return null
215
275
 
216
276
  const currentDate = this.value || new Date()
217
277
 
@@ -226,8 +286,8 @@ export class UiDatePickerInput extends LitElement {
226
286
  .disabledDates=${this.disabledDates}
227
287
  .locale=${this.locale}
228
288
  showActions
229
- @date-select=${this._handleCalendarDateSelect}
230
- @date-cancel=${this._handleCalendarDateCancel}
289
+ @date-select=${this.handleCalendarDateSelect}
290
+ @date-cancel=${this.handleCalendarDateCancel}
231
291
  ></ui-date-picker-calendar>
232
292
  </div>
233
293
  `
@@ -236,23 +296,24 @@ export class UiDatePickerInput extends LitElement {
236
296
  override render(): TemplateResult {
237
297
  return html`
238
298
  <div class="input-container">
239
- ${this._isOpen ? html`<div class="backdrop" @click=${() => (this._isOpen = false)}></div>` : ''}
299
+ ${this.isOpen ? html`<div class="backdrop" @click=${() => (this.isOpen = false)}></div>` : ''}
240
300
  <ui-outlined-text-field
241
301
  .label=${this.label}
302
+ .name=${this.name}
242
303
  .placeholder=${this.placeholder}
243
- .value=${this._inputValue}
304
+ .value=${this.inputValue}
244
305
  .disabled=${this.disabled}
245
306
  .required=${this.required}
246
- .errorMessage=${this.errorMessage}
247
- .error=${this.error}
307
+ ?invalid=${this.error}
308
+ .invalidText=${this.errorMessage}
248
309
  readonly
249
- @click=${this._handleInputClick}
250
- @input=${this._handleInputChange}
251
- @keydown=${this._handleKeyDown}
310
+ @click=${this.handleInputClick}
311
+ @input=${this.handleInputChange}
312
+ @keydown=${this.handleKeyDown}
252
313
  >
253
- ${this._renderCalendarIcon()}
314
+ ${this.renderCalendarIcon()}
254
315
  </ui-outlined-text-field>
255
- ${this._renderDropdown()}
316
+ ${this.renderDropdown()}
256
317
  </div>
257
318
  `
258
319
  }