fancy-ui-ts 1.1.1 → 1.3.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.
- package/dist/index.css +15 -6
- package/dist/index.d.ts +80 -4
- package/dist/index.js +663 -67
- package/package.json +15 -1
package/dist/index.css
CHANGED
|
@@ -94,13 +94,13 @@
|
|
|
94
94
|
--fc-option-bg: var(--fc-white);
|
|
95
95
|
--fc-option-bg-disabled: var(--fc-gray-50);
|
|
96
96
|
--fc-option-bg-hover: var(--fc-gray-100);
|
|
97
|
-
--fc-option-bg-selected: var(--fc-primary-200);
|
|
98
97
|
--fc-option-bg-active: var(--fc-primary-100);
|
|
99
98
|
--fc-option-fg: var(--fc-gray-900);
|
|
100
99
|
--fc-option-fg-disabled: var(--fc-gray-300);
|
|
101
|
-
--fc-option-fg-selected: var(--fc-primary-700);
|
|
102
100
|
--fc-option-padding: var(--fc-space-3);
|
|
103
101
|
--fc-option-radius: var(--fc-radius-md);
|
|
102
|
+
--fc-option-icon-width: calc(var(--fc-font-size-md) + 1px);
|
|
103
|
+
--fc-option-icon-height: calc(var(--fc-font-size-md) + 1px);
|
|
104
104
|
--fc-input-bg: var(--fc-white);
|
|
105
105
|
--fc-input-bg-disabled: var(--fc-gray-50);
|
|
106
106
|
--fc-input-fg: var(--fc-gray-900);
|
|
@@ -115,6 +115,8 @@
|
|
|
115
115
|
--fc-input-focus-ring-error: var(--fc-focus-ring-danger);
|
|
116
116
|
--fc-input-password-icon-color: var(--fc-gray-400);
|
|
117
117
|
--fc-input-password-icon-color-hover: var(--fc-gray-500);
|
|
118
|
+
--fc-input-password-icon-width: calc(var(--fc-font-size-md) + 2px);
|
|
119
|
+
--fc-input-password-icon-height: calc(var(--fc-font-size-md) + 2px);
|
|
118
120
|
--fc-input-file-border: var(--fc-gray-400);
|
|
119
121
|
--fc-input-file-border-hover: var(--fc-gray-400);
|
|
120
122
|
--fc-input-file-btn-bg: var(--fc-gray-400);
|
|
@@ -129,6 +131,11 @@
|
|
|
129
131
|
--fc-error-fg: var(--fc-danger-300);
|
|
130
132
|
--fc-error-max-width: fit-content;
|
|
131
133
|
--fc-error-font-size: var(--fc-font-size-sm);
|
|
134
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
135
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
136
|
+
--fc-label-fg: var(--fc-gray-900);
|
|
137
|
+
--fc-select-dropdown-icon-width: calc(var(--fc-font-size-md) + 4px);
|
|
138
|
+
--fc-select-dropdown-icon-height: calc(var(--fc-font-size-md) + 4px);
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
/* src/styles/themes/fc-theme-light.css */
|
|
@@ -149,11 +156,9 @@
|
|
|
149
156
|
--fc-option-bg: var(--fc-white);
|
|
150
157
|
--fc-option-bg-disabled: var(--fc-gray-50);
|
|
151
158
|
--fc-option-bg-hover: var(--fc-gray-100);
|
|
152
|
-
--fc-option-bg-selected: var(--fc-primary-200);
|
|
153
159
|
--fc-option-bg-active: var(--fc-primary-100);
|
|
154
160
|
--fc-option-fg: var(--fc-gray-900);
|
|
155
161
|
--fc-option-fg-disabled: var(--fc-gray-300);
|
|
156
|
-
--fc-option-fg-selected: var(--fc-primary-700);
|
|
157
162
|
--fc-input-bg: var(--fc-white);
|
|
158
163
|
--fc-input-bg-disabled: var(--fc-gray-50);
|
|
159
164
|
--fc-input-fg: var(--fc-gray-900);
|
|
@@ -180,6 +185,9 @@
|
|
|
180
185
|
--fc-input-radius: var(--fc-radius-md);
|
|
181
186
|
--fc-input-shadow: var(--fc-shadow-none);
|
|
182
187
|
--fc-error-fg: var(--fc-danger-300);
|
|
188
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
189
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
190
|
+
--fc-label-fg: var(--fc-gray-900);
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
/* src/styles/themes/fc-theme-dark.css */
|
|
@@ -201,10 +209,8 @@
|
|
|
201
209
|
--fc-option-bg-disabled: var(--fc-gray-900);
|
|
202
210
|
--fc-option-bg-hover: var(--fc-gray-700);
|
|
203
211
|
--fc-option-bg-active: var(--fc-primary-500);
|
|
204
|
-
--fc-option-bg-selected: var(--fc-primary-600);
|
|
205
212
|
--fc-option-fg: var(--fc-gray-200);
|
|
206
213
|
--fc-option-fg-disabled: var(--fc-gray-700);
|
|
207
|
-
--fc-option-fg-selected: var(--fc-primary-50);
|
|
208
214
|
--fc-input-bg: var(--fc-gray-800);
|
|
209
215
|
--fc-input-bg-disabled: var(--fc-gray-900);
|
|
210
216
|
--fc-input-fg: var(--fc-gray-200);
|
|
@@ -231,4 +237,7 @@
|
|
|
231
237
|
--fc-input-radius: var(--fc-radius-md);
|
|
232
238
|
--fc-input-shadow: var(--fc-shadow-none);
|
|
233
239
|
--fc-error-fg: var(--fc-danger-700);
|
|
240
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
241
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
242
|
+
--fc-label-fg: var(--fc-gray-200);
|
|
234
243
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -57,9 +57,8 @@ declare class FcCombobox extends HTMLElement {
|
|
|
57
57
|
private onBlur;
|
|
58
58
|
private onInvalid;
|
|
59
59
|
private setActiveOption;
|
|
60
|
-
private
|
|
61
|
-
private
|
|
62
|
-
private toggleDropdown;
|
|
60
|
+
private showDropdown;
|
|
61
|
+
private hideDropdown;
|
|
63
62
|
private syncValidity;
|
|
64
63
|
setProps(props: Record<string, any>): void;
|
|
65
64
|
}
|
|
@@ -168,6 +167,83 @@ declare class FcError extends HTMLElement {
|
|
|
168
167
|
|
|
169
168
|
declare const defineError: () => typeof FcError;
|
|
170
169
|
|
|
170
|
+
declare class FcLabel extends HTMLElement {
|
|
171
|
+
static get observedAttributes(): string[];
|
|
172
|
+
constructor();
|
|
173
|
+
connectedCallback(): void;
|
|
174
|
+
disconnectedCallback(): void;
|
|
175
|
+
attributeChangedCallback(name: string, _oldVal: string, newVal: string): void;
|
|
176
|
+
get htmlFor(): string;
|
|
177
|
+
set htmlFor(val: string);
|
|
178
|
+
private onClick;
|
|
179
|
+
setProps(props: Record<string, any>): void;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
declare const defineLabel: () => typeof FcLabel;
|
|
183
|
+
|
|
184
|
+
declare class FcSelect extends HTMLElement {
|
|
185
|
+
static get observedAttributes(): string[];
|
|
186
|
+
private inputEl;
|
|
187
|
+
private dropdownEl;
|
|
188
|
+
static formAssociated: boolean;
|
|
189
|
+
private internals;
|
|
190
|
+
private _value;
|
|
191
|
+
private activeIndex;
|
|
192
|
+
private searchBuffer;
|
|
193
|
+
private searchTimeout;
|
|
194
|
+
constructor();
|
|
195
|
+
get validity(): ValidityState;
|
|
196
|
+
get validationMessage(): string;
|
|
197
|
+
get willValidate(): boolean;
|
|
198
|
+
checkValidity(): boolean;
|
|
199
|
+
reportValidity(): boolean;
|
|
200
|
+
get placeholder(): string;
|
|
201
|
+
set placeholder(val: string);
|
|
202
|
+
get name(): string;
|
|
203
|
+
set name(val: string);
|
|
204
|
+
get disabled(): boolean;
|
|
205
|
+
set disabled(val: boolean);
|
|
206
|
+
get value(): string;
|
|
207
|
+
set value(newValue: string);
|
|
208
|
+
get label(): string;
|
|
209
|
+
get options(): {
|
|
210
|
+
label: string;
|
|
211
|
+
value: string;
|
|
212
|
+
disabled?: boolean;
|
|
213
|
+
}[];
|
|
214
|
+
set options(data: {
|
|
215
|
+
label: string;
|
|
216
|
+
value: string;
|
|
217
|
+
disabled?: boolean;
|
|
218
|
+
}[]);
|
|
219
|
+
get required(): boolean;
|
|
220
|
+
set required(val: boolean);
|
|
221
|
+
get readonly(): boolean;
|
|
222
|
+
connectedCallback(): void;
|
|
223
|
+
attributeChangedCallback(name: string, _old: string, newVal: string): void;
|
|
224
|
+
disconnectedCallback(): void;
|
|
225
|
+
formResetCallback(): void;
|
|
226
|
+
formStateRestoreCallback(state: string | File | FormData | null, mode: 'restore' | 'autocomplete'): void;
|
|
227
|
+
private onClick;
|
|
228
|
+
private onChange;
|
|
229
|
+
private onOptionSelect;
|
|
230
|
+
private onOutsideClick;
|
|
231
|
+
private onFocusOut;
|
|
232
|
+
private onSlotChange;
|
|
233
|
+
private onKeyDown;
|
|
234
|
+
private handleTypeAhead;
|
|
235
|
+
private onBlur;
|
|
236
|
+
private onInvalid;
|
|
237
|
+
private setActiveOption;
|
|
238
|
+
private getVisibleOptions;
|
|
239
|
+
private selectOption;
|
|
240
|
+
private toggleDropdown;
|
|
241
|
+
private syncValidity;
|
|
242
|
+
setProps(props: Record<string, any>): void;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
declare const defineSelect: () => typeof FcSelect;
|
|
246
|
+
|
|
171
247
|
declare const defineAll: () => void;
|
|
172
248
|
|
|
173
|
-
export { FcCombobox, FcError, FcInput, FcOption, defineAll, defineCombobox, defineError, defineInput, defineOption };
|
|
249
|
+
export { FcCombobox, FcError, FcInput, FcLabel, FcOption, FcSelect, defineAll, defineCombobox, defineError, defineInput, defineLabel, defineOption, defineSelect };
|
package/dist/index.js
CHANGED
|
@@ -185,7 +185,6 @@ var FcCombobox = class extends HTMLElement {
|
|
|
185
185
|
this.inputEl.addEventListener("input", this.onInput);
|
|
186
186
|
this.inputEl.addEventListener("change", this.onChange);
|
|
187
187
|
this.addEventListener("fc-option-select", this.onOptionSelect);
|
|
188
|
-
document.addEventListener("click", this.onOutsideClick);
|
|
189
188
|
this.addEventListener("focusout", this.onFocusOut);
|
|
190
189
|
this.inputEl.addEventListener("focus", this.onFocus);
|
|
191
190
|
this.inputEl.addEventListener("blur", this.onBlur);
|
|
@@ -210,7 +209,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
210
209
|
this.inputEl.disabled = isDisabled;
|
|
211
210
|
this.internals.ariaDisabled = isDisabled ? "true" : "false";
|
|
212
211
|
if (isDisabled) {
|
|
213
|
-
this.
|
|
212
|
+
this.hideDropdown();
|
|
214
213
|
}
|
|
215
214
|
}
|
|
216
215
|
if (name === "required" && this.inputEl) {
|
|
@@ -240,7 +239,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
240
239
|
option.selected = false;
|
|
241
240
|
option.hidden = false;
|
|
242
241
|
});
|
|
243
|
-
this.
|
|
242
|
+
this.hideDropdown();
|
|
244
243
|
this.removeAttribute("touched");
|
|
245
244
|
this.syncValidity();
|
|
246
245
|
this.dispatchEvent(new CustomEvent("fc-reset", {
|
|
@@ -287,7 +286,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
287
286
|
this._value = "";
|
|
288
287
|
this.internals.setFormValue("");
|
|
289
288
|
this.inputEl.removeAttribute("aria-activedescendant");
|
|
290
|
-
this.
|
|
289
|
+
this.showDropdown();
|
|
291
290
|
this.syncValidity();
|
|
292
291
|
this.dispatchEvent(new CustomEvent("fc-input", {
|
|
293
292
|
detail: {
|
|
@@ -331,7 +330,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
331
330
|
bubbles: true,
|
|
332
331
|
composed: true
|
|
333
332
|
}));
|
|
334
|
-
this.
|
|
333
|
+
hasMatch ? this.showDropdown() : this.hideDropdown();
|
|
335
334
|
}
|
|
336
335
|
onChange(e) {
|
|
337
336
|
e.stopPropagation();
|
|
@@ -359,7 +358,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
359
358
|
option.hidden = !selected;
|
|
360
359
|
option.active = false;
|
|
361
360
|
});
|
|
362
|
-
this.
|
|
361
|
+
this.hideDropdown();
|
|
363
362
|
this.syncValidity();
|
|
364
363
|
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
365
364
|
detail: {
|
|
@@ -372,12 +371,13 @@ var FcCombobox = class extends HTMLElement {
|
|
|
372
371
|
}
|
|
373
372
|
onOutsideClick(e) {
|
|
374
373
|
if (!this.contains(e.target)) {
|
|
375
|
-
this.
|
|
374
|
+
this.hideDropdown();
|
|
376
375
|
}
|
|
377
376
|
}
|
|
378
377
|
onFocusOut(e) {
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
const target = e.relatedTarget;
|
|
379
|
+
if (!target || !this.contains(target)) {
|
|
380
|
+
this.hideDropdown();
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
383
|
onFocus(e) {
|
|
@@ -390,7 +390,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
390
390
|
const label = (option.getAttribute("label") || option.textContent || "").toLowerCase();
|
|
391
391
|
return label.includes(query);
|
|
392
392
|
});
|
|
393
|
-
this.
|
|
393
|
+
match ? this.showDropdown() : this.hideDropdown();
|
|
394
394
|
}
|
|
395
395
|
onSlotChange() {
|
|
396
396
|
if (!this._value) {
|
|
@@ -410,7 +410,7 @@ var FcCombobox = class extends HTMLElement {
|
|
|
410
410
|
if (!foundMatch && this.inputEl.value === "") {
|
|
411
411
|
this.inputEl.value = this._value;
|
|
412
412
|
options.forEach(option => {
|
|
413
|
-
const match = option.label.includes(this._value);
|
|
413
|
+
const match = option.label.toLowerCase().includes(this._value.toLowerCase());
|
|
414
414
|
option.hidden = !match;
|
|
415
415
|
});
|
|
416
416
|
}
|
|
@@ -420,31 +420,50 @@ var FcCombobox = class extends HTMLElement {
|
|
|
420
420
|
if (this.disabled) {
|
|
421
421
|
return;
|
|
422
422
|
}
|
|
423
|
-
const options = this.
|
|
424
|
-
|
|
423
|
+
const options = this.querySelectorAll("fc-option");
|
|
424
|
+
const visibleOptions = Array.from(options).filter(opt => !opt.hidden && !opt.disabled);
|
|
425
|
+
if (visibleOptions.length === 0) {
|
|
425
426
|
return;
|
|
426
427
|
}
|
|
427
428
|
if (e.key === "ArrowDown") {
|
|
428
429
|
e.preventDefault();
|
|
429
|
-
this.
|
|
430
|
-
const nextIndex = this.activeIndex >=
|
|
430
|
+
this.showDropdown();
|
|
431
|
+
const nextIndex = this.activeIndex >= visibleOptions.length - 1 ? 0 : this.activeIndex + 1;
|
|
431
432
|
this.setActiveOption(nextIndex, options);
|
|
432
433
|
} else if (e.key === "ArrowUp") {
|
|
433
434
|
e.preventDefault();
|
|
434
|
-
this.
|
|
435
|
-
const prevIndex = this.activeIndex <= 0 ?
|
|
435
|
+
this.showDropdown();
|
|
436
|
+
const prevIndex = this.activeIndex <= 0 ? visibleOptions.length - 1 : this.activeIndex - 1;
|
|
436
437
|
this.setActiveOption(prevIndex, options);
|
|
437
438
|
} else if (e.key === "Enter") {
|
|
438
439
|
e.preventDefault();
|
|
439
|
-
if (this.activeIndex > -1 &&
|
|
440
|
-
const target =
|
|
441
|
-
this.
|
|
440
|
+
if (this.activeIndex > -1 && visibleOptions[this.activeIndex]) {
|
|
441
|
+
const target = visibleOptions[this.activeIndex];
|
|
442
|
+
this.inputEl.value = target.label;
|
|
443
|
+
this._value = target.value;
|
|
444
|
+
this.internals.setFormValue(target.value);
|
|
445
|
+
options.forEach(option => {
|
|
446
|
+
const selected = option.value === target.value;
|
|
447
|
+
option.selected = selected;
|
|
448
|
+
option.hidden = !selected;
|
|
449
|
+
option.active = false;
|
|
450
|
+
});
|
|
451
|
+
this.hideDropdown();
|
|
452
|
+
this.syncValidity();
|
|
453
|
+
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
454
|
+
detail: {
|
|
455
|
+
value: target.value,
|
|
456
|
+
label: target.label
|
|
457
|
+
},
|
|
458
|
+
bubbles: true,
|
|
459
|
+
composed: true
|
|
460
|
+
}));
|
|
442
461
|
}
|
|
443
462
|
} else if (e.key === "Escape") {
|
|
444
463
|
e.preventDefault();
|
|
445
|
-
this.
|
|
464
|
+
this.hideDropdown();
|
|
446
465
|
} else if (e.key === "Tab") {
|
|
447
|
-
this.
|
|
466
|
+
this.hideDropdown();
|
|
448
467
|
}
|
|
449
468
|
}
|
|
450
469
|
onBlur() {
|
|
@@ -452,10 +471,18 @@ var FcCombobox = class extends HTMLElement {
|
|
|
452
471
|
}
|
|
453
472
|
onInvalid(e) {
|
|
454
473
|
this.setAttribute("touched", "");
|
|
474
|
+
this.dispatchEvent(new CustomEvent("fc-invalid", {
|
|
475
|
+
bubbles: true,
|
|
476
|
+
composed: true,
|
|
477
|
+
detail: {
|
|
478
|
+
originalEvent: e
|
|
479
|
+
}
|
|
480
|
+
}));
|
|
455
481
|
}
|
|
456
|
-
setActiveOption(index,
|
|
457
|
-
|
|
482
|
+
setActiveOption(index, allOptions) {
|
|
483
|
+
allOptions.forEach(opt => opt.active = false);
|
|
458
484
|
this.activeIndex = index;
|
|
485
|
+
const visibleOptions = Array.from(allOptions).filter(opt => !opt.hidden && !opt.disabled);
|
|
459
486
|
const target = visibleOptions[index];
|
|
460
487
|
if (target) {
|
|
461
488
|
target.active = true;
|
|
@@ -468,51 +495,43 @@ var FcCombobox = class extends HTMLElement {
|
|
|
468
495
|
}
|
|
469
496
|
this.inputEl.removeAttribute("aria-activedescendant");
|
|
470
497
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
selectOption(option) {
|
|
475
|
-
const value = option.value;
|
|
476
|
-
const label = option.label;
|
|
477
|
-
this.inputEl.value = label;
|
|
478
|
-
this._value = value;
|
|
479
|
-
this.internals.setFormValue(value);
|
|
480
|
-
const allOptions = this.querySelectorAll("fc-option");
|
|
481
|
-
allOptions.forEach(opt => {
|
|
482
|
-
const selected = opt.value === value;
|
|
483
|
-
opt.selected = selected;
|
|
484
|
-
opt.hidden = !selected;
|
|
485
|
-
opt.active = false;
|
|
486
|
-
});
|
|
487
|
-
this.toggleDropdown(false);
|
|
488
|
-
this.syncValidity();
|
|
489
|
-
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
490
|
-
detail: {
|
|
491
|
-
value: value,
|
|
492
|
-
label: label
|
|
493
|
-
},
|
|
494
|
-
bubbles: true,
|
|
495
|
-
composed: true
|
|
496
|
-
}));
|
|
497
|
-
}
|
|
498
|
-
toggleDropdown(show) {
|
|
499
|
-
if (!this.dropdownEl) {
|
|
498
|
+
showDropdown() {
|
|
499
|
+
if (!this.dropdownEl || this.disabled) {
|
|
500
500
|
return;
|
|
501
501
|
}
|
|
502
|
-
|
|
502
|
+
const dropdown = this.dropdownEl;
|
|
503
|
+
const showEvent = new CustomEvent("fc-show", {
|
|
504
|
+
bubbles: true,
|
|
505
|
+
composed: true,
|
|
506
|
+
cancelable: true
|
|
507
|
+
});
|
|
508
|
+
this.dispatchEvent(showEvent);
|
|
509
|
+
if (showEvent.defaultPrevented) {
|
|
503
510
|
return;
|
|
504
511
|
}
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
512
|
+
const spaceBelow = calculateBottomAvaliableSpace(this.inputEl);
|
|
513
|
+
const spaceAbove = calculateTopAvaliableSpace(this.inputEl);
|
|
514
|
+
dropdown.hidden = false;
|
|
515
|
+
this.setAttribute("open", "true");
|
|
516
|
+
this.inputEl.setAttribute("aria-expanded", "true");
|
|
517
|
+
const shouldOpenUp = spaceBelow < dropdown.clientHeight && spaceAbove > spaceBelow;
|
|
518
|
+
dropdown.classList.toggle("opens-up", shouldOpenUp);
|
|
519
|
+
setTimeout(() => {
|
|
520
|
+
document.addEventListener("click", this.onOutsideClick);
|
|
521
|
+
}, 0);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
hideDropdown() {
|
|
525
|
+
if (!this.dropdownEl) {
|
|
514
526
|
return;
|
|
515
527
|
}
|
|
528
|
+
if (!this.dropdownEl.hidden) {
|
|
529
|
+
this.dispatchEvent(new CustomEvent("fc-hide", {
|
|
530
|
+
bubbles: true,
|
|
531
|
+
composed: true
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
document.removeEventListener("click", this.onOutsideClick);
|
|
516
535
|
this.dropdownEl.hidden = true;
|
|
517
536
|
this.removeAttribute("open");
|
|
518
537
|
this.inputEl.setAttribute("aria-expanded", "false");
|
|
@@ -577,11 +596,11 @@ var defineCombobox = () => {
|
|
|
577
596
|
return FcCombobox;
|
|
578
597
|
};
|
|
579
598
|
|
|
580
|
-
var styles2 = `\n\t:host {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t}\n\n\t:host([hidden]) {\n display: none !important;\n }\n\n\t:host([disabled]) {\n cursor: not-allowed;\n }\n\t\t\n\
|
|
599
|
+
var styles2 = `\n\t:host {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t}\n\n\t:host([hidden]) {\n display: none !important;\n }\n\n\t:host([disabled]) {\n cursor: not-allowed;\n }\n\t\t\n\tbutton.fc-option {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\t\ttext-align: left;\n\t\tbackground: var(--fc-option-bg);\n\t\tcolor: var(--fc-option-fg);\n\t\tpadding: var(--fc-option-padding);\n\t\tborder-radius: var(--fc-option-radius);\n\t\tborder: none;\n\t\tfont: inherit;\n\t\tcursor: pointer;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\n\t\tdisplay: flex;\n justify-content: space-between;\n align-items: center;\n\t}\n\n\t.fc-option-text {\n flex-grow: 1;\n\t\tfont-size: var(--fc-font-size-md);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-right: 12px;\n }\n\n .fc-option-icon {\n display: none;\n align-items: center;\n\t\tjustify-content: center;\n color: inherit; \n }\n\t\n\t.fc-option-icon svg {\n\t\twidth: var(--fc-option-icon-width);\n\t\theight: var(--fc-option-icon-height);\n }\n\n\tbutton.fc-option:hover {\n\t\tbackground: var(--fc-option-bg-hover);\n\t\ttransition: background 0.15s ease-in-out, color 0.15s ease-in-out;\n\t}\n\n\tbutton.fc-option[data-active="true"] { \n background: var(--fc-option-bg-active);\n }\n\n\tbutton.fc-option:disabled {\n\t\tcolor: var(--fc-option-fg-disabled);\n\t\tbackground: var(--fc-option-bg-disabled);\n\t\tpointer-events: none; // this prevents disabled attribute on button to move focus out of the fc-combobox\n\t\tbox-shadow: none;\n\t}\n\n button.fc-option:disabled:hover {\n\t\tbackground: var(--fc-option-bg-disabled);\n\t}\n\n\tbutton.fc-option[aria-selected="true"] .fc-option-icon {\n display: flex;\n }\n\n`;
|
|
581
600
|
|
|
582
601
|
var template2 = document.createElement("template");
|
|
583
602
|
|
|
584
|
-
template2.innerHTML = `\n
|
|
603
|
+
template2.innerHTML = `\n <style>${styles2}</style>\n \n <button part="container" class="fc-option" role="option">\n \n <span class="fc-option-text" part="text">\n <slot></slot>\n </span>\n\n <span class="fc-option-icon" part="icon" aria-hidden="true">\n <slot name="checked-icon">\n\t\t\t\t<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">\n <polyline points="20 6.5 9 17.5 4 12.5"></polyline>\n </svg>\n </slot>\n </span>\n\n </button>\n`;
|
|
585
604
|
|
|
586
605
|
var FcOption = class extends HTMLElement {
|
|
587
606
|
static get observedAttributes() {
|
|
@@ -717,7 +736,7 @@ var defineOption = () => {
|
|
|
717
736
|
return FcOption;
|
|
718
737
|
};
|
|
719
738
|
|
|
720
|
-
var styles3 = `\n\t:host {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t\tmax-width: var(--fc-input-max-width);\n\t}\n\n\t:host([disabled]) {\n\t\tcursor: not-allowed;\n\t}\n\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n\n\t/* only show invalid style if the user has touched the field (blurred). the :invalid pseudo-class comes from \n\tinternals.setValidity() logic. */\n\n\t:host([touched]:invalid) .fc-input-field {\n\t\tbackground: var(--fc-input-bg-error);\n\t\tborder-color: var(--fc-input-border-error);\n\t}\n\n\t:host([touched]:invalid) .fc-input-field:focus {\n\t\tbox-shadow: 0 0 0 2px var(--fc-input-focus-ring-error);\n\t}\n\n\t.fc-input-wrapper {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\twidth: 100%;\n\t}\n\n\t.fc-input-field {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\n\t\tpadding: var(--fc-input-padding);\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-bg);\n\t\tcolor: var(--fc-input-fg);\n\n\t\tborder: var(--fc-input-border-width) solid var(--fc-input-border);\n\n\t\tfont-size: var(--fc-font-size-md);\n\n\t\tbox-shadow: var(--fc-input-shadow);\n\t\ttransition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n\t\tfont-family: inherit;\n\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t}\n\n\t.fc-input-field::placeholder {\n\t\tcolor: var(--fc-input-placeholder);\n\t}\n\n\t.fc-input-field:hover {\n\t\tborder-color: var(--fc-input-border-hover);\n\t}\n\n\t.fc-input-field:focus {\n\t\tborder-color: var(--fc-input-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-input-focus-ring);\n\t}\n\n\t.fc-input-field:disabled {\n\t\tbackground: var(--fc-input-bg-disabled);\n\t\tcursor: not-allowed;\n\t\tbox-shadow: none;\n\t}\n\n\t.fc-input-field:disabled::placeholder {\n\t\tcolor: var(--fc-input-placeholder-disabled);\n }\n\n\t.fc-input-field:disabled:hover {\n\t\tborder-color: var(--fc-input-border);\n\t}\n\n\t.fc-input-field:disabled:focus {\n\t\tborder-color: var(--fc-input-border);\n\t}\n\t\t\n\t/* FILE type specific CSS */\n\n\t.fc-input-field[type="file"] {\n\t\tpadding: calc(var(--fc-input-padding));\n\t\tcursor: pointer;\n\t\tdisplay: flex; \n \talign-items: center;\n\t\tborder-color: var(--fc-input-file-border);\n\t\ttransition: border-color 0.15s ease-in-out, color 0.15s ease-in-out;\n\t}\n\n\t.fc-input-field[type="file"]:focus {\n\t\tborder-color: var(--fc-input-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-input-focus-ring);\n\t}\n\n\t/* target the button inside type="file" */\n\n\t.fc-input-field::file-selector-button {\n\t\tpadding: 4px 10px;\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-btn-bg);\n\t\tcolor: var(--fc-input-file-btn-fg);\n\t\tborder: 1px solid var(--fc-input-file-border);\n\t\tcursor: pointer;\n\t\tfont-family: inherit;\n\t\ttransition: background-color 0.15s ease;\n\t}\n\n\t/* legacy browsers */\n\t.fc-input-field::-webkit-file-upload-button {\n\t\tmargin-right: 12px;\n\t\tpadding: 4px 10px;\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-file-btn-bg);\n\t\tcolor: var(--fc-input-file-btn-fg);\n\t\tborder: 1px solid var(--fc-input-file-border);\n\t\tcursor: pointer;\n\t\tfont-family: inherit;\n\t\tfont-size: 0.9em;\n\t}\n\n\t/* Hover effects for the button */\n\n\t.fc-input-field::file-selector-button:hover {\n\t\tbackground: var(--fc-input-file-btn-bg-hover); \n\t}\n\n\n\t.fc-input-field::-webkit-file-upload-button:hover {\n\t\tbackground: var(--fc-input-file-btn-bg-hover);\n\t}\n\n\t/* PASSWORD type specific CSS */\n\n\t/* when password toggle is visible, add padding to input so text doesn't overlap icon */\n\t:host([type="password"]) .fc-input-field {\n\t\tpadding-right: 40px; \n\t}\n\n\t.fc-password-toggle {\n\t\tposition: absolute;\n\t\tright: 8px; /* position inside the input */\n\t\ttop: 50%;\n\t\ttransform: translateY(-50%);\n\t\tbackground: transparent;\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tcolor: var(--fc-input-password-icon-color);\n\t\ttransition: color 0.15s ease-in-out;\n\t\tz-index: 2; /* above input */\n\t}\n\t\n\t.fc-password-toggle[hidden] {\n display: none !important;\n }\n\n\t.fc-password-toggle:hover {\n\t\tcolor: var(--fc-input-password-icon-color-hover);\n\t}\n\t\n\t.fc-password-toggle svg {\n\t\twidth:
|
|
739
|
+
var styles3 = `\n\t:host {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t\tmax-width: var(--fc-input-max-width);\n\t}\n\n\t:host([disabled]) {\n\t\tcursor: not-allowed;\n\t}\n\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n\n\t/* only show invalid style if the user has touched the field (blurred). the :invalid pseudo-class comes from \n\tinternals.setValidity() logic. */\n\n\t:host([touched]:invalid) .fc-input-field {\n\t\tbackground: var(--fc-input-bg-error);\n\t\tborder-color: var(--fc-input-border-error);\n\t}\n\n\t:host([touched]:invalid) .fc-input-field:focus {\n\t\tbox-shadow: 0 0 0 2px var(--fc-input-focus-ring-error);\n\t}\n\n\t.fc-input-wrapper {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\twidth: 100%;\n\t}\n\n\t.fc-input-field {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\n\t\tpadding: var(--fc-input-padding);\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-bg);\n\t\tcolor: var(--fc-input-fg);\n\n\t\tborder: var(--fc-input-border-width) solid var(--fc-input-border);\n\n\t\tfont-size: var(--fc-font-size-md);\n\n\t\tbox-shadow: var(--fc-input-shadow);\n\t\ttransition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n\t\tfont-family: inherit;\n\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t}\n\n\t.fc-input-field::placeholder {\n\t\tcolor: var(--fc-input-placeholder);\n\t}\n\n\t.fc-input-field:hover {\n\t\tborder-color: var(--fc-input-border-hover);\n\t}\n\n\t.fc-input-field:focus {\n\t\tborder-color: var(--fc-input-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-input-focus-ring);\n\t}\n\n\t.fc-input-field:disabled {\n\t\tbackground: var(--fc-input-bg-disabled);\n\t\tcursor: not-allowed;\n\t\tbox-shadow: none;\n\t}\n\n\t.fc-input-field:disabled::placeholder {\n\t\tcolor: var(--fc-input-placeholder-disabled);\n }\n\n\t.fc-input-field:disabled:hover {\n\t\tborder-color: var(--fc-input-border);\n\t}\n\n\t.fc-input-field:disabled:focus {\n\t\tborder-color: var(--fc-input-border);\n\t}\n\t\t\n\t/* FILE type specific CSS */\n\n\t.fc-input-field[type="file"] {\n\t\tpadding: calc(var(--fc-input-padding));\n\t\tcursor: pointer;\n\t\tdisplay: flex; \n \talign-items: center;\n\t\tborder-color: var(--fc-input-file-border);\n\t\ttransition: border-color 0.15s ease-in-out, color 0.15s ease-in-out;\n\t}\n\n\t.fc-input-field[type="file"]:focus {\n\t\tborder-color: var(--fc-input-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-input-focus-ring);\n\t}\n\n\t/* target the button inside type="file" */\n\n\t.fc-input-field::file-selector-button {\n\t\tpadding: 4px 10px;\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-btn-bg);\n\t\tcolor: var(--fc-input-file-btn-fg);\n\t\tborder: 1px solid var(--fc-input-file-border);\n\t\tcursor: pointer;\n\t\tfont-family: inherit;\n\t\ttransition: background-color 0.15s ease;\n\t}\n\n\t/* legacy browsers */\n\t.fc-input-field::-webkit-file-upload-button {\n\t\tmargin-right: 12px;\n\t\tpadding: 4px 10px;\n\t\tborder-radius: var(--fc-input-radius);\n\t\tbackground: var(--fc-input-file-btn-bg);\n\t\tcolor: var(--fc-input-file-btn-fg);\n\t\tborder: 1px solid var(--fc-input-file-border);\n\t\tcursor: pointer;\n\t\tfont-family: inherit;\n\t\tfont-size: 0.9em;\n\t}\n\n\t/* Hover effects for the button */\n\n\t.fc-input-field::file-selector-button:hover {\n\t\tbackground: var(--fc-input-file-btn-bg-hover); \n\t}\n\n\n\t.fc-input-field::-webkit-file-upload-button:hover {\n\t\tbackground: var(--fc-input-file-btn-bg-hover);\n\t}\n\n\t/* PASSWORD type specific CSS */\n\n\t/* when password toggle is visible, add padding to input so text doesn't overlap icon */\n\t:host([type="password"]) .fc-input-field {\n\t\tpadding-right: 40px; \n\t}\n\n\t.fc-password-toggle {\n\t\tposition: absolute;\n\t\tright: 8px; /* position inside the input */\n\t\ttop: 50%;\n\t\ttransform: translateY(-50%);\n\t\tbackground: transparent;\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tcolor: var(--fc-input-password-icon-color);\n\t\ttransition: color 0.15s ease-in-out;\n\t\tz-index: 2; /* above input */\n\t}\n\t\n\t.fc-password-toggle[hidden] {\n display: none !important;\n }\n\n\t.fc-password-toggle:hover {\n\t\tcolor: var(--fc-input-password-icon-color-hover);\n\t}\n\t\n\t.fc-password-toggle svg {\n\t\twidth: var(--fc-input-password-icon-width);\n\t\theight: var(--fc-input-password-icon-height);\n\t}\n\n\t.fc-password-toggle svg[hidden] {\n display: none !important;\n }\n\n`;
|
|
721
740
|
|
|
722
741
|
var template3 = document.createElement("template");
|
|
723
742
|
|
|
@@ -1098,6 +1117,13 @@ var FcInput = class extends HTMLElement {
|
|
|
1098
1117
|
}
|
|
1099
1118
|
onInvalid(e) {
|
|
1100
1119
|
this.setAttribute("touched", "");
|
|
1120
|
+
this.dispatchEvent(new CustomEvent("fc-invalid", {
|
|
1121
|
+
bubbles: true,
|
|
1122
|
+
composed: true,
|
|
1123
|
+
detail: {
|
|
1124
|
+
originalEvent: e
|
|
1125
|
+
}
|
|
1126
|
+
}));
|
|
1101
1127
|
}
|
|
1102
1128
|
onTogglePassword(e) {
|
|
1103
1129
|
e.preventDefault();
|
|
@@ -1252,11 +1278,581 @@ var defineError = () => {
|
|
|
1252
1278
|
return FcError;
|
|
1253
1279
|
};
|
|
1254
1280
|
|
|
1281
|
+
var styles5 = `\n :host {\n display: block;\n width: 100%;\n box-sizing: border-box;\n font-family: var(--fc-font-family, inherit);\n font-size: var(--fc-label-font-size);\n font-weight: var(--fc-label-font-weight);\n color: var(--fc-label-fg);\n cursor: pointer;\n line-height: 1.5;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .fc-label-text {\n display: flex;\n align-items: center;\n }\n`;
|
|
1282
|
+
|
|
1283
|
+
var template5 = document.createElement("template");
|
|
1284
|
+
|
|
1285
|
+
template5.innerHTML = `\n <style>${styles5}</style>\n <div class="fc-label-text" part="text">\n <slot></slot>\n </div>\n`;
|
|
1286
|
+
|
|
1287
|
+
var FcLabel = class extends HTMLElement {
|
|
1288
|
+
static get observedAttributes() {
|
|
1289
|
+
return [ "for" ];
|
|
1290
|
+
}
|
|
1291
|
+
constructor() {
|
|
1292
|
+
super();
|
|
1293
|
+
const shadow = this.attachShadow({
|
|
1294
|
+
mode: "open"
|
|
1295
|
+
});
|
|
1296
|
+
shadow.appendChild(template5.content.cloneNode(true));
|
|
1297
|
+
this.onClick = this.onClick.bind(this);
|
|
1298
|
+
}
|
|
1299
|
+
connectedCallback() {
|
|
1300
|
+
this.addEventListener("click", this.onClick);
|
|
1301
|
+
}
|
|
1302
|
+
disconnectedCallback() {
|
|
1303
|
+
this.removeEventListener("click", this.onClick);
|
|
1304
|
+
}
|
|
1305
|
+
attributeChangedCallback(name, _oldVal, newVal) {}
|
|
1306
|
+
get htmlFor() {
|
|
1307
|
+
var _a;
|
|
1308
|
+
return (_a = this.getAttribute("for")) != null ? _a : "";
|
|
1309
|
+
}
|
|
1310
|
+
set htmlFor(val) {
|
|
1311
|
+
this.setAttribute("for", val);
|
|
1312
|
+
}
|
|
1313
|
+
onClick(e) {
|
|
1314
|
+
e.preventDefault();
|
|
1315
|
+
const targetId = this.getAttribute("for");
|
|
1316
|
+
if (!targetId) {
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
const targetEl = document.getElementById(targetId);
|
|
1320
|
+
if (targetEl) {
|
|
1321
|
+
targetEl.focus();
|
|
1322
|
+
targetEl.click();
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
setProps(props) {
|
|
1326
|
+
for (const property in props) {
|
|
1327
|
+
const value = props[property];
|
|
1328
|
+
if (property in this) {
|
|
1329
|
+
this[property] = value;
|
|
1330
|
+
continue;
|
|
1331
|
+
}
|
|
1332
|
+
if ([ "string", "number", "boolean" ].includes(typeof value)) {
|
|
1333
|
+
this.setAttribute(property, String(value));
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
var defineLabel = () => {
|
|
1340
|
+
if (!customElements.get("fc-label")) {
|
|
1341
|
+
customElements.define("fc-label", FcLabel);
|
|
1342
|
+
}
|
|
1343
|
+
return FcLabel;
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
var styles6 = `\n :host {\n display: block;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n font-family: var(--fc-font-family);\n max-width: var(--fc-combobox-max-width);\n cursor: pointer; \n }\n\n \n .fc-input {\n width: 100%;\n box-sizing: border-box;\n padding: var(--fc-combobox-padding);\n padding-right: 36px;\n \n border-radius: var(--fc-combobox-radius);\n background: var(--fc-combobox-bg);\n color: var(--fc-combobox-fg);\n border: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n font-size: var(--fc-font-size-md);\n box-shadow: var(--fc-combobox-shadow);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n \n cursor: pointer; \n caret-color: transparent; \n user-select: none;\n }\n\n \n :host([touched]:invalid) .fc-input {\n background-color: var(--fc-combobox-bg-error);\n border-color: var(--fc-combobox-border-error);\n }\n\n :host([touched]:invalid) .fc-input:focus {\n box-shadow: 0 0 0 2px var(--fc-combobox-focus-ring-error);\n }\n\n .fc-input::placeholder {\n color: var(--fc-combobox-placeholder);\n }\n\n .fc-input:hover {\n border-color: var(--fc-combobox-border-hover);\n }\n\n .fc-input:focus {\n border-color: var(--fc-combobox-border-focus);\n outline: none;\n box-shadow: var(--fc-combobox-focus-ring);\n }\n\n \n .fc-chevron {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: var(--fc-select-dropdown-icon-width);\n height: var(--fc-select-dropdown-icon-height);\n pointer-events: none;\n color: var(--fc-combobox-fg);\n transition: transform 0.2s ease;\n }\n\n \n :host([open]) .fc-chevron {\n transform: translateY(-50%) rotate(180deg);\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n .fc-input:disabled {\n background: var(--fc-combobox-bg-disabled);\n cursor: not-allowed;\n box-shadow: none;\n color: var(--fc-combobox-placeholder-disabled);\n }\n\n :host([disabled]) .fc-chevron {\n color: var(--fc-combobox-placeholder-disabled);\n }\n\n .fc-options {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n right: 0;\n z-index: 1000;\n background: var(--fc-combobox-dropdown-bg, var(--fc-combobox-bg));\n border: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n border-radius: var(--fc-combobox-dropdown-radius, var(--fc-combobox-radius));\n padding: var(--fc-combobox-dropdown-padding, calc(var(--fc-combobox-padding) - 5px));\n box-shadow: var(--fc-combobox-dropdown-shadow);\n max-height: var(--fc-combobox-dropdown-max-height, 240px);\n overflow-y: auto;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .fc-options.opens-up {\n top: auto;\n bottom: calc(100% + 6px);\n }\n \n .fc-options[hidden] {\n display: none !important;\n }\n`;
|
|
1347
|
+
|
|
1348
|
+
var template6 = document.createElement("template");
|
|
1349
|
+
|
|
1350
|
+
template6.innerHTML = `\n <style>${styles6}</style>\n\n <input \n class="fc-input"\n type="text" \n role="combobox"\n aria-autocomplete="none" \n aria-expanded="false"\n aria-haspopup="listbox"\n aria-controls="fc-options"\n part="input"\n autocomplete="off"\n readonly\n />\n\n <svg class="fc-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <polyline points="6 9 12 15 18 9"></polyline>\n </svg>\n\n <div \n part="options" \n class="fc-options" \n role="listbox"\n hidden\n >\n <slot></slot>\n </div>\n`;
|
|
1351
|
+
|
|
1352
|
+
var FcSelect = class extends HTMLElement {
|
|
1353
|
+
constructor() {
|
|
1354
|
+
super();
|
|
1355
|
+
this._value = "";
|
|
1356
|
+
this.activeIndex = -1;
|
|
1357
|
+
this.searchBuffer = "";
|
|
1358
|
+
this.searchTimeout = null;
|
|
1359
|
+
const shadow = this.attachShadow({
|
|
1360
|
+
mode: "open",
|
|
1361
|
+
delegatesFocus: true
|
|
1362
|
+
});
|
|
1363
|
+
shadow.appendChild(template6.content.cloneNode(true));
|
|
1364
|
+
this.internals = this.attachInternals();
|
|
1365
|
+
this.inputEl = shadow.querySelector(".fc-input");
|
|
1366
|
+
this.dropdownEl = shadow.querySelector(".fc-options");
|
|
1367
|
+
const randomId = Math.random().toString(36).substring(2, 9);
|
|
1368
|
+
const inputId = `fc-input-${randomId}`;
|
|
1369
|
+
const dropdownId = `fc-options-${randomId}`;
|
|
1370
|
+
this.inputEl.id = inputId;
|
|
1371
|
+
this.dropdownEl.id = dropdownId;
|
|
1372
|
+
this.inputEl.setAttribute("aria-controls", dropdownId);
|
|
1373
|
+
this.onChange = this.onChange.bind(this);
|
|
1374
|
+
this.onOptionSelect = this.onOptionSelect.bind(this);
|
|
1375
|
+
this.onOutsideClick = this.onOutsideClick.bind(this);
|
|
1376
|
+
this.onFocusOut = this.onFocusOut.bind(this);
|
|
1377
|
+
this.onSlotChange = this.onSlotChange.bind(this);
|
|
1378
|
+
this.onKeyDown = this.onKeyDown.bind(this);
|
|
1379
|
+
this.onBlur = this.onBlur.bind(this);
|
|
1380
|
+
this.onInvalid = this.onInvalid.bind(this);
|
|
1381
|
+
this.onClick = this.onClick.bind(this);
|
|
1382
|
+
}
|
|
1383
|
+
static get observedAttributes() {
|
|
1384
|
+
return [ "placeholder", "name", "value", "disabled", "required" ];
|
|
1385
|
+
}
|
|
1386
|
+
get validity() {
|
|
1387
|
+
return this.internals.validity;
|
|
1388
|
+
}
|
|
1389
|
+
get validationMessage() {
|
|
1390
|
+
return this.internals.validationMessage;
|
|
1391
|
+
}
|
|
1392
|
+
get willValidate() {
|
|
1393
|
+
return this.internals.willValidate;
|
|
1394
|
+
}
|
|
1395
|
+
checkValidity() {
|
|
1396
|
+
return this.internals.checkValidity();
|
|
1397
|
+
}
|
|
1398
|
+
reportValidity() {
|
|
1399
|
+
return this.internals.reportValidity();
|
|
1400
|
+
}
|
|
1401
|
+
get placeholder() {
|
|
1402
|
+
var _a;
|
|
1403
|
+
return (_a = this.getAttribute("placeholder")) != null ? _a : "";
|
|
1404
|
+
}
|
|
1405
|
+
set placeholder(val) {
|
|
1406
|
+
this.setAttribute("placeholder", val);
|
|
1407
|
+
}
|
|
1408
|
+
get name() {
|
|
1409
|
+
var _a;
|
|
1410
|
+
return (_a = this.getAttribute("name")) != null ? _a : "";
|
|
1411
|
+
}
|
|
1412
|
+
set name(val) {
|
|
1413
|
+
this.setAttribute("name", val);
|
|
1414
|
+
}
|
|
1415
|
+
get disabled() {
|
|
1416
|
+
return this.hasAttribute("disabled");
|
|
1417
|
+
}
|
|
1418
|
+
set disabled(val) {
|
|
1419
|
+
if (val) {
|
|
1420
|
+
this.setAttribute("disabled", "true");
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
this.removeAttribute("disabled");
|
|
1424
|
+
}
|
|
1425
|
+
get value() {
|
|
1426
|
+
return this._value;
|
|
1427
|
+
}
|
|
1428
|
+
set value(newValue) {
|
|
1429
|
+
if (this._value === newValue) return;
|
|
1430
|
+
this._value = newValue;
|
|
1431
|
+
this.internals.setFormValue(newValue);
|
|
1432
|
+
if (!this.inputEl) return;
|
|
1433
|
+
this.syncValidity();
|
|
1434
|
+
}
|
|
1435
|
+
get label() {
|
|
1436
|
+
var _a, _b;
|
|
1437
|
+
return (_b = (_a = this.inputEl) == null ? void 0 : _a.value) != null ? _b : "";
|
|
1438
|
+
}
|
|
1439
|
+
get options() {
|
|
1440
|
+
const slot = this.shadowRoot.querySelector("slot");
|
|
1441
|
+
const optionElements = slot.assignedElements().filter(el => el.tagName === "FC-OPTION");
|
|
1442
|
+
return optionElements.map(opt => ({
|
|
1443
|
+
label: opt.label,
|
|
1444
|
+
value: opt.value
|
|
1445
|
+
}));
|
|
1446
|
+
}
|
|
1447
|
+
set options(data) {
|
|
1448
|
+
const oldOptions = this.querySelectorAll("fc-option");
|
|
1449
|
+
oldOptions.forEach(opt => opt.remove());
|
|
1450
|
+
data.forEach(element => {
|
|
1451
|
+
const optEl = document.createElement("fc-option");
|
|
1452
|
+
optEl.setAttribute("value", element.value);
|
|
1453
|
+
optEl.setAttribute("label", element.label);
|
|
1454
|
+
optEl.textContent = element.label;
|
|
1455
|
+
if (element.disabled) optEl.setAttribute("disabled", "");
|
|
1456
|
+
this.appendChild(optEl);
|
|
1457
|
+
});
|
|
1458
|
+
this.syncValidity();
|
|
1459
|
+
}
|
|
1460
|
+
get required() {
|
|
1461
|
+
return this.hasAttribute("required");
|
|
1462
|
+
}
|
|
1463
|
+
set required(val) {
|
|
1464
|
+
if (val) {
|
|
1465
|
+
this.setAttribute("required", "true");
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
this.removeAttribute("required");
|
|
1469
|
+
}
|
|
1470
|
+
get readonly() {
|
|
1471
|
+
return this.hasAttribute("readonly");
|
|
1472
|
+
}
|
|
1473
|
+
connectedCallback() {
|
|
1474
|
+
this.internals.setFormValue(this.value);
|
|
1475
|
+
if (this.hasAttribute("placeholder")) {
|
|
1476
|
+
this.inputEl.placeholder = this.getAttribute("placeholder");
|
|
1477
|
+
}
|
|
1478
|
+
if (this.hasAttribute("disabled")) {
|
|
1479
|
+
this.inputEl.disabled = true;
|
|
1480
|
+
this.internals.ariaDisabled = "true";
|
|
1481
|
+
}
|
|
1482
|
+
if (this.hasAttribute("required")) {
|
|
1483
|
+
this.internals.ariaRequired = "true";
|
|
1484
|
+
this.inputEl.required = true;
|
|
1485
|
+
}
|
|
1486
|
+
this.inputEl.addEventListener("click", this.onClick);
|
|
1487
|
+
this.inputEl.addEventListener("change", this.onChange);
|
|
1488
|
+
this.addEventListener("fc-option-select", this.onOptionSelect);
|
|
1489
|
+
this.addEventListener("focusout", this.onFocusOut);
|
|
1490
|
+
this.inputEl.addEventListener("blur", this.onBlur);
|
|
1491
|
+
this.addEventListener("invalid", this.onInvalid);
|
|
1492
|
+
const slot = this.shadowRoot.querySelector("slot");
|
|
1493
|
+
slot == null ? void 0 : slot.addEventListener("slotchange", this.onSlotChange);
|
|
1494
|
+
this.inputEl.addEventListener("keydown", this.onKeyDown);
|
|
1495
|
+
this.syncValidity();
|
|
1496
|
+
}
|
|
1497
|
+
attributeChangedCallback(name, _old, newVal) {
|
|
1498
|
+
if (name === "placeholder" && this.inputEl) {
|
|
1499
|
+
this.inputEl.placeholder = newVal;
|
|
1500
|
+
}
|
|
1501
|
+
if (name === "name") {
|
|
1502
|
+
this.internals.setFormValue(this.value);
|
|
1503
|
+
}
|
|
1504
|
+
if (name === "value") {
|
|
1505
|
+
this.value = newVal;
|
|
1506
|
+
}
|
|
1507
|
+
if (name === "disabled" && this.inputEl) {
|
|
1508
|
+
const isDisabled = this.hasAttribute("disabled");
|
|
1509
|
+
this.inputEl.disabled = isDisabled;
|
|
1510
|
+
this.internals.ariaDisabled = isDisabled ? "true" : "false";
|
|
1511
|
+
if (isDisabled) {
|
|
1512
|
+
this.toggleDropdown(false);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
if (name === "required" && this.inputEl) {
|
|
1516
|
+
const isRequired = this.hasAttribute("required");
|
|
1517
|
+
this.internals.ariaRequired = isRequired ? "true" : "false";
|
|
1518
|
+
this.inputEl.required = isRequired;
|
|
1519
|
+
this.syncValidity();
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
disconnectedCallback() {
|
|
1523
|
+
document.removeEventListener("click", this.onOutsideClick);
|
|
1524
|
+
}
|
|
1525
|
+
formResetCallback() {
|
|
1526
|
+
this._value = "";
|
|
1527
|
+
if (this.inputEl) {
|
|
1528
|
+
this.inputEl.value = "";
|
|
1529
|
+
}
|
|
1530
|
+
this.internals.setFormValue("");
|
|
1531
|
+
const options = this.querySelectorAll("fc-option");
|
|
1532
|
+
options.forEach(option => {
|
|
1533
|
+
option.selected = false;
|
|
1534
|
+
});
|
|
1535
|
+
this.toggleDropdown(false);
|
|
1536
|
+
this.removeAttribute("touched");
|
|
1537
|
+
this.syncValidity();
|
|
1538
|
+
this.dispatchEvent(new CustomEvent("fc-reset", {
|
|
1539
|
+
bubbles: true,
|
|
1540
|
+
composed: true
|
|
1541
|
+
}));
|
|
1542
|
+
}
|
|
1543
|
+
formStateRestoreCallback(state, mode) {
|
|
1544
|
+
const restoredValue = state;
|
|
1545
|
+
if (restoredValue) {
|
|
1546
|
+
this._value = restoredValue;
|
|
1547
|
+
this.internals.setFormValue(restoredValue);
|
|
1548
|
+
const options = this.querySelectorAll("fc-option");
|
|
1549
|
+
let foundMatch = false;
|
|
1550
|
+
options.forEach(option => {
|
|
1551
|
+
const selected = option.value === this._value;
|
|
1552
|
+
option.selected = selected;
|
|
1553
|
+
if (selected) {
|
|
1554
|
+
this.inputEl.value = option.label;
|
|
1555
|
+
foundMatch = true;
|
|
1556
|
+
}
|
|
1557
|
+
});
|
|
1558
|
+
if (!foundMatch && this.inputEl.value === "") {
|
|
1559
|
+
this.inputEl.value = this._value;
|
|
1560
|
+
}
|
|
1561
|
+
this.syncValidity();
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
onClick(e) {
|
|
1565
|
+
if (this.disabled) {
|
|
1566
|
+
return;
|
|
1567
|
+
}
|
|
1568
|
+
this.toggleDropdown(this.dropdownEl.hidden);
|
|
1569
|
+
}
|
|
1570
|
+
onChange(e) {
|
|
1571
|
+
e.stopPropagation();
|
|
1572
|
+
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
1573
|
+
detail: {
|
|
1574
|
+
value: this._value,
|
|
1575
|
+
label: this.inputEl.value
|
|
1576
|
+
},
|
|
1577
|
+
bubbles: true,
|
|
1578
|
+
composed: true
|
|
1579
|
+
}));
|
|
1580
|
+
}
|
|
1581
|
+
onOptionSelect(e) {
|
|
1582
|
+
const {value: value, label: label} = e.detail;
|
|
1583
|
+
if (this.disabled) {
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
this.inputEl.value = label;
|
|
1587
|
+
this._value = value;
|
|
1588
|
+
this.internals.setFormValue(value);
|
|
1589
|
+
const options = this.querySelectorAll("fc-option");
|
|
1590
|
+
options.forEach(option => {
|
|
1591
|
+
const selected = option.value === value;
|
|
1592
|
+
option.selected = selected;
|
|
1593
|
+
option.active = false;
|
|
1594
|
+
});
|
|
1595
|
+
this.toggleDropdown(false);
|
|
1596
|
+
this.syncValidity();
|
|
1597
|
+
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
1598
|
+
detail: {
|
|
1599
|
+
value: value,
|
|
1600
|
+
label: label
|
|
1601
|
+
},
|
|
1602
|
+
bubbles: true,
|
|
1603
|
+
composed: true
|
|
1604
|
+
}));
|
|
1605
|
+
}
|
|
1606
|
+
onOutsideClick(e) {
|
|
1607
|
+
if (!this.contains(e.target)) {
|
|
1608
|
+
this.toggleDropdown(false);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
onFocusOut(e) {
|
|
1612
|
+
const target = e.relatedTarget;
|
|
1613
|
+
if (!target || !this.contains(target)) {
|
|
1614
|
+
this.toggleDropdown(false);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
onSlotChange() {
|
|
1618
|
+
if (!this._value) return;
|
|
1619
|
+
const options = this.querySelectorAll("fc-option");
|
|
1620
|
+
let foundMatch = false;
|
|
1621
|
+
options.forEach(option => {
|
|
1622
|
+
const selected = option.value === this._value;
|
|
1623
|
+
option.selected = selected;
|
|
1624
|
+
if (selected) {
|
|
1625
|
+
this.inputEl.value = option.label;
|
|
1626
|
+
foundMatch = true;
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
if (!foundMatch && this.inputEl.value === "") {
|
|
1630
|
+
this.inputEl.value = this._value;
|
|
1631
|
+
}
|
|
1632
|
+
this.syncValidity();
|
|
1633
|
+
}
|
|
1634
|
+
onKeyDown(e) {
|
|
1635
|
+
if (this.disabled) {
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
const options = this.getVisibleOptions();
|
|
1639
|
+
if (options.length === 0) return;
|
|
1640
|
+
if (e.key === "ArrowDown") {
|
|
1641
|
+
e.preventDefault();
|
|
1642
|
+
if (this.dropdownEl.hidden) {
|
|
1643
|
+
this.toggleDropdown(true);
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
const nextIndex = this.activeIndex >= options.length - 1 ? 0 : this.activeIndex + 1;
|
|
1647
|
+
this.setActiveOption(nextIndex, options);
|
|
1648
|
+
} else if (e.key === "ArrowUp") {
|
|
1649
|
+
e.preventDefault();
|
|
1650
|
+
if (this.dropdownEl.hidden) {
|
|
1651
|
+
this.toggleDropdown(true);
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
const prevIndex = this.activeIndex <= 0 ? options.length - 1 : this.activeIndex - 1;
|
|
1655
|
+
this.setActiveOption(prevIndex, options);
|
|
1656
|
+
} else if (e.key === "Enter" || e.key === " ") {
|
|
1657
|
+
e.preventDefault();
|
|
1658
|
+
if (this.dropdownEl.hidden) {
|
|
1659
|
+
this.toggleDropdown(true);
|
|
1660
|
+
} else {
|
|
1661
|
+
if (this.activeIndex > -1 && options[this.activeIndex]) {
|
|
1662
|
+
const target = options[this.activeIndex];
|
|
1663
|
+
this.selectOption(target);
|
|
1664
|
+
} else {
|
|
1665
|
+
this.toggleDropdown(false);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
} else if (e.key === "Escape") {
|
|
1669
|
+
e.preventDefault();
|
|
1670
|
+
this.toggleDropdown(false);
|
|
1671
|
+
} else if (e.key === "Tab") {
|
|
1672
|
+
this.toggleDropdown(false);
|
|
1673
|
+
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
1674
|
+
e.preventDefault();
|
|
1675
|
+
this.handleTypeAhead(e.key);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
handleTypeAhead(char) {
|
|
1679
|
+
if (this.searchTimeout) clearTimeout(this.searchTimeout);
|
|
1680
|
+
this.searchBuffer += char.toLowerCase();
|
|
1681
|
+
this.searchTimeout = setTimeout(() => {
|
|
1682
|
+
this.searchBuffer = "";
|
|
1683
|
+
}, 500);
|
|
1684
|
+
const options = this.getVisibleOptions();
|
|
1685
|
+
const matchIndex = options.findIndex(opt => {
|
|
1686
|
+
const label = (opt.getAttribute("label") || opt.textContent || "").toLowerCase();
|
|
1687
|
+
return label.startsWith(this.searchBuffer);
|
|
1688
|
+
});
|
|
1689
|
+
if (matchIndex !== -1) {
|
|
1690
|
+
const match = options[matchIndex];
|
|
1691
|
+
if (!this.dropdownEl.hidden) {
|
|
1692
|
+
this.setActiveOption(matchIndex, options);
|
|
1693
|
+
} else {
|
|
1694
|
+
this.selectOption(match);
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
onBlur() {
|
|
1699
|
+
this.setAttribute("touched", "");
|
|
1700
|
+
}
|
|
1701
|
+
onInvalid(e) {
|
|
1702
|
+
this.setAttribute("touched", "");
|
|
1703
|
+
this.dispatchEvent(new CustomEvent("fc-invalid", {
|
|
1704
|
+
bubbles: true,
|
|
1705
|
+
composed: true,
|
|
1706
|
+
detail: {
|
|
1707
|
+
originalEvent: e
|
|
1708
|
+
}
|
|
1709
|
+
}));
|
|
1710
|
+
}
|
|
1711
|
+
setActiveOption(index, visibleOptions) {
|
|
1712
|
+
this.querySelectorAll("fc-option").forEach(opt => opt.active = false);
|
|
1713
|
+
this.activeIndex = index;
|
|
1714
|
+
const target = visibleOptions[index];
|
|
1715
|
+
if (target) {
|
|
1716
|
+
target.active = true;
|
|
1717
|
+
this.inputEl.setAttribute("aria-activedescendant", target.id);
|
|
1718
|
+
target.scrollIntoView({
|
|
1719
|
+
block: "nearest",
|
|
1720
|
+
behavior: "smooth"
|
|
1721
|
+
});
|
|
1722
|
+
return;
|
|
1723
|
+
}
|
|
1724
|
+
this.inputEl.removeAttribute("aria-activedescendant");
|
|
1725
|
+
}
|
|
1726
|
+
getVisibleOptions() {
|
|
1727
|
+
return Array.from(this.querySelectorAll("fc-option")).filter(opt => !opt.disabled);
|
|
1728
|
+
}
|
|
1729
|
+
selectOption(option) {
|
|
1730
|
+
const value = option.value;
|
|
1731
|
+
const label = option.label;
|
|
1732
|
+
this.inputEl.value = label;
|
|
1733
|
+
this._value = value;
|
|
1734
|
+
this.internals.setFormValue(value);
|
|
1735
|
+
const allOptions = this.querySelectorAll("fc-option");
|
|
1736
|
+
allOptions.forEach(opt => {
|
|
1737
|
+
const selected = opt.value === value;
|
|
1738
|
+
opt.selected = selected;
|
|
1739
|
+
opt.active = false;
|
|
1740
|
+
});
|
|
1741
|
+
this.toggleDropdown(false);
|
|
1742
|
+
this.syncValidity();
|
|
1743
|
+
this.dispatchEvent(new CustomEvent("fc-change", {
|
|
1744
|
+
detail: {
|
|
1745
|
+
value: value,
|
|
1746
|
+
label: label
|
|
1747
|
+
},
|
|
1748
|
+
bubbles: true,
|
|
1749
|
+
composed: true
|
|
1750
|
+
}));
|
|
1751
|
+
}
|
|
1752
|
+
toggleDropdown(show) {
|
|
1753
|
+
if (!this.dropdownEl) {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
if (this.disabled && show) {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
const dropdown = this.dropdownEl;
|
|
1760
|
+
if (show) {
|
|
1761
|
+
const showEvent = new CustomEvent("fc-show", {
|
|
1762
|
+
bubbles: true,
|
|
1763
|
+
composed: true,
|
|
1764
|
+
cancelable: true
|
|
1765
|
+
});
|
|
1766
|
+
this.dispatchEvent(showEvent);
|
|
1767
|
+
if (showEvent.defaultPrevented) {
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
const spaceBelow = calculateBottomAvaliableSpace(this.inputEl);
|
|
1771
|
+
const spaceAbove = calculateTopAvaliableSpace(this.inputEl);
|
|
1772
|
+
dropdown.hidden = false;
|
|
1773
|
+
this.setAttribute("open", "true");
|
|
1774
|
+
this.inputEl.setAttribute("aria-expanded", "true");
|
|
1775
|
+
const shouldOpenUp = spaceBelow < dropdown.clientHeight && spaceAbove > spaceBelow;
|
|
1776
|
+
dropdown.classList.toggle("opens-up", shouldOpenUp);
|
|
1777
|
+
const options = this.getVisibleOptions();
|
|
1778
|
+
const selectedIndex = options.findIndex(opt => opt.value === this._value);
|
|
1779
|
+
if (selectedIndex >= 0) {
|
|
1780
|
+
this.setActiveOption(selectedIndex, options);
|
|
1781
|
+
} else {
|
|
1782
|
+
this.activeIndex = -1;
|
|
1783
|
+
}
|
|
1784
|
+
setTimeout(() => {
|
|
1785
|
+
document.addEventListener("click", this.onOutsideClick);
|
|
1786
|
+
}, 0);
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
if (!this.dropdownEl.hidden) {
|
|
1790
|
+
this.dispatchEvent(new CustomEvent("fc-hide", {
|
|
1791
|
+
bubbles: true,
|
|
1792
|
+
composed: true
|
|
1793
|
+
}));
|
|
1794
|
+
}
|
|
1795
|
+
document.removeEventListener("click", this.onOutsideClick);
|
|
1796
|
+
this.dropdownEl.hidden = true;
|
|
1797
|
+
this.removeAttribute("open");
|
|
1798
|
+
this.inputEl.setAttribute("aria-expanded", "false");
|
|
1799
|
+
this.activeIndex = -1;
|
|
1800
|
+
this.querySelectorAll("fc-option").forEach(opt => opt.active = false);
|
|
1801
|
+
this.inputEl.removeAttribute("aria-activedescendant");
|
|
1802
|
+
}
|
|
1803
|
+
syncValidity() {
|
|
1804
|
+
if (!this.inputEl) {
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
if (!this.inputEl.validity.valid) {
|
|
1808
|
+
this.internals.setValidity(this.inputEl.validity, this.inputEl.validationMessage, this.inputEl);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
const options = this.querySelectorAll("fc-option");
|
|
1812
|
+
let match = false;
|
|
1813
|
+
options.forEach(option => {
|
|
1814
|
+
if (option.value === this._value) {
|
|
1815
|
+
match = true;
|
|
1816
|
+
}
|
|
1817
|
+
});
|
|
1818
|
+
if (!match) {
|
|
1819
|
+
this.internals.setValidity({
|
|
1820
|
+
customError: true
|
|
1821
|
+
}, "Please select a valid option from the list.", this.inputEl);
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
this.internals.setValidity({});
|
|
1825
|
+
}
|
|
1826
|
+
setProps(props) {
|
|
1827
|
+
for (const property in props) {
|
|
1828
|
+
const value = props[property];
|
|
1829
|
+
if (property in this) {
|
|
1830
|
+
this[property] = value;
|
|
1831
|
+
continue;
|
|
1832
|
+
}
|
|
1833
|
+
if ([ "string", "number", "boolean" ].includes(typeof value)) {
|
|
1834
|
+
this.setAttribute(property, String(value));
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
|
|
1840
|
+
FcSelect.formAssociated = true;
|
|
1841
|
+
|
|
1842
|
+
var defineSelect = () => {
|
|
1843
|
+
if (!customElements.get("fc-select")) {
|
|
1844
|
+
customElements.define("fc-select", FcSelect);
|
|
1845
|
+
}
|
|
1846
|
+
return FcSelect;
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1255
1849
|
var defineAll = () => {
|
|
1256
1850
|
defineCombobox();
|
|
1257
1851
|
defineOption();
|
|
1258
1852
|
defineInput();
|
|
1259
1853
|
defineError();
|
|
1854
|
+
defineLabel();
|
|
1855
|
+
defineSelect();
|
|
1260
1856
|
};
|
|
1261
1857
|
|
|
1262
|
-
export { FcCombobox, FcError, FcInput, FcOption, defineAll, defineCombobox, defineError, defineInput, defineOption };
|
|
1858
|
+
export { FcCombobox, FcError, FcInput, FcLabel, FcOption, FcSelect, defineAll, defineCombobox, defineError, defineInput, defineLabel, defineOption, defineSelect };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fancy-ui-ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A library to easily create cool and customizable webcomponents.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,6 +26,20 @@
|
|
|
26
26
|
"build": "tsup",
|
|
27
27
|
"build:watch": "tsup --watch"
|
|
28
28
|
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"web-components",
|
|
31
|
+
"components",
|
|
32
|
+
"custom-elements",
|
|
33
|
+
"typescript",
|
|
34
|
+
"ui-library",
|
|
35
|
+
"design-system",
|
|
36
|
+
"combobox",
|
|
37
|
+
"input",
|
|
38
|
+
"label",
|
|
39
|
+
"html",
|
|
40
|
+
"react",
|
|
41
|
+
"vue"
|
|
42
|
+
],
|
|
29
43
|
"author": "Luan Peixoto",
|
|
30
44
|
"license": "MIT",
|
|
31
45
|
"devDependencies": {
|