@frame-kit/ui-ng 0.2.21 → 0.2.22

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.
@@ -2,8 +2,6 @@ import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholde
2
2
  import { NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { inject, TemplateRef, Directive, model, input, output, contentChild, signal, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
5
- import * as i1 from '@angular/forms';
6
- import { FormsModule } from '@angular/forms';
7
5
  import { ButtonComponent, FkButtonIconStartDirective } from '@frame-kit/ui-ng/ui/button';
8
6
 
9
7
  /**
@@ -154,12 +152,11 @@ class ListEditorComponent {
154
152
  }
155
153
  }
156
154
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ListEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
157
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ListEditorComponent, isStandalone: true, selector: "fk-list-editor", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, addLabel: { classPropertyName: "addLabel", publicName: "addLabel", isSignal: true, isRequired: false, transformFunction: null }, orderable: { classPropertyName: "orderable", publicName: "orderable", isSignal: true, isRequired: false, transformFunction: null }, showOrder: { classPropertyName: "showOrder", publicName: "showOrder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, lockedItems: { classPropertyName: "lockedItems", publicName: "lockedItems", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", itemsChange: "itemsChange", itemAdded: "itemAdded", itemRemoved: "itemRemoved" }, host: { properties: { "class": "this.hostClass" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: FkListEditorItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"newItemValue()\"\n (ngModelChange)=\"newItemValue.set($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n", styles: [":host{display:block}.fk-list-editor__list{display:flex;flex-direction:column;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem))}.fk-list-editor__item{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-list-editor-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-list-editor-item-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-list-editor-item-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));transition:box-shadow .15s ease}.fk-list-editor__item:hover{box-shadow:var(--fk-list-editor-item-hover-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.fk-list-editor__icon{width:var(--fk-list-editor-icon-size, 1rem);height:var(--fk-list-editor-icon-size, 1rem)}.fk-list-editor__handle{display:flex;cursor:grab;color:var(--fk-list-editor-handle-color, var(--fk-color-muted, #8a98a8));padding:var(--fk-list-editor-handle-padding, var(--fk-rhythm-1, .25rem))}.fk-list-editor__handle:active{cursor:grabbing}.fk-list-editor__order{display:flex;align-items:center;justify-content:center;width:var(--fk-list-editor-order-size, 1.5rem);height:var(--fk-list-editor-order-size, 1.5rem);border-radius:var(--fk-list-editor-order-radius, 50%);background:var(--fk-list-editor-order-bg, var(--fk-color-primary-light, #e0f2fe));color:var(--fk-list-editor-order-color, var(--fk-color-primary, #0a84ff));font-size:var(--fk-list-editor-order-font-size, .75rem);font-weight:var(--fk-list-editor-order-font-weight, var(--fk-font-weight-semibold, 600));flex-shrink:0}.fk-list-editor__item-custom{flex:1;min-width:0}.fk-list-editor__input{font-family:var(--fk-list-editor-input-font-family, inherit);flex:1;min-width:0;padding:var(--fk-list-editor-input-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border:1px solid var(--fk-list-editor-input-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-input-radius, var(--fk-radius-md, .5rem));font-size:var(--fk-list-editor-input-font-size, .875rem);color:var(--fk-list-editor-input-color, var(--fk-color-text, #1f2d3d));background:var(--fk-list-editor-input-bg, var(--fk-color-surface, #ffffff));outline:none;transition:border-color .15s ease}.fk-list-editor__input:focus{border-color:var(--fk-list-editor-input-focus-border-color, var(--fk-color-primary, #0a84ff))}.fk-list-editor__input:disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));cursor:not-allowed}.fk-list-editor__remove{display:flex;align-items:center;padding:var(--fk-list-editor-remove-padding, var(--fk-rhythm-1, .25rem));border:none;background:transparent;cursor:pointer;color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));transition:color .15s ease}.fk-list-editor__remove:hover:not(:disabled){color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__remove:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__remove:disabled{opacity:.35;cursor:not-allowed}.fk-list-editor__placeholder{height:var(--fk-list-editor-placeholder-height, 3rem);border:2px dashed var(--fk-list-editor-placeholder-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));background:var(--fk-list-editor-placeholder-bg, var(--fk-color-surface-muted, #f7f9fb))}.fk-list-editor__empty{padding:var(--fk-list-editor-empty-padding, var(--fk-rhythm-4, 1rem));text-align:var(--fk-list-editor-empty-text-align, left);color:var(--fk-list-editor-empty-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-list-editor-empty-font-size, var(--fk-typography-small-font-size, .875rem))}.fk-list-editor__add{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));margin-top:var(--fk-list-editor-add-gap, var(--fk-rhythm-3, .75rem))}.fk-list-editor__add-input{position:relative;display:flex;flex:1;min-width:0}.fk-list-editor__add-input .fk-list-editor__input{padding-right:var(--fk-list-editor-add-clear-reserve, var(--fk-rhythm-7, 1.75rem))}.fk-list-editor__add-clear{position:absolute;top:50%;right:var(--fk-list-editor-add-clear-offset, var(--fk-rhythm-2, .5rem));transform:translateY(-50%);display:flex;align-items:center;justify-content:center;padding:var(--fk-list-editor-add-clear-padding, .125rem);border:0;background:transparent;border-radius:var(--fk-list-editor-add-clear-radius, var(--fk-radius-sm, .25rem));color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));cursor:pointer;transition:color .15s ease}.fk-list-editor__add-clear:hover{color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__add-clear:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__error{margin-top:var(--fk-list-editor-error-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-list-editor-error-color, var(--fk-color-danger, #e02424));font-size:var(--fk-list-editor-error-font-size, var(--fk-typography-small-font-size, .875rem))}:host.fk-list-editor--sm .fk-list-editor__input{font-size:var(--fk-list-editor-input-font-size-sm, .8125rem);padding:var(--fk-list-editor-input-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--sm .fk-list-editor__item{padding:var(--fk-list-editor-item-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));pointer-events:none}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.fk-list-editor__list.cdk-drop-list-dragging .fk-list-editor__item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview.fk-list-editor__item{box-shadow:var(--fk-list-editor-drag-shadow, 0 4px 12px rgba(0, 0, 0, .12));border-color:var(--fk-list-editor-drag-border-color, var(--fk-color-primary, #0a84ff))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: ButtonComponent, selector: "fk-button", inputs: ["variant", "size", "loading", "disabled", "type", "fullWidth", "id", "className", "ariaLabel", "ariaDescribedBy"] }, { kind: "directive", type: FkButtonIconStartDirective, selector: "[fkButtonIconStart]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
155
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ListEditorComponent, isStandalone: true, selector: "fk-list-editor", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, addLabel: { classPropertyName: "addLabel", publicName: "addLabel", isSignal: true, isRequired: false, transformFunction: null }, orderable: { classPropertyName: "orderable", publicName: "orderable", isSignal: true, isRequired: false, transformFunction: null }, showOrder: { classPropertyName: "showOrder", publicName: "showOrder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, lockedItems: { classPropertyName: "lockedItems", publicName: "lockedItems", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", itemsChange: "itemsChange", itemAdded: "itemAdded", itemRemoved: "itemRemoved" }, host: { properties: { "class": "this.hostClass" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: FkListEditorItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [value]=\"newItemValue()\"\n (input)=\"newItemValue.set($any($event.target).value)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n", styles: [":host{display:block}.fk-list-editor__list{display:flex;flex-direction:column;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem))}.fk-list-editor__item{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-list-editor-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-list-editor-item-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-list-editor-item-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));transition:box-shadow .15s ease}.fk-list-editor__item:hover{box-shadow:var(--fk-list-editor-item-hover-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.fk-list-editor__icon{width:var(--fk-list-editor-icon-size, 1rem);height:var(--fk-list-editor-icon-size, 1rem)}.fk-list-editor__handle{display:flex;cursor:grab;color:var(--fk-list-editor-handle-color, var(--fk-color-muted, #8a98a8));padding:var(--fk-list-editor-handle-padding, var(--fk-rhythm-1, .25rem))}.fk-list-editor__handle:active{cursor:grabbing}.fk-list-editor__order{display:flex;align-items:center;justify-content:center;width:var(--fk-list-editor-order-size, 1.5rem);height:var(--fk-list-editor-order-size, 1.5rem);border-radius:var(--fk-list-editor-order-radius, 50%);background:var(--fk-list-editor-order-bg, var(--fk-color-primary-light, #e0f2fe));color:var(--fk-list-editor-order-color, var(--fk-color-primary, #0a84ff));font-size:var(--fk-list-editor-order-font-size, .75rem);font-weight:var(--fk-list-editor-order-font-weight, var(--fk-font-weight-semibold, 600));flex-shrink:0}.fk-list-editor__item-custom{flex:1;min-width:0}.fk-list-editor__input{font-family:var(--fk-list-editor-input-font-family, inherit);flex:1;min-width:0;padding:var(--fk-list-editor-input-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border:1px solid var(--fk-list-editor-input-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-input-radius, var(--fk-radius-md, .5rem));font-size:var(--fk-list-editor-input-font-size, .875rem);color:var(--fk-list-editor-input-color, var(--fk-color-text, #1f2d3d));background:var(--fk-list-editor-input-bg, var(--fk-color-surface, #ffffff));outline:none;transition:border-color .15s ease}.fk-list-editor__input:focus{border-color:var(--fk-list-editor-input-focus-border-color, var(--fk-color-primary, #0a84ff))}.fk-list-editor__input:disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));cursor:not-allowed}.fk-list-editor__remove{display:flex;align-items:center;padding:var(--fk-list-editor-remove-padding, var(--fk-rhythm-1, .25rem));border:none;background:transparent;cursor:pointer;color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));transition:color .15s ease}.fk-list-editor__remove:hover:not(:disabled){color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__remove:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__remove:disabled{opacity:.35;cursor:not-allowed}.fk-list-editor__placeholder{height:var(--fk-list-editor-placeholder-height, 3rem);border:2px dashed var(--fk-list-editor-placeholder-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));background:var(--fk-list-editor-placeholder-bg, var(--fk-color-surface-muted, #f7f9fb))}.fk-list-editor__empty{padding:var(--fk-list-editor-empty-padding, var(--fk-rhythm-4, 1rem));text-align:var(--fk-list-editor-empty-text-align, left);color:var(--fk-list-editor-empty-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-list-editor-empty-font-size, var(--fk-typography-small-font-size, .875rem))}.fk-list-editor__add{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));margin-top:var(--fk-list-editor-add-gap, var(--fk-rhythm-3, .75rem))}.fk-list-editor__add-input{position:relative;display:flex;flex:1;min-width:0}.fk-list-editor__add-input .fk-list-editor__input{padding-right:var(--fk-list-editor-add-clear-reserve, var(--fk-rhythm-7, 1.75rem))}.fk-list-editor__add-clear{position:absolute;top:50%;right:var(--fk-list-editor-add-clear-offset, var(--fk-rhythm-2, .5rem));transform:translateY(-50%);display:flex;align-items:center;justify-content:center;padding:var(--fk-list-editor-add-clear-padding, .125rem);border:0;background:transparent;border-radius:var(--fk-list-editor-add-clear-radius, var(--fk-radius-sm, .25rem));color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));cursor:pointer;transition:color .15s ease}.fk-list-editor__add-clear:hover{color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__add-clear:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__error{margin-top:var(--fk-list-editor-error-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-list-editor-error-color, var(--fk-color-danger, #e02424));font-size:var(--fk-list-editor-error-font-size, var(--fk-typography-small-font-size, .875rem))}:host.fk-list-editor--sm .fk-list-editor__input{font-size:var(--fk-list-editor-input-font-size-sm, .8125rem);padding:var(--fk-list-editor-input-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--sm .fk-list-editor__item{padding:var(--fk-list-editor-item-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));pointer-events:none}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.fk-list-editor__list.cdk-drop-list-dragging .fk-list-editor__item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview.fk-list-editor__item{box-shadow:var(--fk-list-editor-drag-shadow, 0 4px 12px rgba(0, 0, 0, .12));border-color:var(--fk-list-editor-drag-border-color, var(--fk-color-primary, #0a84ff))}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: ButtonComponent, selector: "fk-button", inputs: ["variant", "size", "loading", "disabled", "type", "fullWidth", "id", "className", "ariaLabel", "ariaDescribedBy"] }, { kind: "directive", type: FkButtonIconStartDirective, selector: "[fkButtonIconStart]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
158
156
  }
159
157
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ListEditorComponent, decorators: [{
160
158
  type: Component,
161
159
  args: [{ selector: 'fk-list-editor', standalone: true, imports: [
162
- FormsModule,
163
160
  NgTemplateOutlet,
164
161
  CdkDropList,
165
162
  CdkDrag,
@@ -167,7 +164,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
167
164
  CdkDragPlaceholder,
168
165
  ButtonComponent,
169
166
  FkButtonIconStartDirective,
170
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"newItemValue()\"\n (ngModelChange)=\"newItemValue.set($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n", styles: [":host{display:block}.fk-list-editor__list{display:flex;flex-direction:column;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem))}.fk-list-editor__item{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-list-editor-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-list-editor-item-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-list-editor-item-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));transition:box-shadow .15s ease}.fk-list-editor__item:hover{box-shadow:var(--fk-list-editor-item-hover-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.fk-list-editor__icon{width:var(--fk-list-editor-icon-size, 1rem);height:var(--fk-list-editor-icon-size, 1rem)}.fk-list-editor__handle{display:flex;cursor:grab;color:var(--fk-list-editor-handle-color, var(--fk-color-muted, #8a98a8));padding:var(--fk-list-editor-handle-padding, var(--fk-rhythm-1, .25rem))}.fk-list-editor__handle:active{cursor:grabbing}.fk-list-editor__order{display:flex;align-items:center;justify-content:center;width:var(--fk-list-editor-order-size, 1.5rem);height:var(--fk-list-editor-order-size, 1.5rem);border-radius:var(--fk-list-editor-order-radius, 50%);background:var(--fk-list-editor-order-bg, var(--fk-color-primary-light, #e0f2fe));color:var(--fk-list-editor-order-color, var(--fk-color-primary, #0a84ff));font-size:var(--fk-list-editor-order-font-size, .75rem);font-weight:var(--fk-list-editor-order-font-weight, var(--fk-font-weight-semibold, 600));flex-shrink:0}.fk-list-editor__item-custom{flex:1;min-width:0}.fk-list-editor__input{font-family:var(--fk-list-editor-input-font-family, inherit);flex:1;min-width:0;padding:var(--fk-list-editor-input-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border:1px solid var(--fk-list-editor-input-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-input-radius, var(--fk-radius-md, .5rem));font-size:var(--fk-list-editor-input-font-size, .875rem);color:var(--fk-list-editor-input-color, var(--fk-color-text, #1f2d3d));background:var(--fk-list-editor-input-bg, var(--fk-color-surface, #ffffff));outline:none;transition:border-color .15s ease}.fk-list-editor__input:focus{border-color:var(--fk-list-editor-input-focus-border-color, var(--fk-color-primary, #0a84ff))}.fk-list-editor__input:disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));cursor:not-allowed}.fk-list-editor__remove{display:flex;align-items:center;padding:var(--fk-list-editor-remove-padding, var(--fk-rhythm-1, .25rem));border:none;background:transparent;cursor:pointer;color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));transition:color .15s ease}.fk-list-editor__remove:hover:not(:disabled){color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__remove:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__remove:disabled{opacity:.35;cursor:not-allowed}.fk-list-editor__placeholder{height:var(--fk-list-editor-placeholder-height, 3rem);border:2px dashed var(--fk-list-editor-placeholder-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));background:var(--fk-list-editor-placeholder-bg, var(--fk-color-surface-muted, #f7f9fb))}.fk-list-editor__empty{padding:var(--fk-list-editor-empty-padding, var(--fk-rhythm-4, 1rem));text-align:var(--fk-list-editor-empty-text-align, left);color:var(--fk-list-editor-empty-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-list-editor-empty-font-size, var(--fk-typography-small-font-size, .875rem))}.fk-list-editor__add{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));margin-top:var(--fk-list-editor-add-gap, var(--fk-rhythm-3, .75rem))}.fk-list-editor__add-input{position:relative;display:flex;flex:1;min-width:0}.fk-list-editor__add-input .fk-list-editor__input{padding-right:var(--fk-list-editor-add-clear-reserve, var(--fk-rhythm-7, 1.75rem))}.fk-list-editor__add-clear{position:absolute;top:50%;right:var(--fk-list-editor-add-clear-offset, var(--fk-rhythm-2, .5rem));transform:translateY(-50%);display:flex;align-items:center;justify-content:center;padding:var(--fk-list-editor-add-clear-padding, .125rem);border:0;background:transparent;border-radius:var(--fk-list-editor-add-clear-radius, var(--fk-radius-sm, .25rem));color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));cursor:pointer;transition:color .15s ease}.fk-list-editor__add-clear:hover{color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__add-clear:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__error{margin-top:var(--fk-list-editor-error-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-list-editor-error-color, var(--fk-color-danger, #e02424));font-size:var(--fk-list-editor-error-font-size, var(--fk-typography-small-font-size, .875rem))}:host.fk-list-editor--sm .fk-list-editor__input{font-size:var(--fk-list-editor-input-font-size-sm, .8125rem);padding:var(--fk-list-editor-input-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--sm .fk-list-editor__item{padding:var(--fk-list-editor-item-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));pointer-events:none}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.fk-list-editor__list.cdk-drop-list-dragging .fk-list-editor__item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview.fk-list-editor__item{box-shadow:var(--fk-list-editor-drag-shadow, 0 4px 12px rgba(0, 0, 0, .12));border-color:var(--fk-list-editor-drag-border-color, var(--fk-color-primary, #0a84ff))}\n"] }]
167
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [value]=\"newItemValue()\"\n (input)=\"newItemValue.set($any($event.target).value)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n", styles: [":host{display:block}.fk-list-editor__list{display:flex;flex-direction:column;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem))}.fk-list-editor__item{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-list-editor-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-list-editor-item-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-list-editor-item-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));transition:box-shadow .15s ease}.fk-list-editor__item:hover{box-shadow:var(--fk-list-editor-item-hover-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.fk-list-editor__icon{width:var(--fk-list-editor-icon-size, 1rem);height:var(--fk-list-editor-icon-size, 1rem)}.fk-list-editor__handle{display:flex;cursor:grab;color:var(--fk-list-editor-handle-color, var(--fk-color-muted, #8a98a8));padding:var(--fk-list-editor-handle-padding, var(--fk-rhythm-1, .25rem))}.fk-list-editor__handle:active{cursor:grabbing}.fk-list-editor__order{display:flex;align-items:center;justify-content:center;width:var(--fk-list-editor-order-size, 1.5rem);height:var(--fk-list-editor-order-size, 1.5rem);border-radius:var(--fk-list-editor-order-radius, 50%);background:var(--fk-list-editor-order-bg, var(--fk-color-primary-light, #e0f2fe));color:var(--fk-list-editor-order-color, var(--fk-color-primary, #0a84ff));font-size:var(--fk-list-editor-order-font-size, .75rem);font-weight:var(--fk-list-editor-order-font-weight, var(--fk-font-weight-semibold, 600));flex-shrink:0}.fk-list-editor__item-custom{flex:1;min-width:0}.fk-list-editor__input{font-family:var(--fk-list-editor-input-font-family, inherit);flex:1;min-width:0;padding:var(--fk-list-editor-input-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border:1px solid var(--fk-list-editor-input-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-input-radius, var(--fk-radius-md, .5rem));font-size:var(--fk-list-editor-input-font-size, .875rem);color:var(--fk-list-editor-input-color, var(--fk-color-text, #1f2d3d));background:var(--fk-list-editor-input-bg, var(--fk-color-surface, #ffffff));outline:none;transition:border-color .15s ease}.fk-list-editor__input:focus{border-color:var(--fk-list-editor-input-focus-border-color, var(--fk-color-primary, #0a84ff))}.fk-list-editor__input:disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));cursor:not-allowed}.fk-list-editor__remove{display:flex;align-items:center;padding:var(--fk-list-editor-remove-padding, var(--fk-rhythm-1, .25rem));border:none;background:transparent;cursor:pointer;color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));transition:color .15s ease}.fk-list-editor__remove:hover:not(:disabled){color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__remove:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__remove:disabled{opacity:.35;cursor:not-allowed}.fk-list-editor__placeholder{height:var(--fk-list-editor-placeholder-height, 3rem);border:2px dashed var(--fk-list-editor-placeholder-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-list-editor-item-radius, var(--fk-radius-md, .5rem));background:var(--fk-list-editor-placeholder-bg, var(--fk-color-surface-muted, #f7f9fb))}.fk-list-editor__empty{padding:var(--fk-list-editor-empty-padding, var(--fk-rhythm-4, 1rem));text-align:var(--fk-list-editor-empty-text-align, left);color:var(--fk-list-editor-empty-color, var(--fk-color-muted, #8a98a8));font-size:var(--fk-list-editor-empty-font-size, var(--fk-typography-small-font-size, .875rem))}.fk-list-editor__add{display:flex;align-items:center;gap:var(--fk-list-editor-row-gap, var(--fk-rhythm-2, .5rem));margin-top:var(--fk-list-editor-add-gap, var(--fk-rhythm-3, .75rem))}.fk-list-editor__add-input{position:relative;display:flex;flex:1;min-width:0}.fk-list-editor__add-input .fk-list-editor__input{padding-right:var(--fk-list-editor-add-clear-reserve, var(--fk-rhythm-7, 1.75rem))}.fk-list-editor__add-clear{position:absolute;top:50%;right:var(--fk-list-editor-add-clear-offset, var(--fk-rhythm-2, .5rem));transform:translateY(-50%);display:flex;align-items:center;justify-content:center;padding:var(--fk-list-editor-add-clear-padding, .125rem);border:0;background:transparent;border-radius:var(--fk-list-editor-add-clear-radius, var(--fk-radius-sm, .25rem));color:var(--fk-list-editor-remove-color, var(--fk-color-muted, #8a98a8));cursor:pointer;transition:color .15s ease}.fk-list-editor__add-clear:hover{color:var(--fk-list-editor-remove-hover-color, var(--fk-color-danger, #e02424))}.fk-list-editor__add-clear:focus-visible{outline:none;box-shadow:var(--fk-list-editor-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-list-editor__error{margin-top:var(--fk-list-editor-error-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-list-editor-error-color, var(--fk-color-danger, #e02424));font-size:var(--fk-list-editor-error-font-size, var(--fk-typography-small-font-size, .875rem))}:host.fk-list-editor--sm .fk-list-editor__input{font-size:var(--fk-list-editor-input-font-size-sm, .8125rem);padding:var(--fk-list-editor-input-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--sm .fk-list-editor__item{padding:var(--fk-list-editor-item-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-list-editor--disabled{opacity:var(--fk-list-editor-disabled-opacity, var(--fk-input-disabled-opacity, .5));pointer-events:none}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.fk-list-editor__list.cdk-drop-list-dragging .fk-list-editor__item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview.fk-list-editor__item{box-shadow:var(--fk-list-editor-drag-shadow, 0 4px 12px rgba(0, 0, 0, .12));border-color:var(--fk-list-editor-drag-border-color, var(--fk-color-primary, #0a84ff))}\n"] }]
171
168
  }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }, { type: i0.Output, args: ["itemsChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], addLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "addLabel", required: false }] }], orderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "orderable", required: false }] }], showOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOrder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], lockedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockedItems", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], itemsChange: [{ type: i0.Output, args: ["itemsChange"] }], itemAdded: [{ type: i0.Output, args: ["itemAdded"] }], itemRemoved: [{ type: i0.Output, args: ["itemRemoved"] }], itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FkListEditorItemDirective), { isSignal: true }] }], hostClass: [{
172
169
  type: HostBinding,
173
170
  args: ['class']
@@ -1 +1 @@
1
- {"version":3,"file":"frame-kit-ui-ng-ui-list-editor.mjs","sources":["../../../../packages/ui-ng/ui/list-editor/list-editor-item.directive.ts","../../../../packages/ui-ng/ui/list-editor/list-editor.component.ts","../../../../packages/ui-ng/ui/list-editor/list-editor.component.html","../../../../packages/ui-ng/ui/list-editor/frame-kit-ui-ng-ui-list-editor.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { ListEditorItemContext } from './list-editor.types';\n\n/**\n * Marks an `<ng-template>` as the per-row renderer for `fk-list-editor`. When\n * present, the editor renders this template for each item instead of its\n * default editable input + remove button, so the consumer owns the row markup\n * (scheme tag, status, custom actions, …). The add-input, empty state, and\n * optional drag/order chrome are still provided by the editor.\n *\n * ```html\n * <fk-list-editor [items]=\"origins\">\n * <ng-template fkListEditorItem let-origin let-remove=\"remove\">\n * <span>{{ origin }}</span>\n * <button (click)=\"remove()\">Remove</button>\n * </ng-template>\n * </fk-list-editor>\n * ```\n */\n@Directive({\n selector: '[fkListEditorItem]',\n standalone: true,\n})\nexport class FkListEditorItemDirective {\n readonly templateRef = inject(TemplateRef<ListEditorItemContext>);\n}\n","import {\n CdkDrag,\n CdkDragDrop,\n CdkDragHandle,\n CdkDragPlaceholder,\n CdkDropList,\n moveItemInArray,\n} from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n HostBinding,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ButtonComponent } from '@frame-kit/ui-ng/ui/button';\nimport { FkButtonIconStartDirective } from '@frame-kit/ui-ng/ui/button';\nimport { FkListEditorItemDirective } from './list-editor-item.directive';\nimport type {\n ListEditorItemContext,\n ListEditorSize,\n} from './list-editor.types';\n\n@Component({\n selector: 'fk-list-editor',\n standalone: true,\n imports: [\n FormsModule,\n NgTemplateOutlet,\n CdkDropList,\n CdkDrag,\n CdkDragHandle,\n CdkDragPlaceholder,\n ButtonComponent,\n FkButtonIconStartDirective,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './list-editor.component.html',\n styleUrl: './list-editor.component.scss',\n})\nexport class ListEditorComponent {\n // ===== INPUTS =====\n /** The current list of string items; two-way bindable via `[(items)]`. */\n readonly items = model<string[]>([]);\n /** Placeholder text for the new-item input field. */\n readonly placeholder = input('Add an item...');\n /** Message displayed when the list is empty. */\n readonly emptyMessage = input('No items added yet.');\n /** Label for the add button. */\n readonly addLabel = input('Add');\n /** When true, items can be reordered via drag-and-drop. */\n readonly orderable = input(true);\n /** When true, shows a numeric position indicator next to each item. */\n readonly showOrder = input(true);\n /** Size variant controlling the spacing and font of the component. */\n readonly size = input<ListEditorSize>('md');\n /** Items that cannot be removed by the user (matched case-insensitively). */\n readonly lockedItems = input<string[]>([]);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly disabled = input(false);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires whenever the items array changes, emitting the full updated array. */\n readonly itemsChange = output<string[]>();\n /** Fires when a new item is successfully added, emitting the added value. */\n readonly itemAdded = output<string>();\n /** Fires when an item is removed, emitting the removed value and its former index. */\n readonly itemRemoved = output<{ item: string; index: number }>();\n\n // ===== CONTENT =====\n /**\n * Optional custom row template (`*fkListEditorItem`). When provided, each\n * item renders through it instead of the default editable input + remove\n * button.\n */\n readonly itemTemplate = contentChild(FkListEditorItemDirective);\n\n // ===== LOCAL STATE =====\n readonly newItemValue = signal('');\n\n // ===== COMPUTED =====\n readonly canAdd = computed(() => {\n const value = this.newItemValue().trim();\n\n if (!value) {\n return false;\n }\n\n const existing = this.items().map((n) => n.trim().toLowerCase());\n\n return !existing.includes(value.toLowerCase());\n });\n\n readonly hasDuplicates = computed(() => {\n const names = this.items().map((n) => n.trim().toLowerCase());\n\n return new Set(names).size !== names.length;\n });\n\n readonly hasEmptyItems = computed(() => {\n return this.items().some((n) => n.trim() === '');\n });\n\n readonly classes = computed(() =>\n [\n 'fk-list-editor',\n `fk-list-editor--${this.size()}`,\n this.disabled() ? 'fk-list-editor--disabled' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n // ===== ACTIONS =====\n\n /** Adds the current input value as a new item if it is non-empty and not a duplicate. */\n addItem(): void {\n const value = this.newItemValue().trim();\n\n if (!value || !this.canAdd() || this.disabled()) {\n return;\n }\n\n this.items.update((prev) => [...prev, value]);\n this.newItemValue.set('');\n this.itemsChange.emit(this.items());\n this.itemAdded.emit(value);\n }\n\n /** Removes the item at the given index unless it is locked or the component is disabled. */\n removeItem(index: number): void {\n const item = this.items()[index];\n\n if (this.disabled() || this.isLocked(item)) {\n return;\n }\n\n this.items.update((prev) => prev.filter((_, i) => i !== index));\n this.itemsChange.emit(this.items());\n this.itemRemoved.emit({ item, index });\n }\n\n /** Updates the item at the given index with a new value and emits the changed array. */\n updateItem(index: number, value: string): void {\n this.items.update((prev) =>\n prev.map((item, i) => (i === index ? value : item)),\n );\n this.itemsChange.emit(this.items());\n }\n\n onDrop(event: CdkDragDrop<string[]>): void {\n const updated = [...this.items()];\n\n moveItemInArray(updated, event.previousIndex, event.currentIndex);\n this.items.set(updated);\n this.itemsChange.emit(this.items());\n }\n\n /** Returns true if the given item matches any entry in `lockedItems`. */\n isLocked(item: string): boolean {\n return this.lockedItems().includes(item.trim().toLowerCase());\n }\n\n /** Builds the `let-` context for a custom row template. */\n contextFor(item: string, index: number): ListEditorItemContext {\n return {\n $implicit: item,\n index,\n locked: this.isLocked(item),\n remove: () => this.removeItem(index),\n update: (value: string) => this.updateItem(index, value),\n };\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.addItem();\n }\n }\n}\n","<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"newItemValue()\"\n (ngModelChange)=\"newItemValue.set($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frame-kit-ui-ng-ui-list-editor.mjs","sources":["../../../../packages/ui-ng/ui/list-editor/list-editor-item.directive.ts","../../../../packages/ui-ng/ui/list-editor/list-editor.component.ts","../../../../packages/ui-ng/ui/list-editor/list-editor.component.html","../../../../packages/ui-ng/ui/list-editor/frame-kit-ui-ng-ui-list-editor.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { ListEditorItemContext } from './list-editor.types';\n\n/**\n * Marks an `<ng-template>` as the per-row renderer for `fk-list-editor`. When\n * present, the editor renders this template for each item instead of its\n * default editable input + remove button, so the consumer owns the row markup\n * (scheme tag, status, custom actions, …). The add-input, empty state, and\n * optional drag/order chrome are still provided by the editor.\n *\n * ```html\n * <fk-list-editor [items]=\"origins\">\n * <ng-template fkListEditorItem let-origin let-remove=\"remove\">\n * <span>{{ origin }}</span>\n * <button (click)=\"remove()\">Remove</button>\n * </ng-template>\n * </fk-list-editor>\n * ```\n */\n@Directive({\n selector: '[fkListEditorItem]',\n standalone: true,\n})\nexport class FkListEditorItemDirective {\n readonly templateRef = inject(TemplateRef<ListEditorItemContext>);\n}\n","import {\n CdkDrag,\n CdkDragDrop,\n CdkDragHandle,\n CdkDragPlaceholder,\n CdkDropList,\n moveItemInArray,\n} from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n HostBinding,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\n\nimport { ButtonComponent } from '@frame-kit/ui-ng/ui/button';\nimport { FkButtonIconStartDirective } from '@frame-kit/ui-ng/ui/button';\nimport { FkListEditorItemDirective } from './list-editor-item.directive';\nimport type {\n ListEditorItemContext,\n ListEditorSize,\n} from './list-editor.types';\n\n@Component({\n selector: 'fk-list-editor',\n standalone: true,\n imports: [\n NgTemplateOutlet,\n CdkDropList,\n CdkDrag,\n CdkDragHandle,\n CdkDragPlaceholder,\n ButtonComponent,\n FkButtonIconStartDirective,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './list-editor.component.html',\n styleUrl: './list-editor.component.scss',\n})\nexport class ListEditorComponent {\n // ===== INPUTS =====\n /** The current list of string items; two-way bindable via `[(items)]`. */\n readonly items = model<string[]>([]);\n /** Placeholder text for the new-item input field. */\n readonly placeholder = input('Add an item...');\n /** Message displayed when the list is empty. */\n readonly emptyMessage = input('No items added yet.');\n /** Label for the add button. */\n readonly addLabel = input('Add');\n /** When true, items can be reordered via drag-and-drop. */\n readonly orderable = input(true);\n /** When true, shows a numeric position indicator next to each item. */\n readonly showOrder = input(true);\n /** Size variant controlling the spacing and font of the component. */\n readonly size = input<ListEditorSize>('md');\n /** Items that cannot be removed by the user (matched case-insensitively). */\n readonly lockedItems = input<string[]>([]);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly disabled = input(false);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires whenever the items array changes, emitting the full updated array. */\n readonly itemsChange = output<string[]>();\n /** Fires when a new item is successfully added, emitting the added value. */\n readonly itemAdded = output<string>();\n /** Fires when an item is removed, emitting the removed value and its former index. */\n readonly itemRemoved = output<{ item: string; index: number }>();\n\n // ===== CONTENT =====\n /**\n * Optional custom row template (`*fkListEditorItem`). When provided, each\n * item renders through it instead of the default editable input + remove\n * button.\n */\n readonly itemTemplate = contentChild(FkListEditorItemDirective);\n\n // ===== LOCAL STATE =====\n readonly newItemValue = signal('');\n\n // ===== COMPUTED =====\n readonly canAdd = computed(() => {\n const value = this.newItemValue().trim();\n\n if (!value) {\n return false;\n }\n\n const existing = this.items().map((n) => n.trim().toLowerCase());\n\n return !existing.includes(value.toLowerCase());\n });\n\n readonly hasDuplicates = computed(() => {\n const names = this.items().map((n) => n.trim().toLowerCase());\n\n return new Set(names).size !== names.length;\n });\n\n readonly hasEmptyItems = computed(() => {\n return this.items().some((n) => n.trim() === '');\n });\n\n readonly classes = computed(() =>\n [\n 'fk-list-editor',\n `fk-list-editor--${this.size()}`,\n this.disabled() ? 'fk-list-editor--disabled' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n // ===== ACTIONS =====\n\n /** Adds the current input value as a new item if it is non-empty and not a duplicate. */\n addItem(): void {\n const value = this.newItemValue().trim();\n\n if (!value || !this.canAdd() || this.disabled()) {\n return;\n }\n\n this.items.update((prev) => [...prev, value]);\n this.newItemValue.set('');\n this.itemsChange.emit(this.items());\n this.itemAdded.emit(value);\n }\n\n /** Removes the item at the given index unless it is locked or the component is disabled. */\n removeItem(index: number): void {\n const item = this.items()[index];\n\n if (this.disabled() || this.isLocked(item)) {\n return;\n }\n\n this.items.update((prev) => prev.filter((_, i) => i !== index));\n this.itemsChange.emit(this.items());\n this.itemRemoved.emit({ item, index });\n }\n\n /** Updates the item at the given index with a new value and emits the changed array. */\n updateItem(index: number, value: string): void {\n this.items.update((prev) =>\n prev.map((item, i) => (i === index ? value : item)),\n );\n this.itemsChange.emit(this.items());\n }\n\n onDrop(event: CdkDragDrop<string[]>): void {\n const updated = [...this.items()];\n\n moveItemInArray(updated, event.previousIndex, event.currentIndex);\n this.items.set(updated);\n this.itemsChange.emit(this.items());\n }\n\n /** Returns true if the given item matches any entry in `lockedItems`. */\n isLocked(item: string): boolean {\n return this.lockedItems().includes(item.trim().toLowerCase());\n }\n\n /** Builds the `let-` context for a custom row template. */\n contextFor(item: string, index: number): ListEditorItemContext {\n return {\n $implicit: item,\n index,\n locked: this.isLocked(item),\n remove: () => this.removeItem(index),\n update: (value: string) => this.updateItem(index, value),\n };\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.addItem();\n }\n }\n}\n","<div\n cdkDropList\n [cdkDropListDisabled]=\"disabled() || !orderable()\"\n (cdkDropListDropped)=\"onDrop($event)\"\n class=\"fk-list-editor__list\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @for (item of items(); track $index) {\n <div\n cdkDrag\n [cdkDragDisabled]=\"disabled() || !orderable()\"\n class=\"fk-list-editor__item\"\n >\n @if (orderable()) {\n <span class=\"fk-list-editor__handle\" cdkDragHandle>\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n\n @if (showOrder()) {\n <span class=\"fk-list-editor__order\">{{ $index + 1 }}</span>\n }\n\n @if (itemTemplate(); as def) {\n <div class=\"fk-list-editor__item-custom\">\n <ng-container\n [ngTemplateOutlet]=\"def.templateRef\"\n [ngTemplateOutletContext]=\"contextFor(item, $index)\"\n />\n </div>\n } @else {\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [value]=\"item\"\n [disabled]=\"disabled() || isLocked(item)\"\n (input)=\"updateItem($index, $any($event.target).value)\"\n />\n\n <button\n class=\"fk-list-editor__remove\"\n type=\"button\"\n [disabled]=\"disabled() || isLocked(item)\"\n [title]=\"\n isLocked(item) ? 'This item cannot be removed' : 'Remove item'\n \"\n (click)=\"removeItem($index)\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n\n <div *cdkDragPlaceholder class=\"fk-list-editor__placeholder\"></div>\n </div>\n }\n</div>\n\n@if (items().length === 0 && emptyMessage()) {\n <p class=\"fk-list-editor__empty\">{{ emptyMessage() }}</p>\n}\n\n<div class=\"fk-list-editor__add\">\n <div class=\"fk-list-editor__add-input\">\n <input\n class=\"fk-list-editor__input\"\n type=\"text\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [value]=\"newItemValue()\"\n (input)=\"newItemValue.set($any($event.target).value)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n @if (newItemValue() && !disabled()) {\n <button\n class=\"fk-list-editor__add-clear\"\n type=\"button\"\n aria-label=\"Clear input\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"newItemValue.set('')\"\n >\n <svg\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n\n <fk-button\n variant=\"outline\"\n size=\"sm\"\n [disabled]=\"!canAdd() || disabled()\"\n (click)=\"addItem()\"\n >\n <svg\n fkButtonIconStart\n class=\"fk-list-editor__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12 5v14M5 12h14\"\n stroke=\"currentColor\"\n stroke-width=\"1.9\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ addLabel() }}\n </fk-button>\n</div>\n\n@if (hasDuplicates()) {\n <p class=\"fk-list-editor__error\">Item names must be unique.</p>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frame-kit/ui-ng",
3
- "version": "0.2.21",
3
+ "version": "0.2.22",
4
4
  "description": "Style-agnostic, token-driven Angular UI component library for FrameKit.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,7 +17,7 @@
17
17
  "@angular/forms": "^21.2.0",
18
18
  "@angular/platform-browser": "^21.2.0",
19
19
  "@angular/router": "^21.2.0",
20
- "@frame-kit/utils": "0.2.21",
20
+ "@frame-kit/utils": "0.2.22",
21
21
  "rxjs": "^7.0.0"
22
22
  },
23
23
  "sideEffects": false,