@ship-ui/core 0.13.16 → 0.13.18
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/fesm2022/ship-ui-core.mjs +94 -5
- package/fesm2022/ship-ui-core.mjs.map +1 -1
- package/index.d.ts +7 -1
- package/package.json +1 -1
|
@@ -3015,6 +3015,7 @@ class ShipSelectComponent {
|
|
|
3015
3015
|
this.value = input();
|
|
3016
3016
|
this.label = input();
|
|
3017
3017
|
this.asFreeText = input(false);
|
|
3018
|
+
this.validateFreeText = input();
|
|
3018
3019
|
this.placeholder = input();
|
|
3019
3020
|
this.readonly = model(false);
|
|
3020
3021
|
this.disabled = model(false);
|
|
@@ -3026,11 +3027,22 @@ class ShipSelectComponent {
|
|
|
3026
3027
|
this.optionTemplate = input(null);
|
|
3027
3028
|
this.selectedOptionTemplate = input(null);
|
|
3028
3029
|
this.placeholderTemplate = input(null);
|
|
3030
|
+
this.freeTextOptionTemplate = input(null);
|
|
3029
3031
|
this.isOpen = model(false);
|
|
3030
3032
|
this.isLoading = model(false);
|
|
3031
3033
|
this.options = model([]);
|
|
3032
3034
|
this.selectedOptions = model([]);
|
|
3033
3035
|
this.cleared = output();
|
|
3036
|
+
this.onAddNewFreeTextOption = output();
|
|
3037
|
+
this.computedFreeTextOption = computed(() => {
|
|
3038
|
+
const inputValue = this.inputValue();
|
|
3039
|
+
const valueKey = this.value();
|
|
3040
|
+
const newOption = valueKey ? {} : inputValue;
|
|
3041
|
+
if (valueKey && typeof newOption === 'object') {
|
|
3042
|
+
newOption[valueKey] = inputValue;
|
|
3043
|
+
}
|
|
3044
|
+
return newOption;
|
|
3045
|
+
});
|
|
3034
3046
|
this.#previousSelectedOptions = signal(null);
|
|
3035
3047
|
this.inlineTemplate = contentChild(TemplateRef);
|
|
3036
3048
|
this.optionsWrapRef = viewChild.required('optionsWrap');
|
|
@@ -3166,6 +3178,8 @@ class ShipSelectComponent {
|
|
|
3166
3178
|
this.openAbortController = new AbortController();
|
|
3167
3179
|
}
|
|
3168
3180
|
const input = this.inputRefEl();
|
|
3181
|
+
const asFreeText = this.asFreeText();
|
|
3182
|
+
const baseIndex = asFreeText ? -1 : 0;
|
|
3169
3183
|
if (!input)
|
|
3170
3184
|
return;
|
|
3171
3185
|
input.setAttribute('aria-expanded', this.isOpen().toString());
|
|
@@ -3181,12 +3195,12 @@ class ShipSelectComponent {
|
|
|
3181
3195
|
if (e.key === 'ArrowDown') {
|
|
3182
3196
|
e.preventDefault();
|
|
3183
3197
|
const newIndex = this.focusedOptionIndex() + 1;
|
|
3184
|
-
this.focusedOptionIndex.set(newIndex > this.filteredOptions().length - 1 ?
|
|
3198
|
+
this.focusedOptionIndex.set(newIndex > this.filteredOptions().length - 1 ? baseIndex : newIndex);
|
|
3185
3199
|
}
|
|
3186
3200
|
if (e.key === 'ArrowUp') {
|
|
3187
3201
|
e.preventDefault();
|
|
3188
3202
|
const newIndex = this.focusedOptionIndex() - 1;
|
|
3189
|
-
this.focusedOptionIndex.set(newIndex <
|
|
3203
|
+
this.focusedOptionIndex.set(newIndex < baseIndex ? this.filteredOptions().length - 1 : newIndex);
|
|
3190
3204
|
}
|
|
3191
3205
|
}, {
|
|
3192
3206
|
signal: this.openAbortController?.signal,
|
|
@@ -3355,6 +3369,12 @@ class ShipSelectComponent {
|
|
|
3355
3369
|
this.inputValue.set(newInputValue);
|
|
3356
3370
|
this.updateInputElValue();
|
|
3357
3371
|
}
|
|
3372
|
+
getValue(option) {
|
|
3373
|
+
const valueKey = this.value();
|
|
3374
|
+
if (!valueKey)
|
|
3375
|
+
return option;
|
|
3376
|
+
return this.#getProperty(option, valueKey);
|
|
3377
|
+
}
|
|
3358
3378
|
getLabel(option) {
|
|
3359
3379
|
const label = this.label();
|
|
3360
3380
|
if (!label)
|
|
@@ -3368,8 +3388,25 @@ class ShipSelectComponent {
|
|
|
3368
3388
|
return label.replaceAll(' ', '-');
|
|
3369
3389
|
}
|
|
3370
3390
|
toggleOptionByIndex(optionIndex, event) {
|
|
3371
|
-
|
|
3372
|
-
if (
|
|
3391
|
+
let option = this.filteredOptions()[optionIndex];
|
|
3392
|
+
if (this.asFreeText() && optionIndex === -1) {
|
|
3393
|
+
const newOption = this.computedFreeTextOption();
|
|
3394
|
+
const newOptionValue = this.getValue(newOption);
|
|
3395
|
+
const validateFreeTextFunc = this.validateFreeText() ?? ((val) => true);
|
|
3396
|
+
const isValid = validateFreeTextFunc(newOptionValue);
|
|
3397
|
+
if (!isValid)
|
|
3398
|
+
return;
|
|
3399
|
+
this.options.update((options) => {
|
|
3400
|
+
const index = options.findIndex((option) => this.getValue(option) === newOptionValue);
|
|
3401
|
+
if (index > -1)
|
|
3402
|
+
return options;
|
|
3403
|
+
this.onAddNewFreeTextOption.emit(newOptionValue);
|
|
3404
|
+
return [newOption, ...options];
|
|
3405
|
+
});
|
|
3406
|
+
optionIndex = 0;
|
|
3407
|
+
option = newOption;
|
|
3408
|
+
}
|
|
3409
|
+
else if (!option) {
|
|
3373
3410
|
this.close();
|
|
3374
3411
|
return;
|
|
3375
3412
|
}
|
|
@@ -3535,9 +3572,10 @@ class ShipSelectComponent {
|
|
|
3535
3572
|
}
|
|
3536
3573
|
}
|
|
3537
3574
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: ShipSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3538
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: ShipSelectComponent, isStandalone: true, selector: "sh-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, asFreeText: { classPropertyName: "asFreeText", publicName: "asFreeText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, lazySearch: { classPropertyName: "lazySearch", publicName: "lazySearch", isSignal: true, isRequired: false, transformFunction: null }, inlineSearch: { classPropertyName: "inlineSearch", publicName: "inlineSearch", isSignal: true, isRequired: false, transformFunction: null }, asText: { classPropertyName: "asText", publicName: "asText", isSignal: true, isRequired: false, transformFunction: null }, isClearable: { classPropertyName: "isClearable", publicName: "isClearable", isSignal: true, isRequired: false, transformFunction: null }, selectMultiple: { classPropertyName: "selectMultiple", publicName: "selectMultiple", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, selectedOptionTemplate: { classPropertyName: "selectedOptionTemplate", publicName: "selectedOptionTemplate", isSignal: true, isRequired: false, transformFunction: null }, placeholderTemplate: { classPropertyName: "placeholderTemplate", publicName: "placeholderTemplate", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, selectedOptions: { classPropertyName: "selectedOptions", publicName: "selectedOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { readonly: "readonlyChange", disabled: "disabledChange", isOpen: "isOpenChange", isLoading: "isLoadingChange", options: "optionsChange", selectedOptions: "selectedOptionsChange", cleared: "cleared" }, host: { properties: { "class.multiple": "selectMultiple()" } }, queries: [{ propertyName: "inlineTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "optionsWrapRef", first: true, predicate: ["optionsWrap"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3575
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: ShipSelectComponent, isStandalone: true, selector: "sh-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, asFreeText: { classPropertyName: "asFreeText", publicName: "asFreeText", isSignal: true, isRequired: false, transformFunction: null }, validateFreeText: { classPropertyName: "validateFreeText", publicName: "validateFreeText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, lazySearch: { classPropertyName: "lazySearch", publicName: "lazySearch", isSignal: true, isRequired: false, transformFunction: null }, inlineSearch: { classPropertyName: "inlineSearch", publicName: "inlineSearch", isSignal: true, isRequired: false, transformFunction: null }, asText: { classPropertyName: "asText", publicName: "asText", isSignal: true, isRequired: false, transformFunction: null }, isClearable: { classPropertyName: "isClearable", publicName: "isClearable", isSignal: true, isRequired: false, transformFunction: null }, selectMultiple: { classPropertyName: "selectMultiple", publicName: "selectMultiple", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, selectedOptionTemplate: { classPropertyName: "selectedOptionTemplate", publicName: "selectedOptionTemplate", isSignal: true, isRequired: false, transformFunction: null }, placeholderTemplate: { classPropertyName: "placeholderTemplate", publicName: "placeholderTemplate", isSignal: true, isRequired: false, transformFunction: null }, freeTextOptionTemplate: { classPropertyName: "freeTextOptionTemplate", publicName: "freeTextOptionTemplate", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, selectedOptions: { classPropertyName: "selectedOptions", publicName: "selectedOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { readonly: "readonlyChange", disabled: "disabledChange", isOpen: "isOpenChange", isLoading: "isLoadingChange", options: "optionsChange", selectedOptions: "selectedOptionsChange", cleared: "cleared", onAddNewFreeTextOption: "onAddNewFreeTextOption" }, host: { properties: { "class.multiple": "selectMultiple()" } }, queries: [{ propertyName: "inlineTemplate", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "optionsWrapRef", first: true, predicate: ["optionsWrap"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3539
3576
|
@let _placeholderTemplate = placeholderTemplate();
|
|
3540
3577
|
@let _optionTemplate = optionTemplate();
|
|
3578
|
+
@let _freeTextOptionTemplate = freeTextOptionTemplate();
|
|
3541
3579
|
@let _selectedOptionTemplate = selectedOptionTemplate();
|
|
3542
3580
|
@let _inlineTemplate = inlineTemplate();
|
|
3543
3581
|
@let _selectedOptions = selectedOptions();
|
|
@@ -3629,6 +3667,31 @@ class ShipSelectComponent {
|
|
|
3629
3667
|
</sh-form-field>
|
|
3630
3668
|
|
|
3631
3669
|
<div class="ship-options" #optionsWrap id="optionsWrapId" role="listbox">
|
|
3670
|
+
@if (asFreeText()) {
|
|
3671
|
+
@let freeTextOption = computedFreeTextOption();
|
|
3672
|
+
@let freeTextOptionValue = getValue(freeTextOption);
|
|
3673
|
+
|
|
3674
|
+
@if ($any(freeTextOptionValue).length > 0) {
|
|
3675
|
+
<li
|
|
3676
|
+
(click)="toggleOptionByIndex(-1)"
|
|
3677
|
+
class="option"
|
|
3678
|
+
[id]="this.getLabelAsSlug(freeTextOption)"
|
|
3679
|
+
[attr.aria-selected]="isSelected(-1)"
|
|
3680
|
+
[class.selected]="isSelected(-1)"
|
|
3681
|
+
[class.focused]="-1 === focusedOptionIndex()">
|
|
3682
|
+
@if (_freeTextOptionTemplate) {
|
|
3683
|
+
<ng-container
|
|
3684
|
+
*ngTemplateOutlet="_freeTextOptionTemplate; context: { $implicit: { option: freeTextOption } }" />
|
|
3685
|
+
} @else if (_listOptionTemplate) {
|
|
3686
|
+
<ng-container
|
|
3687
|
+
*ngTemplateOutlet="_listOptionTemplate; context: { $implicit: { option: freeTextOption } }" />
|
|
3688
|
+
} @else {
|
|
3689
|
+
{{ freeTextOptionValue }}
|
|
3690
|
+
}
|
|
3691
|
+
</li>
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3632
3695
|
@for (option of filteredOptions(); track $index) {
|
|
3633
3696
|
<li
|
|
3634
3697
|
(click)="toggleOptionByIndex($index)"
|
|
@@ -3668,6 +3731,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
|
|
|
3668
3731
|
template: `
|
|
3669
3732
|
@let _placeholderTemplate = placeholderTemplate();
|
|
3670
3733
|
@let _optionTemplate = optionTemplate();
|
|
3734
|
+
@let _freeTextOptionTemplate = freeTextOptionTemplate();
|
|
3671
3735
|
@let _selectedOptionTemplate = selectedOptionTemplate();
|
|
3672
3736
|
@let _inlineTemplate = inlineTemplate();
|
|
3673
3737
|
@let _selectedOptions = selectedOptions();
|
|
@@ -3759,6 +3823,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
|
|
|
3759
3823
|
</sh-form-field>
|
|
3760
3824
|
|
|
3761
3825
|
<div class="ship-options" #optionsWrap id="optionsWrapId" role="listbox">
|
|
3826
|
+
@if (asFreeText()) {
|
|
3827
|
+
@let freeTextOption = computedFreeTextOption();
|
|
3828
|
+
@let freeTextOptionValue = getValue(freeTextOption);
|
|
3829
|
+
|
|
3830
|
+
@if ($any(freeTextOptionValue).length > 0) {
|
|
3831
|
+
<li
|
|
3832
|
+
(click)="toggleOptionByIndex(-1)"
|
|
3833
|
+
class="option"
|
|
3834
|
+
[id]="this.getLabelAsSlug(freeTextOption)"
|
|
3835
|
+
[attr.aria-selected]="isSelected(-1)"
|
|
3836
|
+
[class.selected]="isSelected(-1)"
|
|
3837
|
+
[class.focused]="-1 === focusedOptionIndex()">
|
|
3838
|
+
@if (_freeTextOptionTemplate) {
|
|
3839
|
+
<ng-container
|
|
3840
|
+
*ngTemplateOutlet="_freeTextOptionTemplate; context: { $implicit: { option: freeTextOption } }" />
|
|
3841
|
+
} @else if (_listOptionTemplate) {
|
|
3842
|
+
<ng-container
|
|
3843
|
+
*ngTemplateOutlet="_listOptionTemplate; context: { $implicit: { option: freeTextOption } }" />
|
|
3844
|
+
} @else {
|
|
3845
|
+
{{ freeTextOptionValue }}
|
|
3846
|
+
}
|
|
3847
|
+
</li>
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3762
3851
|
@for (option of filteredOptions(); track $index) {
|
|
3763
3852
|
<li
|
|
3764
3853
|
(click)="toggleOptionByIndex($index)"
|