@haloduck/ui 2.0.10 → 2.0.12
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/haloduck-ui.mjs +165 -1
- package/fesm2022/haloduck-ui.mjs.map +1 -1
- package/index.d.ts +30 -1
- package/package.json +1 -1
- package/src/tailwind.css +130 -43
package/fesm2022/haloduck-ui.mjs
CHANGED
|
@@ -2851,6 +2851,170 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
2851
2851
|
args: ['label']
|
|
2852
2852
|
}] } });
|
|
2853
2853
|
|
|
2854
|
+
class TagInputComponent {
|
|
2855
|
+
label;
|
|
2856
|
+
inputEl;
|
|
2857
|
+
placeholder = '';
|
|
2858
|
+
disabled = false;
|
|
2859
|
+
allowDuplicates = false;
|
|
2860
|
+
// Two-way binding support independent of CVA
|
|
2861
|
+
set value(tags) {
|
|
2862
|
+
if (Array.isArray(tags)) {
|
|
2863
|
+
this.tags = tags
|
|
2864
|
+
.map((t) => (t ?? '').trim())
|
|
2865
|
+
.filter((t) => t.length > 0);
|
|
2866
|
+
}
|
|
2867
|
+
else {
|
|
2868
|
+
this.tags = [];
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
valueChange = new EventEmitter();
|
|
2872
|
+
tags = [];
|
|
2873
|
+
inputValue = '';
|
|
2874
|
+
onChange = () => { };
|
|
2875
|
+
onTouched = () => { };
|
|
2876
|
+
writeValue(value) {
|
|
2877
|
+
if (Array.isArray(value)) {
|
|
2878
|
+
this.tags = value
|
|
2879
|
+
.map((t) => (t ?? '').trim())
|
|
2880
|
+
.filter((t) => t.length > 0);
|
|
2881
|
+
}
|
|
2882
|
+
else {
|
|
2883
|
+
this.tags = [];
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
registerOnChange(fn) {
|
|
2887
|
+
this.onChange = fn;
|
|
2888
|
+
}
|
|
2889
|
+
registerOnTouched(fn) {
|
|
2890
|
+
this.onTouched = fn;
|
|
2891
|
+
}
|
|
2892
|
+
setDisabledState(isDisabled) {
|
|
2893
|
+
this.disabled = isDisabled;
|
|
2894
|
+
}
|
|
2895
|
+
ngAfterViewInit() {
|
|
2896
|
+
// hide label if no projected content
|
|
2897
|
+
if (this.label && this.label.nativeElement) {
|
|
2898
|
+
const hasContent = this.label.nativeElement.textContent?.trim();
|
|
2899
|
+
if (!hasContent) {
|
|
2900
|
+
this.label.nativeElement.style.display = 'none';
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
focus() {
|
|
2905
|
+
this.inputEl?.nativeElement?.focus();
|
|
2906
|
+
}
|
|
2907
|
+
onInput(event) {
|
|
2908
|
+
const input = event.target;
|
|
2909
|
+
this.inputValue = input.value;
|
|
2910
|
+
this.onTouched();
|
|
2911
|
+
}
|
|
2912
|
+
onBlur() {
|
|
2913
|
+
if (this.disabled)
|
|
2914
|
+
return;
|
|
2915
|
+
this.inputValue = '';
|
|
2916
|
+
this.onTouched();
|
|
2917
|
+
}
|
|
2918
|
+
onKeydown(event) {
|
|
2919
|
+
if (this.disabled)
|
|
2920
|
+
return;
|
|
2921
|
+
// Commit on comma or Enter
|
|
2922
|
+
if (event.key === ',' || event.key === 'Enter') {
|
|
2923
|
+
event.preventDefault();
|
|
2924
|
+
this.commitCurrentInput();
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2927
|
+
// Backspace behavior
|
|
2928
|
+
if (event.key === 'Backspace') {
|
|
2929
|
+
if (this.inputValue.length > 0) {
|
|
2930
|
+
return; // default backspace in input
|
|
2931
|
+
}
|
|
2932
|
+
if (this.tags.length > 0) {
|
|
2933
|
+
event.preventDefault();
|
|
2934
|
+
this.removeTag(this.tags.length - 1);
|
|
2935
|
+
return;
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
removeTag(index) {
|
|
2940
|
+
if (this.disabled)
|
|
2941
|
+
return;
|
|
2942
|
+
if (index < 0 || index >= this.tags.length)
|
|
2943
|
+
return;
|
|
2944
|
+
this.tags = this.tags.filter((_, i) => i !== index);
|
|
2945
|
+
this.emitChanges();
|
|
2946
|
+
}
|
|
2947
|
+
commitCurrentInput() {
|
|
2948
|
+
const raw = this.inputValue.trim();
|
|
2949
|
+
if (!raw) {
|
|
2950
|
+
this.inputValue = '';
|
|
2951
|
+
return;
|
|
2952
|
+
}
|
|
2953
|
+
// If user pasted multiple comma-separated values, split and add all
|
|
2954
|
+
const parts = raw.split(',').map((p) => p.trim()).filter((p) => p.length > 0);
|
|
2955
|
+
for (const part of parts) {
|
|
2956
|
+
this.addTag(part);
|
|
2957
|
+
}
|
|
2958
|
+
this.inputValue = '';
|
|
2959
|
+
}
|
|
2960
|
+
addTag(tag) {
|
|
2961
|
+
if (!this.allowDuplicates) {
|
|
2962
|
+
const exists = this.tags.some((t) => t.toLowerCase() === tag.toLowerCase());
|
|
2963
|
+
if (exists) {
|
|
2964
|
+
return;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
this.tags = [...this.tags, tag];
|
|
2968
|
+
this.emitChanges();
|
|
2969
|
+
}
|
|
2970
|
+
emitChanges() {
|
|
2971
|
+
const cleaned = this.tags
|
|
2972
|
+
.map((t) => (t ?? '').trim())
|
|
2973
|
+
.filter((t) => t.length > 0);
|
|
2974
|
+
if (cleaned.length !== this.tags.length || cleaned.some((t, i) => t !== this.tags[i])) {
|
|
2975
|
+
this.tags = cleaned;
|
|
2976
|
+
}
|
|
2977
|
+
this.onChange(this.tags);
|
|
2978
|
+
this.valueChange.emit(this.tags);
|
|
2979
|
+
}
|
|
2980
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TagInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2981
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TagInputComponent, isStandalone: true, selector: "haloduck-tag-input", inputs: { placeholder: "placeholder", disabled: "disabled", allowDuplicates: "allowDuplicates", value: "value" }, outputs: { valueChange: "valueChange" }, providers: [
|
|
2982
|
+
{
|
|
2983
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2984
|
+
useExisting: forwardRef(() => TagInputComponent),
|
|
2985
|
+
multi: true,
|
|
2986
|
+
},
|
|
2987
|
+
provideTranslocoScope('haloduck'),
|
|
2988
|
+
], viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <label #label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n\n <div class=\"tag-input-wrapper block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive sm:text-sm/6\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <ng-container *ngFor=\"let tag of tags; let i = index\">\n <span class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\">\n {{ tag }}\n @if (!disabled) {\n <button type=\"button\" (click)=\"removeTag(i)\" class=\"text-light-on-secondary/80 hover:text-light-on-secondary dark:text-dark-on-secondary/80 dark:hover:text-dark-on-secondary hover:cursor-pointer\">\n \u00D7\n </button>\n }\n </span>\n </ng-container>\n\n <input #inputEl\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n class=\"flex-1 min-w-[8rem] bg-transparent outline-none placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [value]=\"inputValue\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.tag-input-wrapper:focus-within{outline-width:2px;outline-offset:2px;outline-color:var(--color-light-primary)!important}@media (prefers-color-scheme: dark){.tag-input-wrapper:focus-within{outline-color:var(--color-dark-primary)!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
2989
|
+
}
|
|
2990
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TagInputComponent, decorators: [{
|
|
2991
|
+
type: Component,
|
|
2992
|
+
args: [{ selector: 'haloduck-tag-input', imports: [CommonModule], providers: [
|
|
2993
|
+
{
|
|
2994
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2995
|
+
useExisting: forwardRef(() => TagInputComponent),
|
|
2996
|
+
multi: true,
|
|
2997
|
+
},
|
|
2998
|
+
provideTranslocoScope('haloduck'),
|
|
2999
|
+
], template: "<div class=\"flex flex-col gap-2\">\n <label #label class=\"block text-sm/6 font-medium text-light-on-control dark:text-dark-on-control text-left\">\n <ng-content></ng-content>\n </label>\n\n <div class=\"tag-input-wrapper block w-full rounded-md bg-light-control dark:bg-dark-control disabled:bg-light-control/60 dark:disabled:bg-dark-control/80 px-2 py-1.5 text-base text-light-on-control dark:text-dark-on-control disabled:cursor-not-allowed disabled:text-light-on-control/60 dark:disabled:text-dark-on-control/80 outline -outline-offset-1 outline-light-inactive dark:outline-dark-inactive placeholder:text-light-inactive dark:placeholder:text-dark-inactive sm:text-sm/6\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <ng-container *ngFor=\"let tag of tags; let i = index\">\n <span class=\"inline-flex items-center gap-1 rounded-md bg-light-secondary dark:bg-dark-secondary text-light-on-secondary dark:text-dark-on-secondary px-2 py-0.5 text-xs\">\n {{ tag }}\n @if (!disabled) {\n <button type=\"button\" (click)=\"removeTag(i)\" class=\"text-light-on-secondary/80 hover:text-light-on-secondary dark:text-dark-on-secondary/80 dark:hover:text-dark-on-secondary hover:cursor-pointer\">\n \u00D7\n </button>\n }\n </span>\n </ng-container>\n\n <input #inputEl\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n class=\"flex-1 min-w-[8rem] bg-transparent outline-none placeholder:text-light-inactive dark:placeholder:text-dark-inactive\"\n [value]=\"inputValue\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.tag-input-wrapper:focus-within{outline-width:2px;outline-offset:2px;outline-color:var(--color-light-primary)!important}@media (prefers-color-scheme: dark){.tag-input-wrapper:focus-within{outline-color:var(--color-dark-primary)!important}}\n"] }]
|
|
3000
|
+
}], propDecorators: { label: [{
|
|
3001
|
+
type: ViewChild,
|
|
3002
|
+
args: ['label']
|
|
3003
|
+
}], inputEl: [{
|
|
3004
|
+
type: ViewChild,
|
|
3005
|
+
args: ['inputEl']
|
|
3006
|
+
}], placeholder: [{
|
|
3007
|
+
type: Input
|
|
3008
|
+
}], disabled: [{
|
|
3009
|
+
type: Input
|
|
3010
|
+
}], allowDuplicates: [{
|
|
3011
|
+
type: Input
|
|
3012
|
+
}], value: [{
|
|
3013
|
+
type: Input
|
|
3014
|
+
}], valueChange: [{
|
|
3015
|
+
type: Output
|
|
3016
|
+
}] } });
|
|
3017
|
+
|
|
2854
3018
|
class BreadcrumbService {
|
|
2855
3019
|
router;
|
|
2856
3020
|
coreService = inject(CoreService);
|
|
@@ -2963,5 +3127,5 @@ const provideHaloduckTransloco = () => provideTranslocoScope({
|
|
|
2963
3127
|
* Generated bundle index. Do not edit.
|
|
2964
3128
|
*/
|
|
2965
3129
|
|
|
2966
|
-
export { AuthenticateComponent, BreadcrumbComponent, ButtonComponent, CalendarComponent, ConfirmDialogService, CopyButtonComponent, DatePickerComponent, DateRangeComponent, DialogService, DrawCanvasComponent, ERROR_NOT_ACCEPTABLE_FILE_TYPE, ERROR_OVER_COUNT, ERROR_OVER_SIZE, ERROR_UPLOAD, FileUploaderComponent, FlipComponent, ImageUploaderComponent, ImageViewerComponent, InputComponent, LanguageSelectorComponent, MapToAddressComponent, NotificationComponent, NotificationService, PictureNameComponent, SelectComponent, SelectDropdownComponent, SideMenuComponent, SideMenuItemComponent, StlViewerComponent, TableComponent, TabsComponent, ToggleComponent, dateToString, provideHaloduckTransloco };
|
|
3130
|
+
export { AuthenticateComponent, BreadcrumbComponent, ButtonComponent, CalendarComponent, ConfirmDialogService, CopyButtonComponent, DatePickerComponent, DateRangeComponent, DialogService, DrawCanvasComponent, ERROR_NOT_ACCEPTABLE_FILE_TYPE, ERROR_OVER_COUNT, ERROR_OVER_SIZE, ERROR_UPLOAD, FileUploaderComponent, FlipComponent, ImageUploaderComponent, ImageViewerComponent, InputComponent, LanguageSelectorComponent, MapToAddressComponent, NotificationComponent, NotificationService, PictureNameComponent, SelectComponent, SelectDropdownComponent, SideMenuComponent, SideMenuItemComponent, StlViewerComponent, TableComponent, TabsComponent, TagInputComponent, ToggleComponent, dateToString, provideHaloduckTransloco };
|
|
2967
3131
|
//# sourceMappingURL=haloduck-ui.mjs.map
|