@frame-kit/ui-ng 0.0.1
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/COMPONENTS.md +683 -0
- package/DEVELOPMENT_GUIDE.md +1102 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/THEMING.md +130 -0
- package/core/headline/README.md +121 -0
- package/core/icon/README.md +173 -0
- package/core/image/README.md +210 -0
- package/core/link/README.md +297 -0
- package/core/separator/README.md +145 -0
- package/core/text/README.md +240 -0
- package/directives/infinite-scroll/README.md +102 -0
- package/directives/spotlight/README.md +154 -0
- package/directives/tooltip/README.md +147 -0
- package/docs/endpoint-link/README.md +142 -0
- package/docs/method-badge/README.md +154 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
- package/layouts/app-shell/README.md +357 -0
- package/layouts/content-split/README.md +180 -0
- package/package.json +253 -0
- package/services/overlay-orchestrator/README.md +184 -0
- package/services/spotlight/README.md +61 -0
- package/services/toast/README.md +118 -0
- package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
- package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
- package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
- package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
- package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
- package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
- package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
- package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
- package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
- package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
- package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
- package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
- package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
- package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
- package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
- package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
- package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
- package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
- package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
- package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
- package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
- package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
- package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
- package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
- package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
- package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
- package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
- package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
- package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
- package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
- package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
- package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
- package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
- package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
- package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
- package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
- package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
- package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
- package/types/frame-kit-ui-ng.d.ts +53 -0
- package/ui/accordion/README.md +261 -0
- package/ui/alert/README.md +211 -0
- package/ui/avatar/README.md +167 -0
- package/ui/avatar-stack/README.md +164 -0
- package/ui/badge/README.md +162 -0
- package/ui/breadcrumb/README.md +240 -0
- package/ui/button/README.md +184 -0
- package/ui/callout/README.md +159 -0
- package/ui/card/README.md +174 -0
- package/ui/copyable-field/README.md +235 -0
- package/ui/data-table/README.md +408 -0
- package/ui/dialog/README.md +222 -0
- package/ui/drawer/README.md +274 -0
- package/ui/dropdown-menu/README.md +336 -0
- package/ui/editable-field/README.md +171 -0
- package/ui/icon-badge/README.md +131 -0
- package/ui/icon-list/README.md +205 -0
- package/ui/inline-edit/README.md +135 -0
- package/ui/list-editor/README.md +162 -0
- package/ui/loader/README.md +160 -0
- package/ui/menu-item/README.md +204 -0
- package/ui/nav-brand/README.md +111 -0
- package/ui/nav-group/README.md +145 -0
- package/ui/nav-separator/README.md +44 -0
- package/ui/node-tree/README.md +278 -0
- package/ui/node-tree-breadcrumb/README.md +164 -0
- package/ui/note/README.md +146 -0
- package/ui/numbered-list/README.md +187 -0
- package/ui/pagination/README.md +174 -0
- package/ui/progress-bar/README.md +223 -0
- package/ui/sidenav-link/README.md +214 -0
- package/ui/tabs/README.md +204 -0
- package/ui/timeline/README.md +285 -0
- package/ui/toast/README.md +243 -0
- package/ui/user-menu/README.md +260 -0
- package/ui/wizard-dialog/README.md +283 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-editable-field.mjs","sources":["../../../../packages/ui-ng/ui/editable-field/editable-field.component.ts","../../../../packages/ui-ng/ui/editable-field/editable-field.component.html","../../../../packages/ui-ng/ui/editable-field/frame-kit-ui-ng-ui-editable-field.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n HostBinding,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\n\nimport { IconComponent } from '@frame-kit/ui-ng/core/icon';\nimport type { EditableFieldSize } from './editable-field.types';\n\n/**\n * A single-line text field that lives in two states:\n *\n * - **Display** — the field reads as a regular bordered input\n * showing the current value. A pencil icon sits inside the\n * trailing edge. Clicking anywhere on the field surface enters\n * edit mode.\n * - **Edit** — the field becomes a live `<input>`. The pencil slot\n * swaps to a cancel (✗) icon inside the trailing edge. A\n * separate Save button slides in as a sibling to the field's\n * right.\n *\n * Distinct from `fk-inline-edit`, which renders the value as a span +\n * an Edit button as siblings. `fk-editable-field` is meant for form-\n * shaped surfaces (billing details, profile pages) where every row\n * should *look* like a regular input even in display mode.\n *\n * The save / cancel / pencil icons can be overridden via the named\n * content slots `[editIcon]`, `[cancelIcon]`, and `[saveIcon]`.\n */\n@Component({\n selector: 'fk-editable-field',\n standalone: true,\n imports: [IconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './editable-field.component.html',\n styleUrl: './editable-field.component.scss',\n})\nexport class EditableFieldComponent {\n // ===== INPUTS =====\n\n /** Current committed value displayed in read mode. */\n readonly value = input<string>('');\n /** Placeholder text shown in the input when the edit buffer is empty. */\n readonly placeholder = input<string>('Enter a value…');\n /** Size variant controlling the font and spacing of the component. */\n readonly size = input<EditableFieldSize>('md');\n /** Text displayed in read mode when the committed value is empty. */\n readonly emptyText = input<string>('None');\n\n // ===== BASE PROPS =====\n\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n readonly disabled = input(false);\n\n // ===== OUTPUTS =====\n\n /** Fires when the user saves an edit, emitting the trimmed new value. */\n readonly valueChange = output<string>();\n /** Fires when the component enters edit mode. */\n readonly editStart = output<void>();\n /** Fires when the user cancels an in-progress edit without saving. */\n readonly editCancel = output<void>();\n\n // ===== STATE =====\n\n readonly editing = signal(false);\n readonly editValue = signal('');\n\n readonly inputRef = viewChild<ElementRef<HTMLInputElement>>('inputEl');\n\n // ===== COMPUTED =====\n\n readonly classes = computed(() =>\n [\n 'fk-editable-field',\n `fk-editable-field--${this.size()}`,\n this.editing() ? 'fk-editable-field--editing' : '',\n this.disabled() ? 'fk-editable-field--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 @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== METHODS =====\n\n /** Enters edit mode and focuses the input, copying the current value into the edit buffer. */\n startEdit(): void {\n if (this.disabled()) {\n return;\n }\n\n this.editValue.set(this.value());\n this.editing.set(true);\n this.editStart.emit();\n\n setTimeout(() => {\n this.inputRef()?.nativeElement.focus();\n });\n }\n\n /** Commits the current edit buffer, exits edit mode, and emits the trimmed value. */\n save(): void {\n const trimmed = this.editValue().trim();\n\n this.editing.set(false);\n this.valueChange.emit(trimmed);\n }\n\n /** Discards the current edit buffer and exits edit mode. */\n cancel(): void {\n this.editing.set(false);\n this.editCancel.emit();\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.save();\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.cancel();\n }\n }\n\n onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n\n this.editValue.set(target.value);\n }\n}\n","@if (editing()) {\n <div class=\"fk-editable-field__container\">\n <div class=\"fk-editable-field__field fk-editable-field__field--editing\">\n <input\n #inputEl\n class=\"fk-editable-field__input\"\n type=\"text\"\n [value]=\"editValue()\"\n [placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <button\n class=\"fk-editable-field__inline-btn\"\n type=\"button\"\n aria-label=\"Cancel\"\n (click)=\"cancel()\"\n >\n <ng-content select=\"[cancelIcon]\">\n <fk-icon name=\"circle-xmark-outline\" size=\"sm\" />\n </ng-content>\n </button>\n </div>\n\n <button\n class=\"fk-editable-field__save\"\n type=\"button\"\n aria-label=\"Save\"\n (click)=\"save()\"\n >\n <ng-content select=\"[saveIcon]\">\n <span class=\"fk-editable-field__save-text\">Save</span>\n </ng-content>\n </button>\n </div>\n} @else {\n <button\n class=\"fk-editable-field__field fk-editable-field__field--display\"\n type=\"button\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"ariaLabel() ? 'Edit ' + ariaLabel() : 'Edit'\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (click)=\"startEdit()\"\n >\n <span class=\"fk-editable-field__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <span class=\"fk-editable-field__empty\">{{ emptyText() }}</span>\n }\n </span>\n\n @if (!disabled()) {\n <span\n class=\"fk-editable-field__inline-btn fk-editable-field__inline-btn--decoration\"\n >\n <ng-content select=\"[editIcon]\">\n <fk-icon name=\"pen-outline\" size=\"sm\" />\n </ng-content>\n </span>\n }\n </button>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { IconComponent } from '@frame-kit/ui-ng/core/icon';
|
|
4
|
+
|
|
5
|
+
class IconBadgeComponent {
|
|
6
|
+
// ===== INPUTS =====
|
|
7
|
+
/** Name of the icon rendered inside the badge container. */
|
|
8
|
+
name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
9
|
+
/** Size of the icon within the badge. */
|
|
10
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
11
|
+
/** Size of the badge container; defaults to matching `size` when null. */
|
|
12
|
+
badgeSize = input(null, ...(ngDevMode ? [{ debugName: "badgeSize" }] : /* istanbul ignore next */ []));
|
|
13
|
+
/** Shape of the badge container — circle or square. */
|
|
14
|
+
shape = input('circle', ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
15
|
+
/** Color of the icon. */
|
|
16
|
+
color = input('inherit', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
17
|
+
/** Custom border color applied directly to the host element. */
|
|
18
|
+
borderColor = input(null, ...(ngDevMode ? [{ debugName: "borderColor" }] : /* istanbul ignore next */ []));
|
|
19
|
+
/** Custom background color applied directly to the host element. */
|
|
20
|
+
backgroundColor = input(null, ...(ngDevMode ? [{ debugName: "backgroundColor" }] : /* istanbul ignore next */ []));
|
|
21
|
+
// ===== BASE PROPS =====
|
|
22
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
23
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
24
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
25
|
+
/** Explicit aria-hidden override; when null it defaults to true unless `ariaLabel` is set. */
|
|
26
|
+
ariaHidden = input(null, ...(ngDevMode ? [{ debugName: "ariaHidden" }] : /* istanbul ignore next */ []));
|
|
27
|
+
// ===== COMPUTED =====
|
|
28
|
+
badgeSizePresets = ['xs', 'sm', 'md', 'lg', 'xl'];
|
|
29
|
+
effectiveBadgeSize = computed(() => {
|
|
30
|
+
return this.badgeSize() ?? this.size();
|
|
31
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveBadgeSize" }] : /* istanbul ignore next */ []));
|
|
32
|
+
isCustomBadgeSize = computed(() => !this.badgeSizePresets.includes(this.effectiveBadgeSize()), ...(ngDevMode ? [{ debugName: "isCustomBadgeSize" }] : /* istanbul ignore next */ []));
|
|
33
|
+
effectiveAriaHidden = computed(() => {
|
|
34
|
+
const explicit = this.ariaHidden();
|
|
35
|
+
if (explicit !== null) {
|
|
36
|
+
return explicit;
|
|
37
|
+
}
|
|
38
|
+
return this.ariaLabel() === null;
|
|
39
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveAriaHidden" }] : /* istanbul ignore next */ []));
|
|
40
|
+
classes = computed(() => {
|
|
41
|
+
return [
|
|
42
|
+
'fk-icon-badge',
|
|
43
|
+
this.isCustomBadgeSize()
|
|
44
|
+
? ''
|
|
45
|
+
: `fk-icon-badge--${this.effectiveBadgeSize()}`,
|
|
46
|
+
`fk-icon-badge--${this.shape()}`,
|
|
47
|
+
this.className(),
|
|
48
|
+
]
|
|
49
|
+
.filter(Boolean)
|
|
50
|
+
.join(' ');
|
|
51
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
52
|
+
get hostClass() {
|
|
53
|
+
return this.classes();
|
|
54
|
+
}
|
|
55
|
+
get hostRole() {
|
|
56
|
+
return this.ariaLabel() ? 'img' : null;
|
|
57
|
+
}
|
|
58
|
+
get hostAriaLabel() {
|
|
59
|
+
return this.ariaLabel();
|
|
60
|
+
}
|
|
61
|
+
get hostAriaHidden() {
|
|
62
|
+
return this.effectiveAriaHidden() ? 'true' : null;
|
|
63
|
+
}
|
|
64
|
+
get hostId() {
|
|
65
|
+
return this.id();
|
|
66
|
+
}
|
|
67
|
+
get hostPadding() {
|
|
68
|
+
return this.isCustomBadgeSize() ? this.effectiveBadgeSize() : null;
|
|
69
|
+
}
|
|
70
|
+
get hostBorderColor() {
|
|
71
|
+
return this.borderColor();
|
|
72
|
+
}
|
|
73
|
+
get hostBackgroundColor() {
|
|
74
|
+
return this.backgroundColor();
|
|
75
|
+
}
|
|
76
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
77
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: IconBadgeComponent, isStandalone: true, selector: "fk-icon-badge", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, badgeSize: { classPropertyName: "badgeSize", publicName: "badgeSize", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, borderColor: { classPropertyName: "borderColor", publicName: "borderColor", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaHidden: { classPropertyName: "ariaHidden", publicName: "ariaHidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "attr.role": "this.hostRole", "attr.aria-label": "this.hostAriaLabel", "attr.aria-hidden": "this.hostAriaHidden", "attr.id": "this.hostId", "style.padding": "this.hostPadding", "style.border-color": "this.hostBorderColor", "style.background-color": "this.hostBackgroundColor" } }, ngImport: i0, template: "<fk-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [ariaHidden]=\"true\"\n></fk-icon>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;border-style:solid;border-width:var(--fk-icon-badge-border-width, 1px);border-color:transparent;background-color:transparent;vertical-align:middle;line-height:1}:host.fk-icon-badge--xs{padding:var(--fk-icon-badge-padding-xs, .25rem)}:host.fk-icon-badge--sm{padding:var(--fk-icon-badge-padding-sm, .375rem)}:host.fk-icon-badge--md{padding:var(--fk-icon-badge-padding-md, .5rem)}:host.fk-icon-badge--lg{padding:var(--fk-icon-badge-padding-lg, .625rem)}:host.fk-icon-badge--xl{padding:var(--fk-icon-badge-padding-xl, .75rem)}:host.fk-icon-badge--circle{border-radius:50%}:host.fk-icon-badge--rounded{border-radius:var(--fk-icon-badge-border-radius, .375rem)}:host.fk-icon-badge--square{border-radius:0}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "fk-icon", inputs: ["name", "size", "color", "className", "id", "ariaLabel", "ariaHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
78
|
+
}
|
|
79
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconBadgeComponent, decorators: [{
|
|
80
|
+
type: Component,
|
|
81
|
+
args: [{ selector: 'fk-icon-badge', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<fk-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [ariaHidden]=\"true\"\n></fk-icon>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;border-style:solid;border-width:var(--fk-icon-badge-border-width, 1px);border-color:transparent;background-color:transparent;vertical-align:middle;line-height:1}:host.fk-icon-badge--xs{padding:var(--fk-icon-badge-padding-xs, .25rem)}:host.fk-icon-badge--sm{padding:var(--fk-icon-badge-padding-sm, .375rem)}:host.fk-icon-badge--md{padding:var(--fk-icon-badge-padding-md, .5rem)}:host.fk-icon-badge--lg{padding:var(--fk-icon-badge-padding-lg, .625rem)}:host.fk-icon-badge--xl{padding:var(--fk-icon-badge-padding-xl, .75rem)}:host.fk-icon-badge--circle{border-radius:50%}:host.fk-icon-badge--rounded{border-radius:var(--fk-icon-badge-border-radius, .375rem)}:host.fk-icon-badge--square{border-radius:0}\n"] }]
|
|
82
|
+
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], badgeSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeSize", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], borderColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderColor", required: false }] }], backgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundColor", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaHidden", required: false }] }], hostClass: [{
|
|
83
|
+
type: HostBinding,
|
|
84
|
+
args: ['class']
|
|
85
|
+
}], hostRole: [{
|
|
86
|
+
type: HostBinding,
|
|
87
|
+
args: ['attr.role']
|
|
88
|
+
}], hostAriaLabel: [{
|
|
89
|
+
type: HostBinding,
|
|
90
|
+
args: ['attr.aria-label']
|
|
91
|
+
}], hostAriaHidden: [{
|
|
92
|
+
type: HostBinding,
|
|
93
|
+
args: ['attr.aria-hidden']
|
|
94
|
+
}], hostId: [{
|
|
95
|
+
type: HostBinding,
|
|
96
|
+
args: ['attr.id']
|
|
97
|
+
}], hostPadding: [{
|
|
98
|
+
type: HostBinding,
|
|
99
|
+
args: ['style.padding']
|
|
100
|
+
}], hostBorderColor: [{
|
|
101
|
+
type: HostBinding,
|
|
102
|
+
args: ['style.border-color']
|
|
103
|
+
}], hostBackgroundColor: [{
|
|
104
|
+
type: HostBinding,
|
|
105
|
+
args: ['style.background-color']
|
|
106
|
+
}] } });
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generated bundle index. Do not edit.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
export { IconBadgeComponent };
|
|
113
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-icon-badge.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-icon-badge.mjs","sources":["../../../../packages/ui-ng/ui/icon-badge/icon-badge.component.ts","../../../../packages/ui-ng/ui/icon-badge/icon-badge.component.html","../../../../packages/ui-ng/ui/icon-badge/frame-kit-ui-ng-ui-icon-badge.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport { IconComponent } from '@frame-kit/ui-ng/core/icon';\nimport type { IconColor, IconSize } from '@frame-kit/ui-ng/core/icon';\nimport type { IconBadgeShape, IconBadgeSize } from './icon-badge.types';\n\n@Component({\n selector: 'fk-icon-badge',\n standalone: true,\n imports: [IconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './icon-badge.component.html',\n styleUrl: './icon-badge.component.scss',\n})\nexport class IconBadgeComponent {\n // ===== INPUTS =====\n /** Name of the icon rendered inside the badge container. */\n readonly name = input.required<string>();\n /** Size of the icon within the badge. */\n readonly size = input<IconSize>('md');\n /** Size of the badge container; defaults to matching `size` when null. */\n readonly badgeSize = input<IconBadgeSize | null>(null);\n /** Shape of the badge container — circle or square. */\n readonly shape = input<IconBadgeShape>('circle');\n /** Color of the icon. */\n readonly color = input<IconColor>('inherit');\n /** Custom border color applied directly to the host element. */\n readonly borderColor = input<string | null>(null);\n /** Custom background color applied directly to the host element. */\n readonly backgroundColor = input<string | null>(null);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n /** Explicit aria-hidden override; when null it defaults to true unless `ariaLabel` is set. */\n readonly ariaHidden = input<boolean | null>(null);\n\n // ===== COMPUTED =====\n\n private readonly badgeSizePresets = ['xs', 'sm', 'md', 'lg', 'xl'];\n\n readonly effectiveBadgeSize = computed(() => {\n return this.badgeSize() ?? this.size();\n });\n\n readonly isCustomBadgeSize = computed(\n () => !this.badgeSizePresets.includes(this.effectiveBadgeSize()),\n );\n\n readonly effectiveAriaHidden = computed(() => {\n const explicit = this.ariaHidden();\n\n if (explicit !== null) {\n return explicit;\n }\n\n return this.ariaLabel() === null;\n });\n\n readonly classes = computed(() => {\n return [\n 'fk-icon-badge',\n this.isCustomBadgeSize()\n ? ''\n : `fk-icon-badge--${this.effectiveBadgeSize()}`,\n `fk-icon-badge--${this.shape()}`,\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.role')\n get hostRole(): string | null {\n return this.ariaLabel() ? 'img' : null;\n }\n\n @HostBinding('attr.aria-label')\n get hostAriaLabel(): string | null {\n return this.ariaLabel();\n }\n\n @HostBinding('attr.aria-hidden')\n get hostAriaHidden(): string | null {\n return this.effectiveAriaHidden() ? 'true' : null;\n }\n\n @HostBinding('attr.id')\n get hostId(): string | null {\n return this.id();\n }\n\n @HostBinding('style.padding')\n get hostPadding(): string | null {\n return this.isCustomBadgeSize() ? this.effectiveBadgeSize() : null;\n }\n\n @HostBinding('style.border-color')\n get hostBorderColor(): string | null {\n return this.borderColor();\n }\n\n @HostBinding('style.background-color')\n get hostBackgroundColor(): string | null {\n return this.backgroundColor();\n }\n}\n","<fk-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [ariaHidden]=\"true\"\n></fk-icon>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, input, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { IconComponent } from '@frame-kit/ui-ng/core/icon';
|
|
4
|
+
|
|
5
|
+
const ICON_LIST_PARENT = new InjectionToken('ICON_LIST_PARENT');
|
|
6
|
+
|
|
7
|
+
class IconListItemComponent {
|
|
8
|
+
// When rendered inside an `fk-icon-list`, we look up the parent via its
|
|
9
|
+
// `ICON_LIST_PARENT` token and treat its inputs as defaults for items that
|
|
10
|
+
// don't override them. Outside a list, the item stands alone with its own
|
|
11
|
+
// defaults. The token indirection is what breaks the circular ES-module
|
|
12
|
+
// import that a direct `IconListComponent` type reference would create.
|
|
13
|
+
parent = inject(ICON_LIST_PARENT, { optional: true });
|
|
14
|
+
// ===== INPUTS =====
|
|
15
|
+
/** Icon name for this item; falls back to the parent list's `icon` when null. */
|
|
16
|
+
icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
17
|
+
/** Color variant for this item's icon; falls back to the parent list's `variant` when null. */
|
|
18
|
+
variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
19
|
+
/** Size for this item; falls back to the parent list's `size` when null. */
|
|
20
|
+
size = input(null, ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
21
|
+
// ===== BASE PROPS =====
|
|
22
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
23
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
24
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
25
|
+
// ===== COMPUTED =====
|
|
26
|
+
resolvedIcon = computed(() => this.icon() ?? this.parent?.icon() ?? null, ...(ngDevMode ? [{ debugName: "resolvedIcon" }] : /* istanbul ignore next */ []));
|
|
27
|
+
resolvedVariant = computed(() => this.variant() ?? this.parent?.variant() ?? 'default', ...(ngDevMode ? [{ debugName: "resolvedVariant" }] : /* istanbul ignore next */ []));
|
|
28
|
+
resolvedSize = computed(() => this.size() ?? this.parent?.size() ?? 'md', ...(ngDevMode ? [{ debugName: "resolvedSize" }] : /* istanbul ignore next */ []));
|
|
29
|
+
classes = computed(() => {
|
|
30
|
+
return [
|
|
31
|
+
'fk-icon-list-item',
|
|
32
|
+
`fk-icon-list-item--${this.resolvedVariant()}`,
|
|
33
|
+
`fk-icon-list-item--${this.resolvedSize()}`,
|
|
34
|
+
this.className(),
|
|
35
|
+
]
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.join(' ');
|
|
38
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
39
|
+
get hostClass() {
|
|
40
|
+
return this.classes();
|
|
41
|
+
}
|
|
42
|
+
// Only carry `role="listitem"` when we're actually inside a list container.
|
|
43
|
+
// Outside a list the item is presentational and should not advertise list
|
|
44
|
+
// semantics — screen readers would otherwise announce an orphan listitem.
|
|
45
|
+
get hostRole() {
|
|
46
|
+
return this.parent ? 'listitem' : null;
|
|
47
|
+
}
|
|
48
|
+
get hostId() {
|
|
49
|
+
return this.id();
|
|
50
|
+
}
|
|
51
|
+
get hostAriaLabel() {
|
|
52
|
+
return this.ariaLabel();
|
|
53
|
+
}
|
|
54
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
55
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: IconListItemComponent, isStandalone: true, selector: "fk-icon-list-item", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "attr.role": "this.hostRole", "attr.id": "this.hostId", "attr.aria-label": "this.hostAriaLabel" } }, ngImport: i0, template: "@if (resolvedIcon(); as iconName) {\n <fk-icon\n class=\"fk-icon-list-item__icon\"\n [name]=\"iconName\"\n [size]=\"resolvedSize()\"\n />\n}\n\n<span class=\"fk-icon-list-item__label\">\n <ng-content />\n</span>\n", styles: [":host{display:flex;align-items:center;gap:var(--fk-icon-list-item-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-icon-list-item-label-color, var(--fk-color-text, #1f2d3d));line-height:var(--fk-icon-list-item-line-height, var(--fk-typography-body-line-height, 1.5))}.fk-icon-list-item__icon{flex-shrink:0}.fk-icon-list-item__label{min-width:0}:host.fk-icon-list-item--sm{font-size:var(--fk-icon-list-item-sm-font-size, var(--fk-typography-small-font-size, .8125rem))}:host.fk-icon-list-item--md{font-size:var(--fk-icon-list-item-md-font-size, var(--fk-typography-body-font-size, .9375rem))}:host.fk-icon-list-item--lg{font-size:var(--fk-icon-list-item-lg-font-size, var(--fk-typography-lead-font-size, 1rem))}:host.fk-icon-list-item--default .fk-icon-list-item__icon{color:var(--fk-icon-list-item-default-color, var(--fk-color-muted, #8a98a8))}:host.fk-icon-list-item--primary .fk-icon-list-item__icon{color:var(--fk-icon-list-item-primary-color, var(--fk-color-primary, #0a84ff))}:host.fk-icon-list-item--success .fk-icon-list-item__icon{color:var(--fk-icon-list-item-success-color, var(--fk-color-success, #10b981))}:host.fk-icon-list-item--warning .fk-icon-list-item__icon{color:var(--fk-icon-list-item-warning-color, var(--fk-color-warning, #f59e0b))}:host.fk-icon-list-item--danger .fk-icon-list-item__icon{color:var(--fk-icon-list-item-danger-color, var(--fk-color-danger, #e02424))}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "fk-icon", inputs: ["name", "size", "color", "className", "id", "ariaLabel", "ariaHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
56
|
+
}
|
|
57
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconListItemComponent, decorators: [{
|
|
58
|
+
type: Component,
|
|
59
|
+
args: [{ selector: 'fk-icon-list-item', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (resolvedIcon(); as iconName) {\n <fk-icon\n class=\"fk-icon-list-item__icon\"\n [name]=\"iconName\"\n [size]=\"resolvedSize()\"\n />\n}\n\n<span class=\"fk-icon-list-item__label\">\n <ng-content />\n</span>\n", styles: [":host{display:flex;align-items:center;gap:var(--fk-icon-list-item-gap, var(--fk-rhythm-2, .5rem));color:var(--fk-icon-list-item-label-color, var(--fk-color-text, #1f2d3d));line-height:var(--fk-icon-list-item-line-height, var(--fk-typography-body-line-height, 1.5))}.fk-icon-list-item__icon{flex-shrink:0}.fk-icon-list-item__label{min-width:0}:host.fk-icon-list-item--sm{font-size:var(--fk-icon-list-item-sm-font-size, var(--fk-typography-small-font-size, .8125rem))}:host.fk-icon-list-item--md{font-size:var(--fk-icon-list-item-md-font-size, var(--fk-typography-body-font-size, .9375rem))}:host.fk-icon-list-item--lg{font-size:var(--fk-icon-list-item-lg-font-size, var(--fk-typography-lead-font-size, 1rem))}:host.fk-icon-list-item--default .fk-icon-list-item__icon{color:var(--fk-icon-list-item-default-color, var(--fk-color-muted, #8a98a8))}:host.fk-icon-list-item--primary .fk-icon-list-item__icon{color:var(--fk-icon-list-item-primary-color, var(--fk-color-primary, #0a84ff))}:host.fk-icon-list-item--success .fk-icon-list-item__icon{color:var(--fk-icon-list-item-success-color, var(--fk-color-success, #10b981))}:host.fk-icon-list-item--warning .fk-icon-list-item__icon{color:var(--fk-icon-list-item-warning-color, var(--fk-color-warning, #f59e0b))}:host.fk-icon-list-item--danger .fk-icon-list-item__icon{color:var(--fk-icon-list-item-danger-color, var(--fk-color-danger, #e02424))}\n"] }]
|
|
60
|
+
}], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hostClass: [{
|
|
61
|
+
type: HostBinding,
|
|
62
|
+
args: ['class']
|
|
63
|
+
}], hostRole: [{
|
|
64
|
+
type: HostBinding,
|
|
65
|
+
args: ['attr.role']
|
|
66
|
+
}], hostId: [{
|
|
67
|
+
type: HostBinding,
|
|
68
|
+
args: ['attr.id']
|
|
69
|
+
}], hostAriaLabel: [{
|
|
70
|
+
type: HostBinding,
|
|
71
|
+
args: ['attr.aria-label']
|
|
72
|
+
}] } });
|
|
73
|
+
|
|
74
|
+
class IconListComponent {
|
|
75
|
+
// ===== INPUTS =====
|
|
76
|
+
/** Optional array of items to render declaratively; when null, projected `fk-icon-list-item` elements are used. */
|
|
77
|
+
items = input(null, ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
78
|
+
/** Default icon name inherited by all child items that don't specify their own. */
|
|
79
|
+
icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/** Color variant applied to the icon in each list item. */
|
|
81
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
82
|
+
/** Size applied to the icon and text in each list item. */
|
|
83
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
84
|
+
// ===== BASE PROPS =====
|
|
85
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
86
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
87
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
88
|
+
// ===== COMPUTED =====
|
|
89
|
+
classes = computed(() => {
|
|
90
|
+
return ['fk-icon-list', this.className()].filter(Boolean).join(' ');
|
|
91
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
92
|
+
get hostClass() {
|
|
93
|
+
return this.classes();
|
|
94
|
+
}
|
|
95
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
96
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: IconListComponent, isStandalone: true, selector: "fk-icon-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass" } }, providers: [{ provide: ICON_LIST_PARENT, useExisting: IconListComponent }], ngImport: i0, template: "<div\n class=\"fk-icon-list__list\"\n role=\"list\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @if (items(); as rows) {\n @for (row of rows; track $index) {\n <fk-icon-list-item [icon]=\"row.icon ?? null\">\n {{ row.label }}\n </fk-icon-list-item>\n }\n } @else {\n <ng-content />\n }\n</div>\n", styles: [":host{display:block;margin-top:var(--fk-icon-list-margin-top, var(--fk-rhythm-4, 1rem))}.fk-icon-list__list{display:flex;flex-direction:column;gap:var(--fk-icon-list-row-gap, var(--fk-rhythm-2, .5rem))}\n"], dependencies: [{ kind: "component", type: IconListItemComponent, selector: "fk-icon-list-item", inputs: ["icon", "variant", "size", "className", "id", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
97
|
+
}
|
|
98
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: IconListComponent, decorators: [{
|
|
99
|
+
type: Component,
|
|
100
|
+
args: [{ selector: 'fk-icon-list', standalone: true, imports: [IconListItemComponent], providers: [{ provide: ICON_LIST_PARENT, useExisting: IconListComponent }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"fk-icon-list__list\"\n role=\"list\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @if (items(); as rows) {\n @for (row of rows; track $index) {\n <fk-icon-list-item [icon]=\"row.icon ?? null\">\n {{ row.label }}\n </fk-icon-list-item>\n }\n } @else {\n <ng-content />\n }\n</div>\n", styles: [":host{display:block;margin-top:var(--fk-icon-list-margin-top, var(--fk-rhythm-4, 1rem))}.fk-icon-list__list{display:flex;flex-direction:column;gap:var(--fk-icon-list-row-gap, var(--fk-rhythm-2, .5rem))}\n"] }]
|
|
101
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hostClass: [{
|
|
102
|
+
type: HostBinding,
|
|
103
|
+
args: ['class']
|
|
104
|
+
}] } });
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Generated bundle index. Do not edit.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
export { IconListComponent, IconListItemComponent };
|
|
111
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-icon-list.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-icon-list.mjs","sources":["../../../../packages/ui-ng/ui/icon-list/icon-list.token.ts","../../../../packages/ui-ng/ui/icon-list/icon-list-item.component.ts","../../../../packages/ui-ng/ui/icon-list/icon-list-item.component.html","../../../../packages/ui-ng/ui/icon-list/icon-list.component.ts","../../../../packages/ui-ng/ui/icon-list/icon-list.component.html","../../../../packages/ui-ng/ui/icon-list/frame-kit-ui-ng-ui-icon-list.ts"],"sourcesContent":["import { InjectionToken, type Signal } from '@angular/core';\n\nimport type { IconListSize, IconListVariant } from './icon-list.types';\n\n/**\n * Parent contract exposed by `fk-icon-list` to `fk-icon-list-item` children.\n * Lives in its own file so the two components can reference it without the\n * circular ES-module import that a direct `IconListComponent` type import\n * would create (item -> list -> item).\n */\nexport interface IconListParent {\n readonly icon: Signal<string | null>;\n readonly variant: Signal<IconListVariant>;\n readonly size: Signal<IconListSize>;\n}\n\nexport const ICON_LIST_PARENT = new InjectionToken<IconListParent>(\n 'ICON_LIST_PARENT',\n);\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n inject,\n input,\n} from '@angular/core';\n\nimport { IconComponent } from '@frame-kit/ui-ng/core/icon';\nimport { ICON_LIST_PARENT } from './icon-list.token';\nimport type { IconListSize, IconListVariant } from './icon-list.types';\n\n@Component({\n selector: 'fk-icon-list-item',\n standalone: true,\n imports: [IconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './icon-list-item.component.html',\n styleUrl: './icon-list-item.component.scss',\n})\nexport class IconListItemComponent {\n // When rendered inside an `fk-icon-list`, we look up the parent via its\n // `ICON_LIST_PARENT` token and treat its inputs as defaults for items that\n // don't override them. Outside a list, the item stands alone with its own\n // defaults. The token indirection is what breaks the circular ES-module\n // import that a direct `IconListComponent` type reference would create.\n private readonly parent = inject(ICON_LIST_PARENT, { optional: true });\n\n // ===== INPUTS =====\n /** Icon name for this item; falls back to the parent list's `icon` when null. */\n readonly icon = input<string | null>(null);\n /** Color variant for this item's icon; falls back to the parent list's `variant` when null. */\n readonly variant = input<IconListVariant | null>(null);\n /** Size for this item; falls back to the parent list's `size` when null. */\n readonly size = input<IconListSize | null>(null);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== COMPUTED =====\n protected readonly resolvedIcon = computed<string | null>(\n () => this.icon() ?? this.parent?.icon() ?? null,\n );\n\n protected readonly resolvedVariant = computed<IconListVariant>(\n () => this.variant() ?? this.parent?.variant() ?? 'default',\n );\n\n protected readonly resolvedSize = computed<IconListSize>(\n () => this.size() ?? this.parent?.size() ?? 'md',\n );\n\n readonly classes = computed(() => {\n return [\n 'fk-icon-list-item',\n `fk-icon-list-item--${this.resolvedVariant()}`,\n `fk-icon-list-item--${this.resolvedSize()}`,\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n // Only carry `role=\"listitem\"` when we're actually inside a list container.\n // Outside a list the item is presentational and should not advertise list\n // semantics — screen readers would otherwise announce an orphan listitem.\n @HostBinding('attr.role')\n get hostRole(): string | null {\n return this.parent ? 'listitem' : null;\n }\n\n @HostBinding('attr.id')\n get hostId(): string | null {\n return this.id();\n }\n\n @HostBinding('attr.aria-label')\n get hostAriaLabel(): string | null {\n return this.ariaLabel();\n }\n}\n","@if (resolvedIcon(); as iconName) {\n <fk-icon\n class=\"fk-icon-list-item__icon\"\n [name]=\"iconName\"\n [size]=\"resolvedSize()\"\n />\n}\n\n<span class=\"fk-icon-list-item__label\">\n <ng-content />\n</span>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport { ICON_LIST_PARENT, type IconListParent } from './icon-list.token';\nimport type {\n IconListItem,\n IconListSize,\n IconListVariant,\n} from './icon-list.types';\nimport { IconListItemComponent } from './icon-list-item.component';\n\n@Component({\n selector: 'fk-icon-list',\n standalone: true,\n imports: [IconListItemComponent],\n providers: [{ provide: ICON_LIST_PARENT, useExisting: IconListComponent }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './icon-list.component.html',\n styleUrl: './icon-list.component.scss',\n})\nexport class IconListComponent implements IconListParent {\n // ===== INPUTS =====\n /** Optional array of items to render declaratively; when null, projected `fk-icon-list-item` elements are used. */\n readonly items = input<readonly IconListItem[] | null>(null);\n /** Default icon name inherited by all child items that don't specify their own. */\n readonly icon = input<string | null>(null);\n /** Color variant applied to the icon in each list item. */\n readonly variant = input<IconListVariant>('default');\n /** Size applied to the icon and text in each list item. */\n readonly size = input<IconListSize>('md');\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-icon-list', this.className()].filter(Boolean).join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n}\n","<div\n class=\"fk-icon-list__list\"\n role=\"list\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n @if (items(); as rows) {\n @for (row of rows; track $index) {\n <fk-icon-list-item [icon]=\"row.icon ?? null\">\n {{ row.label }}\n </fk-icon-list-item>\n }\n } @else {\n <ng-content />\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, signal, viewChild, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
class InlineEditComponent {
|
|
5
|
+
// ===== BASE PROPS =====
|
|
6
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
7
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
8
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
9
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
10
|
+
// ===== INPUTS =====
|
|
11
|
+
/** Current committed value displayed in read mode. */
|
|
12
|
+
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
13
|
+
/** Placeholder text shown in the input when the edit value is empty. */
|
|
14
|
+
placeholder = input('Enter a value…', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
15
|
+
/** Size variant controlling the font and spacing of the component. */
|
|
16
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
17
|
+
/** Text displayed in read mode when the committed value is empty. */
|
|
18
|
+
emptyText = input('None', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
19
|
+
// ===== OUTPUTS =====
|
|
20
|
+
/** Fires when the user saves an edit, emitting the trimmed new value. */
|
|
21
|
+
valueChange = output();
|
|
22
|
+
/** Fires when the component enters edit mode. */
|
|
23
|
+
editStart = output();
|
|
24
|
+
/** Fires when the user cancels an in-progress edit without saving. */
|
|
25
|
+
editCancel = output();
|
|
26
|
+
// ===== STATE =====
|
|
27
|
+
editing = signal(false, ...(ngDevMode ? [{ debugName: "editing" }] : /* istanbul ignore next */ []));
|
|
28
|
+
editValue = signal('', ...(ngDevMode ? [{ debugName: "editValue" }] : /* istanbul ignore next */ []));
|
|
29
|
+
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
|
|
30
|
+
// ===== CLASSES =====
|
|
31
|
+
classes = computed(() => [
|
|
32
|
+
'fk-inline-edit',
|
|
33
|
+
`fk-inline-edit--${this.size()}`,
|
|
34
|
+
this.editing() ? 'fk-inline-edit--editing' : '',
|
|
35
|
+
this.disabled() ? 'fk-inline-edit--disabled' : '',
|
|
36
|
+
this.className(),
|
|
37
|
+
]
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
40
|
+
get hostClass() {
|
|
41
|
+
return this.classes();
|
|
42
|
+
}
|
|
43
|
+
get hostId() {
|
|
44
|
+
return this.id();
|
|
45
|
+
}
|
|
46
|
+
// ===== METHODS =====
|
|
47
|
+
/** Enters edit mode and focuses the input, copying the current value into the edit buffer. */
|
|
48
|
+
startEdit() {
|
|
49
|
+
if (this.disabled()) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.editValue.set(this.value());
|
|
53
|
+
this.editing.set(true);
|
|
54
|
+
this.editStart.emit();
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
this.inputRef()?.nativeElement.focus();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Commits the current edit buffer, exits edit mode, and emits the trimmed value. */
|
|
60
|
+
save() {
|
|
61
|
+
const trimmed = this.editValue().trim();
|
|
62
|
+
this.editing.set(false);
|
|
63
|
+
this.valueChange.emit(trimmed);
|
|
64
|
+
}
|
|
65
|
+
/** Discards the current edit buffer and exits edit mode. */
|
|
66
|
+
cancel() {
|
|
67
|
+
this.editing.set(false);
|
|
68
|
+
this.editCancel.emit();
|
|
69
|
+
}
|
|
70
|
+
onKeydown(event) {
|
|
71
|
+
if (event.key === 'Enter') {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
this.save();
|
|
74
|
+
}
|
|
75
|
+
if (event.key === 'Escape') {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
this.cancel();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
onInput(event) {
|
|
81
|
+
const target = event.target;
|
|
82
|
+
this.editValue.set(target.value);
|
|
83
|
+
}
|
|
84
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: InlineEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
85
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: InlineEditComponent, isStandalone: true, selector: "fk-inline-edit", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", editStart: "editStart", editCancel: "editCancel" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (editing()) {\n <div class=\"fk-inline-edit__editor\">\n <input\n #inputEl\n class=\"fk-inline-edit__input\"\n type=\"text\"\n [value]=\"editValue()\"\n [placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--save\"\n type=\"button\"\n aria-label=\"Save\"\n (click)=\"save()\"\n >\n <ng-content select=\"[saveIcon]\">\n <span class=\"fk-inline-edit__action-text\">Save</span>\n </ng-content>\n </button>\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--cancel\"\n type=\"button\"\n aria-label=\"Cancel\"\n (click)=\"cancel()\"\n >\n <ng-content select=\"[cancelIcon]\">\n <span class=\"fk-inline-edit__action-text\">Cancel</span>\n </ng-content>\n </button>\n </div>\n} @else {\n <div class=\"fk-inline-edit__display\">\n <span class=\"fk-inline-edit__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <span class=\"fk-inline-edit__empty\">{{ emptyText() }}</span>\n }\n </span>\n\n @if (!disabled()) {\n <button\n class=\"fk-inline-edit__trigger\"\n type=\"button\"\n [attr.aria-label]=\"ariaLabel() ? 'Edit ' + ariaLabel() : 'Edit'\"\n (click)=\"startEdit()\"\n >\n <ng-content select=\"[editIcon]\">\n <span class=\"fk-inline-edit__trigger-text\">Edit</span>\n </ng-content>\n </button>\n }\n </div>\n}\n", styles: [":host{display:block}.fk-inline-edit__editor{display:flex;align-items:center;gap:var(--fk-inline-edit-gap, var(--fk-rhythm-2, .5rem))}.fk-inline-edit__input{flex:1;min-width:0;padding:var(--fk-inline-edit-input-padding, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem));font-family:inherit;font-size:var(--fk-inline-edit-font-size, var(--fk-typography-body-font-size, .875rem));font-weight:var(--fk-inline-edit-font-weight, var(--fk-font-weight-normal, 400));color:var(--fk-inline-edit-color, var(--fk-color-text, #1f2d3d));background:var(--fk-inline-edit-input-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-inline-edit-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-inline-edit-border-radius, var(--fk-radius-md, .375rem));outline:none}.fk-inline-edit__input:focus{border-color:var(--fk-inline-edit-focus-border, var(--fk-color-primary, #3b82f6));box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 2px rgba(59, 130, 246, .15)))}.fk-inline-edit__display{display:flex;align-items:center;gap:var(--fk-inline-edit-gap, var(--fk-rhythm-2, .5rem))}.fk-inline-edit__value{font-size:var(--fk-inline-edit-font-size, var(--fk-typography-body-font-size, .875rem));font-weight:var(--fk-inline-edit-font-weight, var(--fk-font-weight-normal, 400));color:var(--fk-inline-edit-color, var(--fk-color-text, #1f2d3d))}.fk-inline-edit__empty{color:var(--fk-inline-edit-empty-color, var(--fk-color-muted, #8a98a8))}.fk-inline-edit__trigger{display:inline-flex;align-items:center;flex-shrink:0;padding:0;background:none;border:none;color:var(--fk-inline-edit-trigger-color, var(--fk-color-muted, #8a98a8));cursor:pointer}.fk-inline-edit__trigger:hover{color:var(--fk-inline-edit-trigger-hover-color, var(--fk-color-primary, #3b82f6))}.fk-inline-edit__trigger:focus-visible{outline:none;box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)));border-radius:var(--fk-radius-sm, .25rem)}.fk-inline-edit__trigger-text,.fk-inline-edit__action-text{font-size:var(--fk-inline-edit-action-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-font-weight-medium, 500)}.fk-inline-edit__action{display:inline-flex;align-items:center;flex-shrink:0;padding:var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem);font-family:inherit;font-size:var(--fk-inline-edit-action-font-size, var(--fk-typography-small-font-size, .8125rem));border:1px solid var(--fk-color-border, #d9e2ee);border-radius:var(--fk-radius-md, .375rem);cursor:pointer}.fk-inline-edit__action--save{background:var(--fk-inline-edit-save-bg, var(--fk-color-primary, #3b82f6));border-color:var(--fk-inline-edit-save-bg, var(--fk-color-primary, #3b82f6));color:var(--fk-inline-edit-save-color, #ffffff)}.fk-inline-edit__action--save:hover{opacity:.9}.fk-inline-edit__action--cancel{background:var(--fk-inline-edit-cancel-bg, var(--fk-color-surface, #ffffff));color:var(--fk-inline-edit-cancel-color, var(--fk-color-text, #1f2d3d))}.fk-inline-edit__action--cancel:hover{background:var(--fk-color-surface-hover, #f5f7fa)}.fk-inline-edit__action:focus-visible{outline:none;box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}:host-context(.fk-inline-edit--sm) .fk-inline-edit__input{font-size:var(--fk-typography-small-font-size, .8125rem)}:host-context(.fk-inline-edit--sm) .fk-inline-edit__value{font-size:var(--fk-typography-small-font-size, .8125rem)}:host-context(.fk-inline-edit--lg) .fk-inline-edit__input{font-size:var(--fk-inline-edit-lg-font-size, var(--fk-typography-heading-font-size, 1.25rem));font-weight:var(--fk-inline-edit-lg-font-weight, var(--fk-font-weight-semibold, 600))}:host-context(.fk-inline-edit--lg) .fk-inline-edit__value{font-size:var(--fk-inline-edit-lg-font-size, var(--fk-typography-heading-font-size, 1.25rem));font-weight:var(--fk-inline-edit-lg-font-weight, var(--fk-font-weight-semibold, 600))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
86
|
+
}
|
|
87
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: InlineEditComponent, decorators: [{
|
|
88
|
+
type: Component,
|
|
89
|
+
args: [{ selector: 'fk-inline-edit', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (editing()) {\n <div class=\"fk-inline-edit__editor\">\n <input\n #inputEl\n class=\"fk-inline-edit__input\"\n type=\"text\"\n [value]=\"editValue()\"\n [placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--save\"\n type=\"button\"\n aria-label=\"Save\"\n (click)=\"save()\"\n >\n <ng-content select=\"[saveIcon]\">\n <span class=\"fk-inline-edit__action-text\">Save</span>\n </ng-content>\n </button>\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--cancel\"\n type=\"button\"\n aria-label=\"Cancel\"\n (click)=\"cancel()\"\n >\n <ng-content select=\"[cancelIcon]\">\n <span class=\"fk-inline-edit__action-text\">Cancel</span>\n </ng-content>\n </button>\n </div>\n} @else {\n <div class=\"fk-inline-edit__display\">\n <span class=\"fk-inline-edit__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <span class=\"fk-inline-edit__empty\">{{ emptyText() }}</span>\n }\n </span>\n\n @if (!disabled()) {\n <button\n class=\"fk-inline-edit__trigger\"\n type=\"button\"\n [attr.aria-label]=\"ariaLabel() ? 'Edit ' + ariaLabel() : 'Edit'\"\n (click)=\"startEdit()\"\n >\n <ng-content select=\"[editIcon]\">\n <span class=\"fk-inline-edit__trigger-text\">Edit</span>\n </ng-content>\n </button>\n }\n </div>\n}\n", styles: [":host{display:block}.fk-inline-edit__editor{display:flex;align-items:center;gap:var(--fk-inline-edit-gap, var(--fk-rhythm-2, .5rem))}.fk-inline-edit__input{flex:1;min-width:0;padding:var(--fk-inline-edit-input-padding, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem));font-family:inherit;font-size:var(--fk-inline-edit-font-size, var(--fk-typography-body-font-size, .875rem));font-weight:var(--fk-inline-edit-font-weight, var(--fk-font-weight-normal, 400));color:var(--fk-inline-edit-color, var(--fk-color-text, #1f2d3d));background:var(--fk-inline-edit-input-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-inline-edit-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-inline-edit-border-radius, var(--fk-radius-md, .375rem));outline:none}.fk-inline-edit__input:focus{border-color:var(--fk-inline-edit-focus-border, var(--fk-color-primary, #3b82f6));box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 2px rgba(59, 130, 246, .15)))}.fk-inline-edit__display{display:flex;align-items:center;gap:var(--fk-inline-edit-gap, var(--fk-rhythm-2, .5rem))}.fk-inline-edit__value{font-size:var(--fk-inline-edit-font-size, var(--fk-typography-body-font-size, .875rem));font-weight:var(--fk-inline-edit-font-weight, var(--fk-font-weight-normal, 400));color:var(--fk-inline-edit-color, var(--fk-color-text, #1f2d3d))}.fk-inline-edit__empty{color:var(--fk-inline-edit-empty-color, var(--fk-color-muted, #8a98a8))}.fk-inline-edit__trigger{display:inline-flex;align-items:center;flex-shrink:0;padding:0;background:none;border:none;color:var(--fk-inline-edit-trigger-color, var(--fk-color-muted, #8a98a8));cursor:pointer}.fk-inline-edit__trigger:hover{color:var(--fk-inline-edit-trigger-hover-color, var(--fk-color-primary, #3b82f6))}.fk-inline-edit__trigger:focus-visible{outline:none;box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)));border-radius:var(--fk-radius-sm, .25rem)}.fk-inline-edit__trigger-text,.fk-inline-edit__action-text{font-size:var(--fk-inline-edit-action-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-font-weight-medium, 500)}.fk-inline-edit__action{display:inline-flex;align-items:center;flex-shrink:0;padding:var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem);font-family:inherit;font-size:var(--fk-inline-edit-action-font-size, var(--fk-typography-small-font-size, .8125rem));border:1px solid var(--fk-color-border, #d9e2ee);border-radius:var(--fk-radius-md, .375rem);cursor:pointer}.fk-inline-edit__action--save{background:var(--fk-inline-edit-save-bg, var(--fk-color-primary, #3b82f6));border-color:var(--fk-inline-edit-save-bg, var(--fk-color-primary, #3b82f6));color:var(--fk-inline-edit-save-color, #ffffff)}.fk-inline-edit__action--save:hover{opacity:.9}.fk-inline-edit__action--cancel{background:var(--fk-inline-edit-cancel-bg, var(--fk-color-surface, #ffffff));color:var(--fk-inline-edit-cancel-color, var(--fk-color-text, #1f2d3d))}.fk-inline-edit__action--cancel:hover{background:var(--fk-color-surface-hover, #f5f7fa)}.fk-inline-edit__action:focus-visible{outline:none;box-shadow:var(--fk-inline-edit-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}:host-context(.fk-inline-edit--sm) .fk-inline-edit__input{font-size:var(--fk-typography-small-font-size, .8125rem)}:host-context(.fk-inline-edit--sm) .fk-inline-edit__value{font-size:var(--fk-typography-small-font-size, .8125rem)}:host-context(.fk-inline-edit--lg) .fk-inline-edit__input{font-size:var(--fk-inline-edit-lg-font-size, var(--fk-typography-heading-font-size, 1.25rem));font-weight:var(--fk-inline-edit-lg-font-weight, var(--fk-font-weight-semibold, 600))}:host-context(.fk-inline-edit--lg) .fk-inline-edit__value{font-size:var(--fk-inline-edit-lg-font-size, var(--fk-typography-heading-font-size, 1.25rem));font-weight:var(--fk-inline-edit-lg-font-weight, var(--fk-font-weight-semibold, 600))}\n"] }]
|
|
90
|
+
}], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], editStart: [{ type: i0.Output, args: ["editStart"] }], editCancel: [{ type: i0.Output, args: ["editCancel"] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], hostClass: [{
|
|
91
|
+
type: HostBinding,
|
|
92
|
+
args: ['class']
|
|
93
|
+
}], hostId: [{
|
|
94
|
+
type: HostBinding,
|
|
95
|
+
args: ['attr.id']
|
|
96
|
+
}] } });
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generated bundle index. Do not edit.
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
export { InlineEditComponent };
|
|
103
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-inline-edit.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-inline-edit.mjs","sources":["../../../../packages/ui-ng/ui/inline-edit/inline-edit.component.ts","../../../../packages/ui-ng/ui/inline-edit/inline-edit.component.html","../../../../packages/ui-ng/ui/inline-edit/frame-kit-ui-ng-ui-inline-edit.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n HostBinding,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\n\nimport type { InlineEditSize } from './inline-edit.types';\n\n@Component({\n selector: 'fk-inline-edit',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './inline-edit.component.html',\n styleUrl: './inline-edit.component.scss',\n})\nexport class InlineEditComponent {\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n readonly disabled = input(false);\n\n // ===== INPUTS =====\n /** Current committed value displayed in read mode. */\n readonly value = input<string>('');\n /** Placeholder text shown in the input when the edit value is empty. */\n readonly placeholder = input<string>('Enter a value…');\n /** Size variant controlling the font and spacing of the component. */\n readonly size = input<InlineEditSize>('md');\n /** Text displayed in read mode when the committed value is empty. */\n readonly emptyText = input<string>('None');\n\n // ===== OUTPUTS =====\n /** Fires when the user saves an edit, emitting the trimmed new value. */\n readonly valueChange = output<string>();\n /** Fires when the component enters edit mode. */\n readonly editStart = output<void>();\n /** Fires when the user cancels an in-progress edit without saving. */\n readonly editCancel = output<void>();\n\n // ===== STATE =====\n readonly editing = signal(false);\n readonly editValue = signal('');\n\n readonly inputRef = viewChild<ElementRef<HTMLInputElement>>('inputEl');\n\n // ===== CLASSES =====\n readonly classes = computed(() =>\n [\n 'fk-inline-edit',\n `fk-inline-edit--${this.size()}`,\n this.editing() ? 'fk-inline-edit--editing' : '',\n this.disabled() ? 'fk-inline-edit--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 @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n // ===== METHODS =====\n\n /** Enters edit mode and focuses the input, copying the current value into the edit buffer. */\n startEdit(): void {\n if (this.disabled()) {\n return;\n }\n\n this.editValue.set(this.value());\n this.editing.set(true);\n this.editStart.emit();\n\n setTimeout(() => {\n this.inputRef()?.nativeElement.focus();\n });\n }\n\n /** Commits the current edit buffer, exits edit mode, and emits the trimmed value. */\n save(): void {\n const trimmed = this.editValue().trim();\n\n this.editing.set(false);\n this.valueChange.emit(trimmed);\n }\n\n /** Discards the current edit buffer and exits edit mode. */\n cancel(): void {\n this.editing.set(false);\n this.editCancel.emit();\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.save();\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.cancel();\n }\n }\n\n onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n\n this.editValue.set(target.value);\n }\n}\n","@if (editing()) {\n <div class=\"fk-inline-edit__editor\">\n <input\n #inputEl\n class=\"fk-inline-edit__input\"\n type=\"text\"\n [value]=\"editValue()\"\n [placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--save\"\n type=\"button\"\n aria-label=\"Save\"\n (click)=\"save()\"\n >\n <ng-content select=\"[saveIcon]\">\n <span class=\"fk-inline-edit__action-text\">Save</span>\n </ng-content>\n </button>\n\n <button\n class=\"fk-inline-edit__action fk-inline-edit__action--cancel\"\n type=\"button\"\n aria-label=\"Cancel\"\n (click)=\"cancel()\"\n >\n <ng-content select=\"[cancelIcon]\">\n <span class=\"fk-inline-edit__action-text\">Cancel</span>\n </ng-content>\n </button>\n </div>\n} @else {\n <div class=\"fk-inline-edit__display\">\n <span class=\"fk-inline-edit__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <span class=\"fk-inline-edit__empty\">{{ emptyText() }}</span>\n }\n </span>\n\n @if (!disabled()) {\n <button\n class=\"fk-inline-edit__trigger\"\n type=\"button\"\n [attr.aria-label]=\"ariaLabel() ? 'Edit ' + ariaLabel() : 'Edit'\"\n (click)=\"startEdit()\"\n >\n <ng-content select=\"[editIcon]\">\n <span class=\"fk-inline-edit__trigger-text\">Edit</span>\n </ng-content>\n </button>\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|