@raintonic/formaui 0.2.0 → 0.2.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +7 -7
  2. package/README.md +145 -145
  3. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -1
  4. package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -1
  5. package/fesm2022/raintonic-formaui-cdk-overlay.mjs +0 -26
  6. package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -1
  7. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +2 -2
  8. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -1
  9. package/fesm2022/raintonic-formaui-components-accordion.mjs +2 -2
  10. package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
  11. package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
  12. package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
  13. package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -1
  14. package/fesm2022/raintonic-formaui-components-badge.mjs +2 -2
  15. package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -1
  16. package/fesm2022/raintonic-formaui-components-big-menu.mjs +2 -2
  17. package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -1
  18. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +4 -4
  19. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -1
  20. package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -1
  21. package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -1
  22. package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -1
  23. package/fesm2022/raintonic-formaui-components-checkbox.mjs +2 -2
  24. package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -1
  25. package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
  26. package/fesm2022/raintonic-formaui-components-date-picker.mjs +4 -4
  27. package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -1
  28. package/fesm2022/raintonic-formaui-components-divider.mjs +2 -2
  29. package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -1
  30. package/fesm2022/raintonic-formaui-components-drawer.mjs +2 -2
  31. package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -1
  32. package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +1 -1
  33. package/fesm2022/raintonic-formaui-components-empty-state.mjs +2 -2
  34. package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -1
  35. package/fesm2022/raintonic-formaui-components-file-upload.mjs +2 -2
  36. package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -1
  37. package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -1
  38. package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -1
  39. package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -1
  40. package/fesm2022/raintonic-formaui-components-list.mjs +4 -4
  41. package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -1
  42. package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -1
  43. package/fesm2022/raintonic-formaui-components-number-input.mjs +2 -2
  44. package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -1
  45. package/fesm2022/raintonic-formaui-components-paginator.mjs +2 -2
  46. package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -1
  47. package/fesm2022/raintonic-formaui-components-password-input.mjs +2 -2
  48. package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
  49. package/fesm2022/raintonic-formaui-components-popover.mjs +2 -2
  50. package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
  51. package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
  52. package/fesm2022/raintonic-formaui-components-radio.mjs +4 -4
  53. package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
  54. package/fesm2022/raintonic-formaui-components-select.mjs +24 -24
  55. package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -1
  56. package/fesm2022/raintonic-formaui-components-side-panel.mjs +2 -2
  57. package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -1
  58. package/fesm2022/raintonic-formaui-components-sidebar.mjs +2 -2
  59. package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -1
  60. package/fesm2022/raintonic-formaui-components-skeleton.mjs +2 -2
  61. package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -1
  62. package/fesm2022/raintonic-formaui-components-slider.mjs +2 -2
  63. package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -1
  64. package/fesm2022/raintonic-formaui-components-spinner.mjs +2 -2
  65. package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -1
  66. package/fesm2022/raintonic-formaui-components-stepper.mjs +2 -2
  67. package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
  68. package/fesm2022/raintonic-formaui-components-tab.mjs +10 -10
  69. package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
  70. package/fesm2022/raintonic-formaui-components-tag.mjs +2 -2
  71. package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -1
  72. package/fesm2022/raintonic-formaui-components-time-picker.mjs +4 -4
  73. package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
  74. package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -1
  75. package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -1
  76. package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -1
  77. package/fesm2022/raintonic-formaui-components-tree-select.mjs +2 -2
  78. package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -1
  79. package/fesm2022/raintonic-formaui-components-tree-table.mjs +2 -2
  80. package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -1
  81. package/fesm2022/raintonic-formaui-components-tree.mjs +4 -4
  82. package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
  83. package/fesm2022/raintonic-formaui-core.mjs.map +1 -1
  84. package/fesm2022/raintonic-formaui-services-dialog.mjs +36 -36
  85. package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -1
  86. package/fesm2022/raintonic-formaui-services-notification.mjs +2 -2
  87. package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -1
  88. package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -1
  89. package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -1
  90. package/fesm2022/raintonic-formaui.mjs.map +1 -1
  91. package/llms-full.txt +3 -97
  92. package/llms.txt +3 -3
  93. package/package.json +1 -1
  94. package/styles/index.scss +3 -3
  95. package/styles/partials/components/_button.scss +367 -0
  96. package/styles/partials/components/_dialog.scss +180 -0
  97. package/styles/partials/components/_overlay.scss +87 -0
  98. package/types/raintonic-formaui-cdk-overlay.d.ts +0 -1
  99. package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-file-upload.mjs","sources":["../../../lib/components/file-upload/file-upload.component.ts","../../../lib/components/file-upload/file-upload.component.html","../../../lib/components/file-upload/raintonic-formaui-components-file-upload.ts"],"sourcesContent":["import {\n Component,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n input,\n output,\n signal,\n viewChild,\n ElementRef,\n WritableSignal,\n booleanAttribute,\n} from '@angular/core';\n\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\nimport { FileUploadFile, FileUploadValidationError } from './file-upload.types';\n\n/**\n * # FuiFileUploadComponent\n *\n * A file upload component with drag-and-drop support, file previews, and validation.\n *\n * ## Features\n * - Drag & drop file upload\n * - Click to browse\n * - File type, size, and count validation\n * - Image preview thumbnails\n * - Accessible (keyboard, ARIA)\n *\n * ## Usage\n *\n * ### Basic\n * ```html\n * <fui-file-upload\n * accept=\"image/*,.pdf\"\n * [multiple]=\"true\"\n * [maxFileSize]=\"5242880\"\n * (filesSelected)=\"onFiles($event)\"\n * ></fui-file-upload>\n * ```\n */\n@Component({\n selector: 'fui-file-upload',\n standalone: true,\n imports: [FuiIconComponent],\n templateUrl: './file-upload.component.html',\n styleUrls: ['./file-upload.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-file-upload',\n '[class.fui-file-upload--disabled]': 'disabled()',\n '[class.fui-file-upload--drag-over]': '_isDragOver()',\n '[class.fui-file-upload--has-files]': '_files().length > 0',\n },\n})\nexport class FuiFileUploadComponent {\n // Inputs\n readonly accept = input('');\n readonly multiple = input<boolean, unknown>(false, { transform: booleanAttribute });\n readonly maxFileSize = input(0);\n readonly maxFiles = input(0);\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\n readonly showPreview = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n // Outputs\n readonly filesSelected = output<FileUploadFile[]>();\n readonly fileRemoved = output<FileUploadFile>();\n readonly filesDropped = output<FileUploadFile[]>();\n readonly validationErrors = output<FileUploadValidationError[]>();\n\n // Internal state\n readonly _files: WritableSignal<FileUploadFile[]> = signal([]);\n readonly _isDragOver: WritableSignal<boolean> = signal(false);\n\n // ViewChild\n readonly fileInput = viewChild<ElementRef<HTMLInputElement>>('fileInput');\n\n // Public methods\n browse(): void {\n if (this.disabled()) return;\n this.fileInput()?.nativeElement.click();\n }\n\n removeFile(index: number): void {\n if (this.disabled()) return;\n const files = [...this._files()];\n const removed = files.splice(index, 1)[0];\n if (removed) {\n if (removed.previewUrl) {\n URL.revokeObjectURL(removed.previewUrl);\n }\n this._files.set(files);\n this.fileRemoved.emit(removed);\n }\n }\n\n clearAll(): void {\n const files = this._files();\n for (const f of files) {\n if (f.previewUrl) {\n URL.revokeObjectURL(f.previewUrl);\n }\n }\n this._files.set([]);\n }\n\n getFiles(): FileUploadFile[] {\n return this._files();\n }\n\n // Template event handlers\n _onFileInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this._processFiles(input.files);\n }\n // Reset input so the same file can be selected again\n input.value = '';\n }\n\n _onDragEnter(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (!this.disabled()) {\n this._isDragOver.set(true);\n }\n }\n\n _onDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (!this.disabled()) {\n this._isDragOver.set(true);\n }\n }\n\n _onDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this._isDragOver.set(false);\n }\n\n _onDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this._isDragOver.set(false);\n\n if (this.disabled()) return;\n\n const files = event.dataTransfer?.files;\n if (files && files.length > 0) {\n this._processFiles(files);\n this.filesDropped.emit(this._files());\n }\n }\n\n _formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const size = parseFloat((bytes / Math.pow(k, i)).toFixed(1));\n return `${size} ${units[i]}`;\n }\n\n // Private methods\n private _processFiles(fileList: FileList): void {\n const newFiles: FileUploadFile[] = [];\n const errors: FileUploadValidationError[] = [];\n const currentFiles = this._files();\n\n const filesToProcess = Array.from(fileList);\n\n for (const file of filesToProcess) {\n // Max files check\n const maxFiles = this.maxFiles();\n if (maxFiles > 0 && currentFiles.length + newFiles.length >= maxFiles) {\n errors.push({\n file,\n error: 'maxFiles',\n message: `Maximum ${maxFiles} file(s) allowed`,\n });\n continue;\n }\n\n const validationError = this._validateFile(file);\n if (validationError) {\n errors.push(validationError);\n continue;\n }\n\n const uploadFile: FileUploadFile = {\n file,\n name: file.name,\n size: file.size,\n type: file.type,\n };\n\n if (this.showPreview() && this._isImage(file)) {\n uploadFile.previewUrl = this._generatePreview(file);\n }\n\n newFiles.push(uploadFile);\n }\n\n if (errors.length > 0) {\n this.validationErrors.emit(errors);\n }\n\n if (newFiles.length > 0) {\n if (this.multiple()) {\n this._files.set([...currentFiles, ...newFiles]);\n } else {\n // Single mode: replace existing\n for (const f of currentFiles) {\n if (f.previewUrl) URL.revokeObjectURL(f.previewUrl);\n }\n this._files.set([newFiles[0]]);\n }\n this.filesSelected.emit(this._files());\n }\n }\n\n private _validateFile(file: File): FileUploadValidationError | null {\n // Type check\n const accept = this.accept();\n if (accept && !this._matchesAccept(file, accept)) {\n return {\n file,\n error: 'type',\n message: `File type \"${file.type || file.name.split('.').pop()}\" is not allowed`,\n };\n }\n\n // Size check\n const maxSize = this.maxFileSize();\n if (maxSize > 0 && file.size > maxSize) {\n return {\n file,\n error: 'size',\n message: `File size ${this._formatFileSize(file.size)} exceeds maximum ${this._formatFileSize(maxSize)}`,\n };\n }\n\n return null;\n }\n\n private _matchesAccept(file: File, accept: string): boolean {\n const acceptTypes = accept.split(',').map((t) => t.trim().toLowerCase());\n\n for (const acceptType of acceptTypes) {\n // Wildcard MIME type (e.g. \"image/*\")\n if (acceptType.endsWith('/*')) {\n const category = acceptType.slice(0, acceptType.indexOf('/'));\n if (file.type.toLowerCase().startsWith(category + '/')) {\n return true;\n }\n }\n // Extension match (e.g. \".pdf\")\n else if (acceptType.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(acceptType)) {\n return true;\n }\n }\n // Exact MIME match\n else if (file.type.toLowerCase() === acceptType) {\n return true;\n }\n }\n\n return false;\n }\n\n private _isImage(file: File): boolean {\n return file.type.startsWith('image/');\n }\n\n private _generatePreview(file: File): string {\n return URL.createObjectURL(file);\n }\n}\n","<input\n #fileInput\n type=\"file\"\n class=\"fui-file-upload__native-input\"\n [attr.accept]=\"accept()\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [attr.disabled]=\"disabled() ? '' : null\"\n (change)=\"_onFileInputChange($event)\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n/>\n\n<div\n class=\"fui-file-upload__dropzone\"\n (click)=\"browse()\"\n (dragenter)=\"_onDragEnter($event)\"\n (dragover)=\"_onDragOver($event)\"\n (dragleave)=\"_onDragLeave($event)\"\n (drop)=\"_onDrop($event)\"\n (keydown.enter)=\"browse()\"\n (keydown.space)=\"browse(); $event.preventDefault()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n role=\"button\"\n [attr.aria-label]=\"'Drop files here or click to browse'\"\n [attr.aria-disabled]=\"disabled()\"\n>\n <fui-icon name=\"upload-simple\" size=\"lg\" class=\"fui-file-upload__icon\"></fui-icon>\n <span class=\"fui-file-upload__text\"> Drag &amp; drop files here or <strong>browse</strong> </span>\n @if (accept()) {\n <span class=\"fui-file-upload__hint\">Accepted: {{ accept() }}</span>\n }\n @if (maxFileSize() > 0) {\n <span class=\"fui-file-upload__hint\">Max size: {{ _formatFileSize(maxFileSize()) }}</span>\n }\n</div>\n\n@if (_files().length > 0) {\n <ul class=\"fui-file-upload__file-list\" role=\"list\">\n @for (fileItem of _files(); track fileItem.name; let i = $index) {\n <li class=\"fui-file-upload__file-item\" [class.fui-file-upload__file-item--error]=\"fileItem.error\">\n @if (showPreview() && fileItem.previewUrl) {\n <img [src]=\"fileItem.previewUrl\" class=\"fui-file-upload__preview\" [alt]=\"fileItem.name\" />\n } @else {\n <fui-icon name=\"file\" size=\"sm\" class=\"fui-file-upload__file-icon\"></fui-icon>\n }\n <div class=\"fui-file-upload__file-info\">\n <span class=\"fui-file-upload__file-name\">{{ fileItem.name }}</span>\n <span class=\"fui-file-upload__file-size\">{{ _formatFileSize(fileItem.size) }}</span>\n @if (fileItem.error) {\n <span class=\"fui-file-upload__file-error\">{{ fileItem.error }}</span>\n }\n </div>\n <button\n type=\"button\"\n class=\"fui-file-upload__remove-btn\"\n (click)=\"removeFile(i); $event.stopPropagation()\"\n [attr.aria-label]=\"'Remove ' + fileItem.name\"\n [disabled]=\"disabled()\"\n >\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\n </button>\n </li>\n }\n </ul>\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":"raintonic-formaui-components-file-upload.mjs","sources":["../../../lib/components/file-upload/file-upload.component.ts","../../../lib/components/file-upload/file-upload.component.html","../../../lib/components/file-upload/raintonic-formaui-components-file-upload.ts"],"sourcesContent":["import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n signal,\r\n viewChild,\r\n ElementRef,\r\n WritableSignal,\r\n booleanAttribute,\r\n} from '@angular/core';\r\n\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FileUploadFile, FileUploadValidationError } from './file-upload.types';\r\n\r\n/**\r\n * # FuiFileUploadComponent\r\n *\r\n * A file upload component with drag-and-drop support, file previews, and validation.\r\n *\r\n * ## Features\r\n * - Drag & drop file upload\r\n * - Click to browse\r\n * - File type, size, and count validation\r\n * - Image preview thumbnails\r\n * - Accessible (keyboard, ARIA)\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic\r\n * ```html\r\n * <fui-file-upload\r\n * accept=\"image/*,.pdf\"\r\n * [multiple]=\"true\"\r\n * [maxFileSize]=\"5242880\"\r\n * (filesSelected)=\"onFiles($event)\"\r\n * ></fui-file-upload>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-file-upload',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './file-upload.component.html',\r\n styleUrls: ['./file-upload.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-file-upload',\r\n '[class.fui-file-upload--disabled]': 'disabled()',\r\n '[class.fui-file-upload--drag-over]': '_isDragOver()',\r\n '[class.fui-file-upload--has-files]': '_files().length > 0',\r\n },\r\n})\r\nexport class FuiFileUploadComponent {\r\n // Inputs\r\n readonly accept = input('');\r\n readonly multiple = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly maxFileSize = input(0);\r\n readonly maxFiles = input(0);\r\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n readonly showPreview = input<boolean, unknown>(true, { transform: booleanAttribute });\r\n\r\n // Outputs\r\n readonly filesSelected = output<FileUploadFile[]>();\r\n readonly fileRemoved = output<FileUploadFile>();\r\n readonly filesDropped = output<FileUploadFile[]>();\r\n readonly validationErrors = output<FileUploadValidationError[]>();\r\n\r\n // Internal state\r\n readonly _files: WritableSignal<FileUploadFile[]> = signal([]);\r\n readonly _isDragOver: WritableSignal<boolean> = signal(false);\r\n\r\n // ViewChild\r\n readonly fileInput = viewChild<ElementRef<HTMLInputElement>>('fileInput');\r\n\r\n // Public methods\r\n browse(): void {\r\n if (this.disabled()) return;\r\n this.fileInput()?.nativeElement.click();\r\n }\r\n\r\n removeFile(index: number): void {\r\n if (this.disabled()) return;\r\n const files = [...this._files()];\r\n const removed = files.splice(index, 1)[0];\r\n if (removed) {\r\n if (removed.previewUrl) {\r\n URL.revokeObjectURL(removed.previewUrl);\r\n }\r\n this._files.set(files);\r\n this.fileRemoved.emit(removed);\r\n }\r\n }\r\n\r\n clearAll(): void {\r\n const files = this._files();\r\n for (const f of files) {\r\n if (f.previewUrl) {\r\n URL.revokeObjectURL(f.previewUrl);\r\n }\r\n }\r\n this._files.set([]);\r\n }\r\n\r\n getFiles(): FileUploadFile[] {\r\n return this._files();\r\n }\r\n\r\n // Template event handlers\r\n _onFileInputChange(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n this._processFiles(input.files);\r\n }\r\n // Reset input so the same file can be selected again\r\n input.value = '';\r\n }\r\n\r\n _onDragEnter(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.disabled()) {\r\n this._isDragOver.set(true);\r\n }\r\n }\r\n\r\n _onDragOver(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.disabled()) {\r\n this._isDragOver.set(true);\r\n }\r\n }\r\n\r\n _onDragLeave(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this._isDragOver.set(false);\r\n }\r\n\r\n _onDrop(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this._isDragOver.set(false);\r\n\r\n if (this.disabled()) return;\r\n\r\n const files = event.dataTransfer?.files;\r\n if (files && files.length > 0) {\r\n this._processFiles(files);\r\n this.filesDropped.emit(this._files());\r\n }\r\n }\r\n\r\n _formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const units = ['B', 'KB', 'MB', 'GB'];\r\n const k = 1024;\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n const size = parseFloat((bytes / Math.pow(k, i)).toFixed(1));\r\n return `${size} ${units[i]}`;\r\n }\r\n\r\n // Private methods\r\n private _processFiles(fileList: FileList): void {\r\n const newFiles: FileUploadFile[] = [];\r\n const errors: FileUploadValidationError[] = [];\r\n const currentFiles = this._files();\r\n\r\n const filesToProcess = Array.from(fileList);\r\n\r\n for (const file of filesToProcess) {\r\n // Max files check\r\n const maxFiles = this.maxFiles();\r\n if (maxFiles > 0 && currentFiles.length + newFiles.length >= maxFiles) {\r\n errors.push({\r\n file,\r\n error: 'maxFiles',\r\n message: `Maximum ${maxFiles} file(s) allowed`,\r\n });\r\n continue;\r\n }\r\n\r\n const validationError = this._validateFile(file);\r\n if (validationError) {\r\n errors.push(validationError);\r\n continue;\r\n }\r\n\r\n const uploadFile: FileUploadFile = {\r\n file,\r\n name: file.name,\r\n size: file.size,\r\n type: file.type,\r\n };\r\n\r\n if (this.showPreview() && this._isImage(file)) {\r\n uploadFile.previewUrl = this._generatePreview(file);\r\n }\r\n\r\n newFiles.push(uploadFile);\r\n }\r\n\r\n if (errors.length > 0) {\r\n this.validationErrors.emit(errors);\r\n }\r\n\r\n if (newFiles.length > 0) {\r\n if (this.multiple()) {\r\n this._files.set([...currentFiles, ...newFiles]);\r\n } else {\r\n // Single mode: replace existing\r\n for (const f of currentFiles) {\r\n if (f.previewUrl) URL.revokeObjectURL(f.previewUrl);\r\n }\r\n this._files.set([newFiles[0]]);\r\n }\r\n this.filesSelected.emit(this._files());\r\n }\r\n }\r\n\r\n private _validateFile(file: File): FileUploadValidationError | null {\r\n // Type check\r\n const accept = this.accept();\r\n if (accept && !this._matchesAccept(file, accept)) {\r\n return {\r\n file,\r\n error: 'type',\r\n message: `File type \"${file.type || file.name.split('.').pop()}\" is not allowed`,\r\n };\r\n }\r\n\r\n // Size check\r\n const maxSize = this.maxFileSize();\r\n if (maxSize > 0 && file.size > maxSize) {\r\n return {\r\n file,\r\n error: 'size',\r\n message: `File size ${this._formatFileSize(file.size)} exceeds maximum ${this._formatFileSize(maxSize)}`,\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private _matchesAccept(file: File, accept: string): boolean {\r\n const acceptTypes = accept.split(',').map((t) => t.trim().toLowerCase());\r\n\r\n for (const acceptType of acceptTypes) {\r\n // Wildcard MIME type (e.g. \"image/*\")\r\n if (acceptType.endsWith('/*')) {\r\n const category = acceptType.slice(0, acceptType.indexOf('/'));\r\n if (file.type.toLowerCase().startsWith(category + '/')) {\r\n return true;\r\n }\r\n }\r\n // Extension match (e.g. \".pdf\")\r\n else if (acceptType.startsWith('.')) {\r\n if (file.name.toLowerCase().endsWith(acceptType)) {\r\n return true;\r\n }\r\n }\r\n // Exact MIME match\r\n else if (file.type.toLowerCase() === acceptType) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _isImage(file: File): boolean {\r\n return file.type.startsWith('image/');\r\n }\r\n\r\n private _generatePreview(file: File): string {\r\n return URL.createObjectURL(file);\r\n }\r\n}\r\n","<input\r\n #fileInput\r\n type=\"file\"\r\n class=\"fui-file-upload__native-input\"\r\n [attr.accept]=\"accept()\"\r\n [attr.multiple]=\"multiple() ? '' : null\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n (change)=\"_onFileInputChange($event)\"\r\n tabindex=\"-1\"\r\n aria-hidden=\"true\"\r\n/>\r\n\r\n<div\r\n class=\"fui-file-upload__dropzone\"\r\n (click)=\"browse()\"\r\n (dragenter)=\"_onDragEnter($event)\"\r\n (dragover)=\"_onDragOver($event)\"\r\n (dragleave)=\"_onDragLeave($event)\"\r\n (drop)=\"_onDrop($event)\"\r\n (keydown.enter)=\"browse()\"\r\n (keydown.space)=\"browse(); $event.preventDefault()\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n role=\"button\"\r\n [attr.aria-label]=\"'Drop files here or click to browse'\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n>\r\n <fui-icon name=\"upload-simple\" size=\"lg\" class=\"fui-file-upload__icon\"></fui-icon>\r\n <span class=\"fui-file-upload__text\"> Drag &amp; drop files here or <strong>browse</strong> </span>\r\n @if (accept()) {\r\n <span class=\"fui-file-upload__hint\">Accepted: {{ accept() }}</span>\r\n }\r\n @if (maxFileSize() > 0) {\r\n <span class=\"fui-file-upload__hint\">Max size: {{ _formatFileSize(maxFileSize()) }}</span>\r\n }\r\n</div>\r\n\r\n@if (_files().length > 0) {\r\n <ul class=\"fui-file-upload__file-list\" role=\"list\">\r\n @for (fileItem of _files(); track fileItem.name; let i = $index) {\r\n <li class=\"fui-file-upload__file-item\" [class.fui-file-upload__file-item--error]=\"fileItem.error\">\r\n @if (showPreview() && fileItem.previewUrl) {\r\n <img [src]=\"fileItem.previewUrl\" class=\"fui-file-upload__preview\" [alt]=\"fileItem.name\" />\r\n } @else {\r\n <fui-icon name=\"file\" size=\"sm\" class=\"fui-file-upload__file-icon\"></fui-icon>\r\n }\r\n <div class=\"fui-file-upload__file-info\">\r\n <span class=\"fui-file-upload__file-name\">{{ fileItem.name }}</span>\r\n <span class=\"fui-file-upload__file-size\">{{ _formatFileSize(fileItem.size) }}</span>\r\n @if (fileItem.error) {\r\n <span class=\"fui-file-upload__file-error\">{{ fileItem.error }}</span>\r\n }\r\n </div>\r\n <button\r\n type=\"button\"\r\n class=\"fui-file-upload__remove-btn\"\r\n (click)=\"removeFile(i); $event.stopPropagation()\"\r\n [attr.aria-label]=\"'Remove ' + fileItem.name\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-form-field.mjs","sources":["../../../lib/components/form-field/prefix.directive.ts","../../../lib/components/form-field/suffix.directive.ts","../../../lib/components/form-field/form-field.component.ts","../../../lib/components/form-field/form-field.component.html","../../../lib/components/form-field/error.component.ts","../../../lib/components/form-field/hint.component.ts","../../../lib/components/form-field/label.component.ts","../../../lib/components/form-field/raintonic-formaui-components-form-field.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Prefix directive for content to be placed before the input in fui-form-field\n *\n * @example\n * ```html\n * <fui-form-field>\n * <fui-label>Price</fui-label>\n * <span fuiPrefix>$</span>\n * <input fuiInput type=\"number\">\n * </fui-form-field>\n * ```\n */\n@Directive({\n selector: '[fuiPrefix]',\n standalone: true,\n host: {\n class: 'fui-prefix',\n },\n})\nexport class FuiPrefixDirective {}\n","import { Directive } from '@angular/core';\n\n/**\n * Suffix directive for content to be placed after the input in fui-form-field\n *\n * @example\n * ```html\n * <fui-form-field>\n * <fui-label>Weight</fui-label>\n * <input fuiInput type=\"number\">\n * <span fuiSuffix>kg</span>\n * </fui-form-field>\n * ```\n */\n@Directive({\n selector: '[fuiSuffix]',\n standalone: true,\n host: {\n class: 'fui-suffix',\n },\n})\nexport class FuiSuffixDirective {}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ContentChildren,\n effect,\n ElementRef,\n input,\n InputSignal,\n QueryList,\n Signal,\n signal,\n ViewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { FuiPrefixDirective } from './prefix.directive';\nimport { FuiSuffixDirective } from './suffix.directive';\nimport { FUI_FORM_FIELD_CONTROL } from '@raintonic/formaui/core';\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\n\n/**\n * Available form field appearance modes.\n * - `'outline'` — default bordered appearance (Carbon Design System style)\n * - `'fill'` — filled background with bottom-border only\n * - `'float'` — floating-label that animates above the input on focus / value\n */\nexport type FormFieldAppearance = 'outline' | 'fill' | 'float';\n\n/**\n * # FormField Component\n *\n * A form field wrapper component that provides consistent styling and behavior\n * for form controls. Follows Angular Material patterns with Carbon Design System styling.\n *\n * ## Features\n * - Floating labels with configurable behavior\n * - Error message display with animations\n * - Helper text support\n * - Prefix and suffix support\n * - Outline appearance with Carbon Design System styling\n * - Full accessibility support\n * - Automatic integration with form controls\n *\n * ## Usage\n *\n * ### Basic Form Field\n * ```html\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\" placeholder=\"Enter your email\">\n * </fui-form-field>\n * ```\n *\n * ### With Error Messages\n * ```html\n * <fui-form-field>\n * <fui-label>Username</fui-label>\n * <input fuiInput formControlName=\"username\">\n * <fui-error key=\"required\">Username is required</fui-error>\n * <fui-error key=\"minlength\">Username must be at least 3 characters</fui-error>\n * </fui-form-field>\n * ```\n *\n * ### With Helper Text and Icons\n * ```html\n * <fui-form-field>\n * <fui-label>Password</fui-label>\n * <fui-icon fuiPrefix name=\"lock\"></fui-icon>\n * <input fuiInput type=\"password\">\n * <button fuiSuffix fuiButton variant=\"ghost\" (click)=\"togglePasswordVisibility()\">\n * <fui-icon [name]=\"showPassword ? 'eye-slash' : 'eye'\"></fui-icon>\n * </button>\n * <fui-hint>Must be at least 8 characters</fui-hint>\n * </fui-form-field>\n * ```\n *\n * @example\n * ```typescript\n * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';\n * import { FuiInputDirective } from '@raintonic/formaui/components/input';\n *\n * @Component({\n * standalone: true,\n * imports: [FuiFormFieldComponent, FuiInputDirective, ReactiveFormsModule],\n * template: `\n * <form [formGroup]=\"form\">\n * <fui-form-field>\n * <fui-label>Email Address</fui-label>\n * <input fuiInput type=\"email\" formControlName=\"email\">\n * <fui-error key=\"required\">Email is required</fui-error>\n * <fui-error key=\"email\">Please enter a valid email</fui-error>\n * </fui-form-field>\n * </form>\n * `\n * })\n * export class MyFormComponent {\n * form = this.fb.group({\n * email: ['', [Validators.required, Validators.email]]\n * });\n *\n * get emailControl() {\n * return this.form.get('email');\n * }\n * }\n * ```\n */\n@Component({\n selector: 'fui-form-field',\n standalone: true,\n imports: [FuiIconComponent],\n templateUrl: './form-field.component.html',\n styleUrls: ['./form-field.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-form-field',\n '[class.fui-form-field--disabled]': 'isDisabled()',\n '[class.fui-form-field--focused]': 'isFocused()',\n '[class.fui-form-field--error]': 'hasError()',\n '[class.fui-form-field--empty]': 'isEmpty()',\n '[class.fui-form-field--readonly]': 'readOnly()',\n '[class.fui-form-field--float]': 'appearance() === \"float\"',\n '[class.fui-form-field--fill]': 'appearance() === \"fill\"',\n '[class.fui-form-field--float-active]': 'shouldFloat()',\n role: 'group',\n '[attr.aria-labelledby]': 'labelId',\n '[attr.aria-disabled]': 'isDisabled() || null',\n },\n})\nexport class FuiFormFieldComponent {\n /**\n * Whether the form field is in read-only mode.\n * When true, hides the input and shows a plain text value instead.\n * @default false\n */\n readonly readOnly: InputSignal<boolean> = input(false);\n\n /**\n * Visual appearance variant.\n * - `'outline'` (default): bordered input with label above\n * - `'fill'`: filled background with bottom-border accent\n * - `'float'`: label floats from inside the input to above it on focus/value\n */\n readonly appearance = input<FormFieldAppearance>('outline');\n\n /**\n * Whether to hide the required marker\n * @default false\n */\n readonly hideRequiredMarker: InputSignal<boolean> = input(false);\n\n // Content children\n control = contentChild(FUI_FORM_FIELD_CONTROL);\n\n @ContentChildren(FuiPrefixDirective, { descendants: true }) _prefixes?: QueryList<FuiPrefixDirective>;\n @ContentChildren(FuiSuffixDirective, { descendants: true }) _suffixes?: QueryList<FuiSuffixDirective>;\n @ViewChild('connectionContainer', { static: true }) _connectionContainerRef?: ElementRef<HTMLElement>;\n\n hideSubscript = input(false);\n\n // Read-only display value derived from the control's value\n // For select/autocomplete controls, uses their displayValue signal to show the label\n readonly displayValue: Signal<string> = computed(() => {\n const control = this.control();\n if (!control) return '\\u2014';\n\n // Select and autocomplete controls expose a displayValue signal with the option label\n if (\n 'displayValue' in control &&\n typeof (control as unknown as Record<string, unknown>)['displayValue'] === 'function'\n ) {\n const label = ((control as unknown as Record<string, unknown>)['displayValue'] as () => string)();\n return label || '\\u2014';\n }\n\n const val = control.value();\n if (val == null || val === '') return '\\u2014';\n return String(val);\n });\n\n // State signals\n readonly isFocused: Signal<boolean> = computed(() => {\n return this.control()?.focused() ?? false;\n });\n readonly hasError: Signal<boolean> = computed(() => {\n return this.control()?.errorState() ?? false;\n });\n readonly isDisabled: Signal<boolean> = computed(() => {\n return this.control()?.disabled() ?? false;\n });\n readonly isEmpty: Signal<boolean> = computed(() => {\n return this.control()?.empty() ?? false;\n });\n readonly isRequired: Signal<boolean> = computed(() => {\n return this.control()?.required() ?? false;\n });\n\n /**\n * Whether the floating label should be in its \"floated\" (raised) position.\n * Only meaningful when `appearance === 'float'`. True when the field is\n * focused or contains a non-empty value.\n */\n readonly shouldFloat: Signal<boolean> = computed(() => {\n if (this.appearance() !== 'float') return false;\n return this.isFocused() || !this.isEmpty();\n });\n\n /** Whether control-specific icons (dropdown caret, calendar) should be hidden in readOnly mode */\n readonly hideControlIcons: Signal<boolean> = computed(() => {\n if (!this.readOnly()) return false;\n const ct = this.control()?.controlType;\n return ct === 'fui-select' || ct === 'fui-autocomplete' || ct === 'fui-date-picker';\n });\n\n /** Whether the \"copied\" feedback indicator is active */\n readonly copied: WritableSignal<boolean> = signal(false);\n private _copiedTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Generate unique IDs\n readonly labelId = `fui-form-field-label-${Math.random().toString(36).substring(2, 11)}`;\n readonly hintId = `fui-form-field-hint-${Math.random().toString(36).substring(2, 11)}`;\n readonly errorId = `fui-form-field-error-${Math.random().toString(36).substring(2, 11)}`;\n\n constructor() {\n // Effect to update aria-describedby when state changes\n effect(() => {\n const control = this.control();\n if (control) {\n const ids: string[] = [];\n\n if (this.hasError()) {\n ids.push(this.errorId);\n } else {\n ids.push(this.hintId);\n }\n\n control.setDescribedByIds(ids);\n } else {\n // FuiFormField must contain an FuiFormFieldControl\n }\n });\n\n // Effect to propagate readOnly state to child controls\n effect(() => {\n const control = this.control();\n const ro = this.readOnly();\n if (control?.setReadOnly) {\n control.setReadOnly(ro);\n }\n });\n }\n\n /**\n * Handles click on the form field container\n */\n onContainerClick(event: MouseEvent): void {\n const control = this.control();\n if (control && !this.isDisabled() && !this.readOnly()) {\n control.onContainerClick(event);\n }\n }\n\n /**\n * Copies the display value to the clipboard\n */\n copyValue(): void {\n const text = this.displayValue();\n if (!text || text === '\\u2014') return;\n\n void navigator.clipboard.writeText(text).then(() => {\n this.copied.set(true);\n if (this._copiedTimeout) clearTimeout(this._copiedTimeout);\n this._copiedTimeout = setTimeout(() => {\n this.copied.set(false);\n this._copiedTimeout = null;\n }, 1500);\n });\n }\n\n /**\n * Gets the current error messages\n */\n getErrorMessages(): string[] {\n // This would be populated by projected fui-error components\n // Implementation would query ContentChildren for error components\n return [];\n }\n\n /**\n * Checks if the form field contains a select control\n */\n hasSelectControl(): boolean {\n const control = this.control();\n if (!control) return false;\n\n // Check if it's the full fui-select component\n if (control.controlType === 'fui-select') {\n return true;\n }\n\n // Check if it's fuiInput directive on a select element\n if (\n control.controlType === 'fui-input' &&\n typeof (control as unknown as Record<string, unknown>)['isSelect'] === 'function'\n ) {\n return ((control as unknown as Record<string, unknown>)['isSelect'] as () => boolean)();\n }\n\n return false;\n }\n\n /**\n * Checks if the select control is a multiple select\n */\n isMultipleSelect(): boolean {\n if (!this.hasSelectControl()) {\n return false;\n }\n // Check if the control has a multiple property and it's true\n const ctrl = this.control() as unknown as Record<string, unknown> | undefined;\n return typeof ctrl?.['multiple'] === 'function' ? (ctrl['multiple'] as () => boolean)() : false;\n }\n\n /**\n * Whether there is projected prefix content\n */\n hasPrefix(): boolean {\n return (this._prefixes?.length ?? 0) > 0;\n }\n\n /**\n * Whether there is projected suffix content\n */\n hasSuffix(): boolean {\n return (this._suffixes?.length ?? 0) > 0;\n }\n}\n","<div class=\"fui-form-field__container\">\r\n <!-- Label - Carbon Design System style (outside wrapper) -->\r\n <label class=\"fui-form-field__label fui-animate-fade\" [attr.id]=\"labelId\" [attr.for]=\"control()?.id\">\r\n <ng-content select=\"fui-label\"></ng-content>\r\n @if (isRequired() && !readOnly()) {\r\n <span class=\"fui-form-field__required-marker\" [class.--has-error]=\"hasError()\">*</span>\r\n }\r\n </label>\r\n\r\n <!-- Wrapper — always visible, styled as read-only when applicable -->\r\n <div\r\n class=\"fui-form-field__wrapper\"\r\n [class.fui-form-field__wrapper--readonly]=\"readOnly()\"\r\n (click)=\"onContainerClick($event)\"\r\n >\r\n <!-- Prefix -->\r\n @if (hasPrefix()) {\r\n <div class=\"fui-form-field__prefix\">\r\n <ng-content select=\"[fuiPrefix]\"></ng-content>\r\n </div>\r\n }\r\n\r\n <!-- Infix (contains input) -->\r\n <div class=\"fui-form-field__infix\">\r\n <!-- Input container -->\r\n <div class=\"fui-form-field__input\" #connectionContainer>\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Suffix -->\r\n @if (hasSuffix() || (hasSelectControl() && !isMultipleSelect()) || readOnly()) {\r\n <div class=\"fui-form-field__suffix\">\r\n <!-- User-projected suffix content -->\r\n <ng-content select=\"[fuiSuffix]\"></ng-content>\r\n\r\n <!-- Dropdown icon for select elements (not multiple) — hidden in readOnly -->\r\n @if (hasSelectControl() && !isMultipleSelect() && !readOnly()) {\r\n <div class=\"fui-form-field__select-icon\">\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </div>\r\n }\r\n\r\n <!-- Copy button — visible only in readOnly on hover -->\r\n @if (readOnly()) {\r\n <button\r\n type=\"button\"\r\n class=\"fui-form-field__copy-btn\"\r\n (click)=\"copyValue(); $event.stopPropagation()\"\r\n [attr.aria-label]=\"copied() ? 'Copied' : 'Copy value'\"\r\n >\r\n <fui-icon [name]=\"copied() ? 'check' : 'copy'\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (!hideSubscript()) {\r\n <!-- Helper text and error messages container -->\r\n <div class=\"fui-form-field__subscript-wrapper\">\r\n <!-- Error messages -->\r\n @if (hasError()) {\r\n <div class=\"fui-form-field__error-wrapper fui-animate-slide-in-top\">\r\n <div class=\"fui-form-field__error\" [attr.id]=\"errorId\">\r\n <ng-content select=\"fui-error\"></ng-content>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Hint text -->\r\n <div class=\"fui-form-field__hint-wrapper fui-animate-fade\">\r\n <div class=\"fui-form-field__hint\" [attr.id]=\"hintId\">\r\n <ng-content select=\"fui-hint\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n","import { Component, computed, inject, input, Signal } from '@angular/core';\nimport { FuiFormFieldComponent } from './form-field.component';\n\n/**\n * FuiErrorComponent\n *\n * Validation error message shown under the form field. Can automatically show/hide\n * based on a specific error key, or use with *ngIf for custom control logic.\n * The component provides proper accessibility roles and live region behavior.\n *\n * @example\n * ```html\n * <!-- Automatic error key handling -->\n * <fui-error key=\"required\">This field is required</fui-error>\n * <fui-error key=\"email\">Please enter a valid email</fui-error>\n *\n * <!-- Manual control (backward compatible) -->\n * <fui-error *ngIf=\"control.hasError('custom')\">Custom error</fui-error>\n * ```\n */\n@Component({\n selector: 'fui-error',\n standalone: true,\n template: ` <ng-content></ng-content> `,\n host: {\n class: 'fui-error',\n role: 'alert',\n 'aria-live': 'assertive',\n '[style.display]': '_shouldHide() ? \"none\" : null',\n },\n})\nexport class FuiErrorComponent {\n /**\n * Optional error key to match against form control errors.\n * When provided, the error will only show if the control has this specific error.\n * When not provided, the error will always show (backward compatible behavior).\n */\n readonly key = input<string>();\n\n private readonly _parent = inject(FuiFormFieldComponent, { host: true });\n\n /**\n * Computed signal to determine if this error should be hidden\n */\n protected readonly _shouldHide: Signal<boolean> = computed(() => {\n if (!this._parent.control()?.errorState()) {\n return true;\n }\n const errorKey = this.key();\n // If no key is provided, always show (backward compatible)\n if (!errorKey) {\n return false;\n }\n\n // If no form field control is available, show the error\n const formFieldControl = this._parent.control();\n if (!formFieldControl) {\n return false;\n }\n\n // Get the ngControl from the form field control\n const ngControl = formFieldControl.ngControl;\n if (!ngControl?.control) {\n return false;\n }\n\n // Hide if the control doesn't have this specific error\n return !ngControl.control.hasError(errorKey);\n });\n}\n","import { Component } from '@angular/core';\n\n/**\n * @component FuiHintComponent\n * @selector fui-hint\n * @description Helper text displayed below the form field input when there is no error.\n * Automatically hidden when the parent form field is in an error state.\n *\n * @example\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\">\n * <fui-hint>We will never share your email</fui-hint>\n * </fui-form-field>\n */\n@Component({\n selector: 'fui-hint',\n standalone: true,\n template: ` <ng-content></ng-content> `,\n host: {\n class: 'fui-hint',\n },\n})\nexport class FuiHintComponent {}\n","import { Component } from '@angular/core';\n\n/**\n * @component FuiLabelComponent\n * @selector fui-label\n * @description Label element projected inside `fui-form-field` to provide an accessible\n * field label. Automatically linked to the form control via `aria-labelledby`.\n *\n * @example\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\">\n * </fui-form-field>\n */\n@Component({\n selector: 'fui-label',\n standalone: true,\n template: ` <ng-content></ng-content> `,\n host: {\n class: 'fui-label',\n },\n})\nexport class FuiLabelComponent {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"raintonic-formaui-components-form-field.mjs","sources":["../../../lib/components/form-field/prefix.directive.ts","../../../lib/components/form-field/suffix.directive.ts","../../../lib/components/form-field/form-field.component.ts","../../../lib/components/form-field/form-field.component.html","../../../lib/components/form-field/error.component.ts","../../../lib/components/form-field/hint.component.ts","../../../lib/components/form-field/label.component.ts","../../../lib/components/form-field/raintonic-formaui-components-form-field.ts"],"sourcesContent":["import { Directive } from '@angular/core';\r\n\r\n/**\r\n * Prefix directive for content to be placed before the input in fui-form-field\r\n *\r\n * @example\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Price</fui-label>\r\n * <span fuiPrefix>$</span>\r\n * <input fuiInput type=\"number\">\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[fuiPrefix]',\r\n standalone: true,\r\n host: {\r\n class: 'fui-prefix',\r\n },\r\n})\r\nexport class FuiPrefixDirective {}\r\n","import { Directive } from '@angular/core';\r\n\r\n/**\r\n * Suffix directive for content to be placed after the input in fui-form-field\r\n *\r\n * @example\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Weight</fui-label>\r\n * <input fuiInput type=\"number\">\r\n * <span fuiSuffix>kg</span>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[fuiSuffix]',\r\n standalone: true,\r\n host: {\r\n class: 'fui-suffix',\r\n },\r\n})\r\nexport class FuiSuffixDirective {}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n contentChild,\r\n ContentChildren,\r\n effect,\r\n ElementRef,\r\n input,\r\n InputSignal,\r\n QueryList,\r\n Signal,\r\n signal,\r\n ViewChild,\r\n ViewEncapsulation,\r\n WritableSignal,\r\n} from '@angular/core';\r\n\r\nimport { FuiPrefixDirective } from './prefix.directive';\r\nimport { FuiSuffixDirective } from './suffix.directive';\r\nimport { FUI_FORM_FIELD_CONTROL } from '@raintonic/formaui/core';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\n\r\n/**\r\n * Available form field appearance modes.\r\n * - `'outline'` — default bordered appearance (Carbon Design System style)\r\n * - `'fill'` — filled background with bottom-border only\r\n * - `'float'` — floating-label that animates above the input on focus / value\r\n */\r\nexport type FormFieldAppearance = 'outline' | 'fill' | 'float';\r\n\r\n/**\r\n * # FormField Component\r\n *\r\n * A form field wrapper component that provides consistent styling and behavior\r\n * for form controls. Follows Angular Material patterns with Carbon Design System styling.\r\n *\r\n * ## Features\r\n * - Floating labels with configurable behavior\r\n * - Error message display with animations\r\n * - Helper text support\r\n * - Prefix and suffix support\r\n * - Outline appearance with Carbon Design System styling\r\n * - Full accessibility support\r\n * - Automatic integration with form controls\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Form Field\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Email</fui-label>\r\n * <input fuiInput type=\"email\" placeholder=\"Enter your email\">\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Error Messages\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Username</fui-label>\r\n * <input fuiInput formControlName=\"username\">\r\n * <fui-error key=\"required\">Username is required</fui-error>\r\n * <fui-error key=\"minlength\">Username must be at least 3 characters</fui-error>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Helper Text and Icons\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Password</fui-label>\r\n * <fui-icon fuiPrefix name=\"lock\"></fui-icon>\r\n * <input fuiInput type=\"password\">\r\n * <button fuiSuffix fuiButton variant=\"ghost\" (click)=\"togglePasswordVisibility()\">\r\n * <fui-icon [name]=\"showPassword ? 'eye-slash' : 'eye'\"></fui-icon>\r\n * </button>\r\n * <fui-hint>Must be at least 8 characters</fui-hint>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';\r\n * import { FuiInputDirective } from '@raintonic/formaui/components/input';\r\n *\r\n * @Component({\r\n * standalone: true,\r\n * imports: [FuiFormFieldComponent, FuiInputDirective, ReactiveFormsModule],\r\n * template: `\r\n * <form [formGroup]=\"form\">\r\n * <fui-form-field>\r\n * <fui-label>Email Address</fui-label>\r\n * <input fuiInput type=\"email\" formControlName=\"email\">\r\n * <fui-error key=\"required\">Email is required</fui-error>\r\n * <fui-error key=\"email\">Please enter a valid email</fui-error>\r\n * </fui-form-field>\r\n * </form>\r\n * `\r\n * })\r\n * export class MyFormComponent {\r\n * form = this.fb.group({\r\n * email: ['', [Validators.required, Validators.email]]\r\n * });\r\n *\r\n * get emailControl() {\r\n * return this.form.get('email');\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-form-field',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './form-field.component.html',\r\n styleUrls: ['./form-field.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-form-field',\r\n '[class.fui-form-field--disabled]': 'isDisabled()',\r\n '[class.fui-form-field--focused]': 'isFocused()',\r\n '[class.fui-form-field--error]': 'hasError()',\r\n '[class.fui-form-field--empty]': 'isEmpty()',\r\n '[class.fui-form-field--readonly]': 'readOnly()',\r\n '[class.fui-form-field--float]': 'appearance() === \"float\"',\r\n '[class.fui-form-field--fill]': 'appearance() === \"fill\"',\r\n '[class.fui-form-field--float-active]': 'shouldFloat()',\r\n role: 'group',\r\n '[attr.aria-labelledby]': 'labelId',\r\n '[attr.aria-disabled]': 'isDisabled() || null',\r\n },\r\n})\r\nexport class FuiFormFieldComponent {\r\n /**\r\n * Whether the form field is in read-only mode.\r\n * When true, hides the input and shows a plain text value instead.\r\n * @default false\r\n */\r\n readonly readOnly: InputSignal<boolean> = input(false);\r\n\r\n /**\r\n * Visual appearance variant.\r\n * - `'outline'` (default): bordered input with label above\r\n * - `'fill'`: filled background with bottom-border accent\r\n * - `'float'`: label floats from inside the input to above it on focus/value\r\n */\r\n readonly appearance = input<FormFieldAppearance>('outline');\r\n\r\n /**\r\n * Whether to hide the required marker\r\n * @default false\r\n */\r\n readonly hideRequiredMarker: InputSignal<boolean> = input(false);\r\n\r\n // Content children\r\n control = contentChild(FUI_FORM_FIELD_CONTROL);\r\n\r\n @ContentChildren(FuiPrefixDirective, { descendants: true }) _prefixes?: QueryList<FuiPrefixDirective>;\r\n @ContentChildren(FuiSuffixDirective, { descendants: true }) _suffixes?: QueryList<FuiSuffixDirective>;\r\n @ViewChild('connectionContainer', { static: true }) _connectionContainerRef?: ElementRef<HTMLElement>;\r\n\r\n hideSubscript = input(false);\r\n\r\n // Read-only display value derived from the control's value\r\n // For select/autocomplete controls, uses their displayValue signal to show the label\r\n readonly displayValue: Signal<string> = computed(() => {\r\n const control = this.control();\r\n if (!control) return '\\u2014';\r\n\r\n // Select and autocomplete controls expose a displayValue signal with the option label\r\n if (\r\n 'displayValue' in control &&\r\n typeof (control as unknown as Record<string, unknown>)['displayValue'] === 'function'\r\n ) {\r\n const label = ((control as unknown as Record<string, unknown>)['displayValue'] as () => string)();\r\n return label || '\\u2014';\r\n }\r\n\r\n const val = control.value();\r\n if (val == null || val === '') return '\\u2014';\r\n return String(val);\r\n });\r\n\r\n // State signals\r\n readonly isFocused: Signal<boolean> = computed(() => {\r\n return this.control()?.focused() ?? false;\r\n });\r\n readonly hasError: Signal<boolean> = computed(() => {\r\n return this.control()?.errorState() ?? false;\r\n });\r\n readonly isDisabled: Signal<boolean> = computed(() => {\r\n return this.control()?.disabled() ?? false;\r\n });\r\n readonly isEmpty: Signal<boolean> = computed(() => {\r\n return this.control()?.empty() ?? false;\r\n });\r\n readonly isRequired: Signal<boolean> = computed(() => {\r\n return this.control()?.required() ?? false;\r\n });\r\n\r\n /**\r\n * Whether the floating label should be in its \"floated\" (raised) position.\r\n * Only meaningful when `appearance === 'float'`. True when the field is\r\n * focused or contains a non-empty value.\r\n */\r\n readonly shouldFloat: Signal<boolean> = computed(() => {\r\n if (this.appearance() !== 'float') return false;\r\n return this.isFocused() || !this.isEmpty();\r\n });\r\n\r\n /** Whether control-specific icons (dropdown caret, calendar) should be hidden in readOnly mode */\r\n readonly hideControlIcons: Signal<boolean> = computed(() => {\r\n if (!this.readOnly()) return false;\r\n const ct = this.control()?.controlType;\r\n return ct === 'fui-select' || ct === 'fui-autocomplete' || ct === 'fui-date-picker';\r\n });\r\n\r\n /** Whether the \"copied\" feedback indicator is active */\r\n readonly copied: WritableSignal<boolean> = signal(false);\r\n private _copiedTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Generate unique IDs\r\n readonly labelId = `fui-form-field-label-${Math.random().toString(36).substring(2, 11)}`;\r\n readonly hintId = `fui-form-field-hint-${Math.random().toString(36).substring(2, 11)}`;\r\n readonly errorId = `fui-form-field-error-${Math.random().toString(36).substring(2, 11)}`;\r\n\r\n constructor() {\r\n // Effect to update aria-describedby when state changes\r\n effect(() => {\r\n const control = this.control();\r\n if (control) {\r\n const ids: string[] = [];\r\n\r\n if (this.hasError()) {\r\n ids.push(this.errorId);\r\n } else {\r\n ids.push(this.hintId);\r\n }\r\n\r\n control.setDescribedByIds(ids);\r\n } else {\r\n // FuiFormField must contain an FuiFormFieldControl\r\n }\r\n });\r\n\r\n // Effect to propagate readOnly state to child controls\r\n effect(() => {\r\n const control = this.control();\r\n const ro = this.readOnly();\r\n if (control?.setReadOnly) {\r\n control.setReadOnly(ro);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handles click on the form field container\r\n */\r\n onContainerClick(event: MouseEvent): void {\r\n const control = this.control();\r\n if (control && !this.isDisabled() && !this.readOnly()) {\r\n control.onContainerClick(event);\r\n }\r\n }\r\n\r\n /**\r\n * Copies the display value to the clipboard\r\n */\r\n copyValue(): void {\r\n const text = this.displayValue();\r\n if (!text || text === '\\u2014') return;\r\n\r\n void navigator.clipboard.writeText(text).then(() => {\r\n this.copied.set(true);\r\n if (this._copiedTimeout) clearTimeout(this._copiedTimeout);\r\n this._copiedTimeout = setTimeout(() => {\r\n this.copied.set(false);\r\n this._copiedTimeout = null;\r\n }, 1500);\r\n });\r\n }\r\n\r\n /**\r\n * Gets the current error messages\r\n */\r\n getErrorMessages(): string[] {\r\n // This would be populated by projected fui-error components\r\n // Implementation would query ContentChildren for error components\r\n return [];\r\n }\r\n\r\n /**\r\n * Checks if the form field contains a select control\r\n */\r\n hasSelectControl(): boolean {\r\n const control = this.control();\r\n if (!control) return false;\r\n\r\n // Check if it's the full fui-select component\r\n if (control.controlType === 'fui-select') {\r\n return true;\r\n }\r\n\r\n // Check if it's fuiInput directive on a select element\r\n if (\r\n control.controlType === 'fui-input' &&\r\n typeof (control as unknown as Record<string, unknown>)['isSelect'] === 'function'\r\n ) {\r\n return ((control as unknown as Record<string, unknown>)['isSelect'] as () => boolean)();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if the select control is a multiple select\r\n */\r\n isMultipleSelect(): boolean {\r\n if (!this.hasSelectControl()) {\r\n return false;\r\n }\r\n // Check if the control has a multiple property and it's true\r\n const ctrl = this.control() as unknown as Record<string, unknown> | undefined;\r\n return typeof ctrl?.['multiple'] === 'function' ? (ctrl['multiple'] as () => boolean)() : false;\r\n }\r\n\r\n /**\r\n * Whether there is projected prefix content\r\n */\r\n hasPrefix(): boolean {\r\n return (this._prefixes?.length ?? 0) > 0;\r\n }\r\n\r\n /**\r\n * Whether there is projected suffix content\r\n */\r\n hasSuffix(): boolean {\r\n return (this._suffixes?.length ?? 0) > 0;\r\n }\r\n}\r\n","<div class=\"fui-form-field__container\">\r\n <!-- Label - Carbon Design System style (outside wrapper) -->\r\n <label class=\"fui-form-field__label fui-animate-fade\" [attr.id]=\"labelId\" [attr.for]=\"control()?.id\">\r\n <ng-content select=\"fui-label\"></ng-content>\r\n @if (isRequired() && !readOnly()) {\r\n <span class=\"fui-form-field__required-marker\" [class.--has-error]=\"hasError()\">*</span>\r\n }\r\n </label>\r\n\r\n <!-- Wrapper — always visible, styled as read-only when applicable -->\r\n <div\r\n class=\"fui-form-field__wrapper\"\r\n [class.fui-form-field__wrapper--readonly]=\"readOnly()\"\r\n (click)=\"onContainerClick($event)\"\r\n >\r\n <!-- Prefix -->\r\n @if (hasPrefix()) {\r\n <div class=\"fui-form-field__prefix\">\r\n <ng-content select=\"[fuiPrefix]\"></ng-content>\r\n </div>\r\n }\r\n\r\n <!-- Infix (contains input) -->\r\n <div class=\"fui-form-field__infix\">\r\n <!-- Input container -->\r\n <div class=\"fui-form-field__input\" #connectionContainer>\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Suffix -->\r\n @if (hasSuffix() || (hasSelectControl() && !isMultipleSelect()) || readOnly()) {\r\n <div class=\"fui-form-field__suffix\">\r\n <!-- User-projected suffix content -->\r\n <ng-content select=\"[fuiSuffix]\"></ng-content>\r\n\r\n <!-- Dropdown icon for select elements (not multiple) — hidden in readOnly -->\r\n @if (hasSelectControl() && !isMultipleSelect() && !readOnly()) {\r\n <div class=\"fui-form-field__select-icon\">\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </div>\r\n }\r\n\r\n <!-- Copy button — visible only in readOnly on hover -->\r\n @if (readOnly()) {\r\n <button\r\n type=\"button\"\r\n class=\"fui-form-field__copy-btn\"\r\n (click)=\"copyValue(); $event.stopPropagation()\"\r\n [attr.aria-label]=\"copied() ? 'Copied' : 'Copy value'\"\r\n >\r\n <fui-icon [name]=\"copied() ? 'check' : 'copy'\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (!hideSubscript()) {\r\n <!-- Helper text and error messages container -->\r\n <div class=\"fui-form-field__subscript-wrapper\">\r\n <!-- Error messages -->\r\n @if (hasError()) {\r\n <div class=\"fui-form-field__error-wrapper fui-animate-slide-in-top\">\r\n <div class=\"fui-form-field__error\" [attr.id]=\"errorId\">\r\n <ng-content select=\"fui-error\"></ng-content>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Hint text -->\r\n <div class=\"fui-form-field__hint-wrapper fui-animate-fade\">\r\n <div class=\"fui-form-field__hint\" [attr.id]=\"hintId\">\r\n <ng-content select=\"fui-hint\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n","import { Component, computed, inject, input, Signal } from '@angular/core';\r\nimport { FuiFormFieldComponent } from './form-field.component';\r\n\r\n/**\r\n * FuiErrorComponent\r\n *\r\n * Validation error message shown under the form field. Can automatically show/hide\r\n * based on a specific error key, or use with *ngIf for custom control logic.\r\n * The component provides proper accessibility roles and live region behavior.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Automatic error key handling -->\r\n * <fui-error key=\"required\">This field is required</fui-error>\r\n * <fui-error key=\"email\">Please enter a valid email</fui-error>\r\n *\r\n * <!-- Manual control (backward compatible) -->\r\n * <fui-error *ngIf=\"control.hasError('custom')\">Custom error</fui-error>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-error',\r\n standalone: true,\r\n template: ` <ng-content></ng-content> `,\r\n host: {\r\n class: 'fui-error',\r\n role: 'alert',\r\n 'aria-live': 'assertive',\r\n '[style.display]': '_shouldHide() ? \"none\" : null',\r\n },\r\n})\r\nexport class FuiErrorComponent {\r\n /**\r\n * Optional error key to match against form control errors.\r\n * When provided, the error will only show if the control has this specific error.\r\n * When not provided, the error will always show (backward compatible behavior).\r\n */\r\n readonly key = input<string>();\r\n\r\n private readonly _parent = inject(FuiFormFieldComponent, { host: true });\r\n\r\n /**\r\n * Computed signal to determine if this error should be hidden\r\n */\r\n protected readonly _shouldHide: Signal<boolean> = computed(() => {\r\n if (!this._parent.control()?.errorState()) {\r\n return true;\r\n }\r\n const errorKey = this.key();\r\n // If no key is provided, always show (backward compatible)\r\n if (!errorKey) {\r\n return false;\r\n }\r\n\r\n // If no form field control is available, show the error\r\n const formFieldControl = this._parent.control();\r\n if (!formFieldControl) {\r\n return false;\r\n }\r\n\r\n // Get the ngControl from the form field control\r\n const ngControl = formFieldControl.ngControl;\r\n if (!ngControl?.control) {\r\n return false;\r\n }\r\n\r\n // Hide if the control doesn't have this specific error\r\n return !ngControl.control.hasError(errorKey);\r\n });\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n/**\r\n * @component FuiHintComponent\r\n * @selector fui-hint\r\n * @description Helper text displayed below the form field input when there is no error.\r\n * Automatically hidden when the parent form field is in an error state.\r\n *\r\n * @example\r\n * <fui-form-field>\r\n * <fui-label>Email</fui-label>\r\n * <input fuiInput type=\"email\">\r\n * <fui-hint>We will never share your email</fui-hint>\r\n * </fui-form-field>\r\n */\r\n@Component({\r\n selector: 'fui-hint',\r\n standalone: true,\r\n template: ` <ng-content></ng-content> `,\r\n host: {\r\n class: 'fui-hint',\r\n },\r\n})\r\nexport class FuiHintComponent {}\r\n","import { Component } from '@angular/core';\r\n\r\n/**\r\n * @component FuiLabelComponent\r\n * @selector fui-label\r\n * @description Label element projected inside `fui-form-field` to provide an accessible\r\n * field label. Automatically linked to the form control via `aria-labelledby`.\r\n *\r\n * @example\r\n * <fui-form-field>\r\n * <fui-label>Email</fui-label>\r\n * <input fuiInput type=\"email\">\r\n * </fui-form-field>\r\n */\r\n@Component({\r\n selector: 'fui-label',\r\n standalone: true,\r\n template: ` <ng-content></ng-content> `,\r\n host: {\r\n class: 'fui-label',\r\n },\r\n})\r\nexport class FuiLabelComponent {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-icon.mjs","sources":["../../../lib/components/icon/icon-config.ts","../../../lib/components/icon/icon.component.ts","../../../lib/components/icon/raintonic-formaui-components-icon.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { FuiIconWeight } from './icon.component';\n\nexport interface FuiIconConfig {\n /** Base URL for the Phosphor Icons CDN */\n cdnBase: string;\n /** SRI hashes per weight. If provided, integrity attribute is added to link elements */\n integrity?: Partial<Record<FuiIconWeight, string>>;\n /** If true, disables automatic CDN loading. Consumer must load icon CSS manually. */\n disableAutoLoad?: boolean;\n}\n\nexport const FUI_ICON_DEFAULT_CONFIG: FuiIconConfig = {\n cdnBase: 'https://unpkg.com/@phosphor-icons/web@2.1.2/src',\n};\n\nexport const FUI_ICON_CONFIG = new InjectionToken<FuiIconConfig>('FUI_ICON_CONFIG', {\n providedIn: 'root',\n factory: () => FUI_ICON_DEFAULT_CONFIG,\n});\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n InputSignal,\n Signal,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { FUI_ICON_CONFIG, FuiIconConfig } from './icon-config';\n\n/**\n * Available icon sizes following Carbon Design System\n */\nexport type FuiIconSize = 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Available icon weights\n */\nexport type FuiIconWeight = 'thin' | 'light' | 'regular' | 'bold' | 'fill';\n\n/**\n * # FuiIcon Component\n *\n * A wrapper component for Phosphor Icons with consistent sizing and styling.\n * Provides easy access to the complete Phosphor Icons library with theme integration.\n *\n * ## Usage\n *\n * ### Basic Icon\n * ```html\n * <fui-icon name=\"heart\"></fui-icon>\n * ```\n */\n@Component({\n selector: 'fui-icon',\n template: '',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'fui-icon',\n '[class]': 'computedClasses()',\n '[style.color]': 'color() || null',\n role: 'img',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-hidden]': 'ariaLabel() ? null : \"true\"',\n },\n})\nexport class FuiIconComponent {\n // Track which phosphor icon weights have been loaded\n private static readonly _loadedWeights = new Set<FuiIconWeight>();\n\n private readonly _config = inject(FUI_ICON_CONFIG);\n private readonly _document = inject(DOCUMENT);\n\n // Inputs using new signal-based API\n name: InputSignal<string> = input.required<string>();\n size: InputSignal<FuiIconSize> = input<FuiIconSize>('md');\n weight: InputSignal<FuiIconWeight> = input<FuiIconWeight>('regular');\n color: InputSignal<string | undefined> = input<string>();\n ariaLabel: InputSignal<string | undefined> = input<string>();\n spin: InputSignal<boolean> = input(false);\n pulse: InputSignal<boolean> = input(false);\n\n // Computed properties\n readonly computedClasses: Signal<string> = computed(() => {\n const classes: string[] = ['fui-icon', `fui-icon--${this.size()}`, `fui-icon--${this.weight()}`, this.iconClass()];\n\n if (this.spin()) {\n classes.push('fui-icon--spin');\n }\n\n if (this.pulse()) {\n classes.push('fui-icon--pulse');\n }\n\n return classes.join(' ');\n });\n\n readonly iconClass: Signal<string> = computed(() => {\n const weight: FuiIconWeight = this.weight();\n const weightSuffix: string = weight === 'regular' ? '' : `-${weight}`;\n return `ph${weightSuffix} ph-${this.name()}`;\n });\n\n constructor() {\n // Watch for weight changes and load the corresponding CSS\n effect(() => {\n const weight = this.weight();\n this._loadPhosphorWeight(weight);\n });\n }\n\n /**\n * Dynamically loads the CSS for a specific Phosphor Icons weight from CDN\n * @param weight The icon weight to load\n */\n private _loadPhosphorWeight(weight: FuiIconWeight): void {\n if (this._config.disableAutoLoad) {\n return;\n }\n\n // Skip if already loaded\n if (FuiIconComponent._loadedWeights.has(weight)) {\n return;\n }\n\n // Check if CSS link already exists in DOM\n const linkId = `phosphor-icons-${weight}`;\n if (this._document.getElementById(linkId)) {\n FuiIconComponent._loadedWeights.add(weight);\n return;\n }\n\n // Create and append the link element\n const link = this._document.createElement('link');\n link.id = linkId;\n link.rel = 'stylesheet';\n link.href = `${this._config.cdnBase}/${weight}/style.css`;\n link.crossOrigin = 'anonymous';\n\n const integrityHash = this._config.integrity?.[weight];\n if (integrityHash) {\n link.integrity = integrityHash;\n }\n\n link.onerror = (): void => {\n console.warn(`[FormaUI] Failed to load Phosphor Icons weight \"${weight}\" from CDN.`);\n FuiIconComponent._loadedWeights.delete(weight);\n };\n\n this._document.head.appendChild(link);\n FuiIconComponent._loadedWeights.add(weight);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAYO,MAAM,uBAAuB,GAAkB;AACpD,IAAA,OAAO,EAAE,iDAAiD;;MAG/C,eAAe,GAAG,IAAI,cAAc,CAAgB,iBAAiB,EAAE;AAClF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,uBAAuB;AACvC,CAAA;;ACID;;;;;;;;;;;;AAYG;MAeU,gBAAgB,CAAA;;AAEnB,IAAA,OAAgB,cAAc,GAAG,IAAI,GAAG,EAAiB;AAEhD,IAAA,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC;AACjC,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;;AAG7C,IAAA,IAAI,GAAwB,KAAK,CAAC,QAAQ,0EAAU;AACpD,IAAA,IAAI,GAA6B,KAAK,CAAc,IAAI,2EAAC;AACzD,IAAA,MAAM,GAA+B,KAAK,CAAgB,SAAS,6EAAC;IACpE,KAAK,GAAoC,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;IACxD,SAAS,GAAoC,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAC5D,IAAA,IAAI,GAAyB,KAAK,CAAC,KAAK,2EAAC;AACzC,IAAA,KAAK,GAAyB,KAAK,CAAC,KAAK,4EAAC;;AAGjC,IAAA,eAAe,GAAmB,QAAQ,CAAC,MAAK;QACvD,MAAM,OAAO,GAAa,CAAC,UAAU,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE,CAAA,CAAE,EAAE,aAAa,IAAI,CAAC,MAAM,EAAE,CAAA,CAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AAElH,QAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;AACf,YAAA,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAChC;AAEA,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC;QACjC;AAEA,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;AAC1B,IAAA,CAAC,sFAAC;AAEO,IAAA,SAAS,GAAmB,QAAQ,CAAC,MAAK;AACjD,QAAA,MAAM,MAAM,GAAkB,IAAI,CAAC,MAAM,EAAE;AAC3C,QAAA,MAAM,YAAY,GAAW,MAAM,KAAK,SAAS,GAAG,EAAE,GAAG,CAAA,CAAA,EAAI,MAAM,EAAE;QACrE,OAAO,CAAA,EAAA,EAAK,YAAY,CAAA,IAAA,EAAO,IAAI,CAAC,IAAI,EAAE,EAAE;AAC9C,IAAA,CAAC,gFAAC;AAEF,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;AAC5B,YAAA,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;AAClC,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;AACK,IAAA,mBAAmB,CAAC,MAAqB,EAAA;AAC/C,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;YAChC;QACF;;QAGA,IAAI,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC/C;QACF;;AAGA,QAAA,MAAM,MAAM,GAAG,CAAA,eAAA,EAAkB,MAAM,EAAE;QACzC,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;AACzC,YAAA,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;YAC3C;QACF;;QAGA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC;AACjD,QAAA,IAAI,CAAC,EAAE,GAAG,MAAM;AAChB,QAAA,IAAI,CAAC,GAAG,GAAG,YAAY;AACvB,QAAA,IAAI,CAAC,IAAI,GAAG,CAAA,EAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAA,CAAA,EAAI,MAAM,CAAA,UAAA,CAAY;AACzD,QAAA,IAAI,CAAC,WAAW,GAAG,WAAW;QAE9B,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;QACtD,IAAI,aAAa,EAAE;AACjB,YAAA,IAAI,CAAC,SAAS,GAAG,aAAa;QAChC;AAEA,QAAA,IAAI,CAAC,OAAO,GAAG,MAAW;AACxB,YAAA,OAAO,CAAC,IAAI,CAAC,mDAAmD,MAAM,CAAA,WAAA,CAAa,CAAC;AACpF,YAAA,gBAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC;AAChD,QAAA,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACrC,QAAA,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;IAC7C;uGArFW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,gBAAgB,ipCAZjB,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,syFAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAYD,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAd5B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,YACV,EAAE,EAAA,eAAA,EAEK,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,KAAK,EAAE,UAAU;AACjB,wBAAA,SAAS,EAAE,mBAAmB;AAC9B,wBAAA,eAAe,EAAE,iBAAiB;AAClC,wBAAA,IAAI,EAAE,KAAK;AACX,wBAAA,mBAAmB,EAAE,qBAAqB;AAC1C,wBAAA,oBAAoB,EAAE,6BAA6B;AACpD,qBAAA,EAAA,MAAA,EAAA,CAAA,syFAAA,CAAA,EAAA;;;AChDH;;AAEG;;;;"}
1
+ {"version":3,"file":"raintonic-formaui-components-icon.mjs","sources":["../../../lib/components/icon/icon-config.ts","../../../lib/components/icon/icon.component.ts","../../../lib/components/icon/raintonic-formaui-components-icon.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\nimport { FuiIconWeight } from './icon.component';\r\n\r\nexport interface FuiIconConfig {\r\n /** Base URL for the Phosphor Icons CDN */\r\n cdnBase: string;\r\n /** SRI hashes per weight. If provided, integrity attribute is added to link elements */\r\n integrity?: Partial<Record<FuiIconWeight, string>>;\r\n /** If true, disables automatic CDN loading. Consumer must load icon CSS manually. */\r\n disableAutoLoad?: boolean;\r\n}\r\n\r\nexport const FUI_ICON_DEFAULT_CONFIG: FuiIconConfig = {\r\n cdnBase: 'https://unpkg.com/@phosphor-icons/web@2.1.2/src',\r\n};\r\n\r\nexport const FUI_ICON_CONFIG = new InjectionToken<FuiIconConfig>('FUI_ICON_CONFIG', {\r\n providedIn: 'root',\r\n factory: () => FUI_ICON_DEFAULT_CONFIG,\r\n});\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n InputSignal,\r\n Signal,\r\n} from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FUI_ICON_CONFIG, FuiIconConfig } from './icon-config';\r\n\r\n/**\r\n * Available icon sizes following Carbon Design System\r\n */\r\nexport type FuiIconSize = 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * Available icon weights\r\n */\r\nexport type FuiIconWeight = 'thin' | 'light' | 'regular' | 'bold' | 'fill';\r\n\r\n/**\r\n * # FuiIcon Component\r\n *\r\n * A wrapper component for Phosphor Icons with consistent sizing and styling.\r\n * Provides easy access to the complete Phosphor Icons library with theme integration.\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Icon\r\n * ```html\r\n * <fui-icon name=\"heart\"></fui-icon>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-icon',\r\n template: '',\r\n styleUrls: ['./icon.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'fui-icon',\r\n '[class]': 'computedClasses()',\r\n '[style.color]': 'color() || null',\r\n role: 'img',\r\n '[attr.aria-label]': 'ariaLabel() || null',\r\n '[attr.aria-hidden]': 'ariaLabel() ? null : \"true\"',\r\n },\r\n})\r\nexport class FuiIconComponent {\r\n // Track which phosphor icon weights have been loaded\r\n private static readonly _loadedWeights = new Set<FuiIconWeight>();\r\n\r\n private readonly _config = inject(FUI_ICON_CONFIG);\r\n private readonly _document = inject(DOCUMENT);\r\n\r\n // Inputs using new signal-based API\r\n name: InputSignal<string> = input.required<string>();\r\n size: InputSignal<FuiIconSize> = input<FuiIconSize>('md');\r\n weight: InputSignal<FuiIconWeight> = input<FuiIconWeight>('regular');\r\n color: InputSignal<string | undefined> = input<string>();\r\n ariaLabel: InputSignal<string | undefined> = input<string>();\r\n spin: InputSignal<boolean> = input(false);\r\n pulse: InputSignal<boolean> = input(false);\r\n\r\n // Computed properties\r\n readonly computedClasses: Signal<string> = computed(() => {\r\n const classes: string[] = ['fui-icon', `fui-icon--${this.size()}`, `fui-icon--${this.weight()}`, this.iconClass()];\r\n\r\n if (this.spin()) {\r\n classes.push('fui-icon--spin');\r\n }\r\n\r\n if (this.pulse()) {\r\n classes.push('fui-icon--pulse');\r\n }\r\n\r\n return classes.join(' ');\r\n });\r\n\r\n readonly iconClass: Signal<string> = computed(() => {\r\n const weight: FuiIconWeight = this.weight();\r\n const weightSuffix: string = weight === 'regular' ? '' : `-${weight}`;\r\n return `ph${weightSuffix} ph-${this.name()}`;\r\n });\r\n\r\n constructor() {\r\n // Watch for weight changes and load the corresponding CSS\r\n effect(() => {\r\n const weight = this.weight();\r\n this._loadPhosphorWeight(weight);\r\n });\r\n }\r\n\r\n /**\r\n * Dynamically loads the CSS for a specific Phosphor Icons weight from CDN\r\n * @param weight The icon weight to load\r\n */\r\n private _loadPhosphorWeight(weight: FuiIconWeight): void {\r\n if (this._config.disableAutoLoad) {\r\n return;\r\n }\r\n\r\n // Skip if already loaded\r\n if (FuiIconComponent._loadedWeights.has(weight)) {\r\n return;\r\n }\r\n\r\n // Check if CSS link already exists in DOM\r\n const linkId = `phosphor-icons-${weight}`;\r\n if (this._document.getElementById(linkId)) {\r\n FuiIconComponent._loadedWeights.add(weight);\r\n return;\r\n }\r\n\r\n // Create and append the link element\r\n const link = this._document.createElement('link');\r\n link.id = linkId;\r\n link.rel = 'stylesheet';\r\n link.href = `${this._config.cdnBase}/${weight}/style.css`;\r\n link.crossOrigin = 'anonymous';\r\n\r\n const integrityHash = this._config.integrity?.[weight];\r\n if (integrityHash) {\r\n link.integrity = integrityHash;\r\n }\r\n\r\n link.onerror = (): void => {\r\n console.warn(`[FormaUI] Failed to load Phosphor Icons weight \"${weight}\" from CDN.`);\r\n FuiIconComponent._loadedWeights.delete(weight);\r\n };\r\n\r\n this._document.head.appendChild(link);\r\n FuiIconComponent._loadedWeights.add(weight);\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-input.mjs","sources":["../../../lib/components/input/input.directive.ts","../../../lib/components/input/raintonic-formaui-components-input.ts"],"sourcesContent":["import {\n computed,\n Directive,\n DoCheck,\n effect,\n ElementRef,\n HostListener,\n inject,\n input,\n InputSignal,\n OnDestroy,\n output,\n OutputEmitterRef,\n signal,\n WritableSignal,\n} from '@angular/core';\n\nimport { ControlValueAccessor, FormGroupDirective, NG_VALUE_ACCESSOR, NgControl, NgForm } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\n\n/**\n * Available input types\n */\nexport type FuiInputType =\n | 'text'\n | 'email'\n | 'password'\n | 'number'\n | 'tel'\n | 'url'\n | 'search'\n | 'date'\n | 'time'\n | 'datetime-local';\n\n/**\n * # FuiInput Directive\n *\n * An input directive that integrates seamlessly with fui-form-field and Angular Forms.\n * Follows Angular Material patterns with Carbon Design System styling.\n *\n * ## Features\n * - Full integration with fui-form-field\n * - Reactive Forms and Template-driven Forms support\n * - Multiple input types support\n * - Error state handling with customizable error messages\n * - Accessibility features (ARIA attributes, labels)\n * - Smooth animations and transitions\n * - Theme-aware styling\n *\n * ## Usage\n *\n * ### Basic Input with Form Field\n * ```html\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\" placeholder=\"Enter your email\">\n * </fui-form-field>\n * ```\n *\n * ### With Reactive Forms\n * ```html\n * <fui-form-field>\n * <fui-label>Username</fui-label>\n * <input fuiInput formControlName=\"username\">\n * <fui-error *ngIf=\"form.get('username')?.hasError('required')\">\n * Username is required\n * </fui-error>\n * </fui-form-field>\n * ```\n *\n * ### Password Input with Toggle\n * ```html\n * <fui-form-field>\n * <fui-label>Password</fui-label>\n * <input fuiInput [type]=\"showPassword ? 'text' : 'password'\">\n * <button fuiSuffix fuiButton variant=\"ghost\" (click)=\"togglePassword()\">\n * <fui-icon [name]=\"showPassword ? 'eye-slash' : 'eye'\"></fui-icon>\n * </button>\n * </fui-form-field>\n * ```\n *\n * @example\n * ```typescript\n * import { FuiInputDirective } from '@raintonic/formaui/components/input';\n * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';\n *\n * @Component({\n * standalone: true,\n * imports: [FuiInputDirective, FuiFormFieldComponent, ReactiveFormsModule],\n * template: `\n * <form [formGroup]=\"form\">\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\" formControlName=\"email\">\n * <fui-error *ngIf=\"emailControl?.invalid && emailControl?.touched\">\n * Please enter a valid email\n * </fui-error>\n * </fui-form-field>\n * </form>\n * `\n * })\n * export class MyFormComponent {\n * form = this.fb.group({\n * email: ['', [Validators.required, Validators.email]]\n * });\n *\n * get emailControl() {\n * return this.form.get('email');\n * }\n * }\n * ```\n */\n@Directive({\n selector: 'input[fuiInput], textarea[fuiInput], select[fuiInput]',\n standalone: true,\n host: {\n class: 'fui-input',\n '[class.fui-input--select]': 'isSelect()',\n '[class.fui-input--disabled]': 'disabled()',\n '[class.fui-input--readonly]': 'readonly()',\n '[class.fui-input--error]': 'errorState()',\n '[attr.id]': 'id',\n '[attr.type]': 'type()',\n '[attr.placeholder]': 'placeholder()',\n '[attr.disabled]': 'disabled() ? \"\" : null',\n '[attr.readonly]': 'readonly() ? \"\" : null',\n '[attr.required]': 'required() ? \"\" : null',\n // constraints\n '[attr.maxlength]': 'maxlength()',\n '[attr.minlength]': 'minlength()',\n '[attr.pattern]': 'pattern()',\n // ARIA\n '[attr.aria-invalid]': 'errorState() ? \"true\" : null',\n '[attr.aria-required]': 'required() ? \"true\" : null',\n '[attr.aria-describedby]': '_ariaDescribedby',\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n '[attr.aria-readonly]': 'readonly() ? \"true\" : null',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: FuiInputDirective,\n multi: true,\n },\n {\n provide: FUI_FORM_FIELD_CONTROL,\n useExisting: FuiInputDirective,\n },\n ],\n})\nexport class FuiInputDirective implements ControlValueAccessor, FuiFormFieldControl<string>, DoCheck, OnDestroy {\n // Static properties\n static nextId = 0;\n readonly controlType = 'fui-input';\n\n // Inputs\n type: InputSignal<FuiInputType> = input<FuiInputType>('text');\n placeholder: InputSignal<string> = input('');\n\n readonly: InputSignal<boolean> = input(false);\n\n // Validation/constraint inputs (pass-through to native attributes)\n maxlength: InputSignal<number | null> = input<number | null>(null);\n minlength: InputSignal<number | null> = input<number | null>(null);\n pattern: InputSignal<string | null> = input<string | null>(null);\n\n // Interface implementation\n required: WritableSignal<boolean> = signal(false);\n\n errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\n readonly disabledInput: InputSignal<boolean> = input(false);\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\n\n // Outputs\n readonly valueChange: OutputEmitterRef<string> = output<string>();\n\n // Internal state\n private readonly _focused: WritableSignal<boolean> = signal(false);\n readonly focused = this._focused;\n readonly stateChanges = new Subject<void>();\n\n private readonly _value: WritableSignal<string> = signal('');\n readonly value = this._value;\n private readonly _disabled: WritableSignal<boolean> = signal(false);\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\n private _uid = `fui-input-${FuiInputDirective.nextId++}`;\n _ariaDescribedby: string | null = null;\n\n // Error state\n private readonly _errorState: WritableSignal<boolean> = signal(false);\n readonly errorState = this._errorState;\n\n // Form control references\n private _parentForm = inject(NgForm, { optional: true });\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\n\n // Element reference\n private readonly _elementRef: ElementRef<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> =\n inject(ElementRef);\n\n // Computed properties\n readonly empty = computed(() => {\n const v = this._value();\n return !v || v.length === 0;\n });\n readonly id = this._uid;\n\n // ControlValueAccessor callbacks\n private _onChange: (value: string) => void = () => {\n /* noop */\n };\n private _onTouched: () => void = () => {\n /* noop */\n };\n\n private readonly _ngControlRef = injectNgControl();\n\n get ngControl(): NgControl | null {\n return this._ngControlRef.ngControl;\n }\n\n constructor() {\n // Set valueAccessor after NgControl is resolved\n void Promise.resolve().then(() => {\n if (this._ngControlRef.ngControl) {\n this._ngControlRef.ngControl.valueAccessor = this;\n }\n });\n\n // Effect to emit state changes\n effect(() => {\n // Track all reactive inputs and internal signals\n this.type();\n this.placeholder();\n this.readonly();\n this.maxlength();\n this.minlength();\n this.pattern();\n this.disabledInput();\n this.errorStateMatcher();\n this._focused();\n this._value();\n this._disabled();\n this._ngControlDisabled();\n this.required();\n this._errorState();\n\n // Emit state change\n this.stateChanges.next();\n });\n }\n\n ngDoCheck(): void {\n if (this.ngControl) {\n updateErrorState(\n this.ngControl,\n this._errorState,\n this.errorStateMatcher(),\n this._defaultErrorStateMatcher,\n this._parentForm,\n this._parentFormGroup,\n this.stateChanges,\n );\n syncRequiredState(this.ngControl, this.required, this.stateChanges);\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\n }\n }\n\n ngOnDestroy(): void {\n this.stateChanges.complete();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n const v = value ?? '';\n this._value.set(v);\n // Update the DOM element's value to reflect the new value\n this._elementRef.nativeElement.value = v;\n this.stateChanges.next();\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled.set(isDisabled);\n this.stateChanges.next();\n }\n\n onContainerClick(_event: MouseEvent): void {\n if (!this._focused()) {\n this._elementRef.nativeElement.focus();\n }\n }\n\n setDescribedByIds(ids: string[]): void {\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\n }\n\n // Event handlers\n @HostListener('input', ['$event'])\n onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n const newValue = target.value;\n if (newValue !== this._value()) {\n this._value.set(newValue);\n this._onChange(newValue);\n this.valueChange.emit(newValue);\n this.stateChanges.next();\n }\n }\n\n @HostListener('change', ['$event'])\n onChange(event: Event): void {\n // Handle change event for select elements\n if (this.isSelect()) {\n const target = event.target as HTMLSelectElement;\n const newValue = target.value;\n if (newValue !== this._value()) {\n this._value.set(newValue);\n this._onChange(newValue);\n this.valueChange.emit(newValue);\n this.stateChanges.next();\n }\n }\n }\n\n @HostListener('focus')\n onFocus(): void {\n if (!this._focused()) {\n this._focused.set(true);\n this.stateChanges.next();\n }\n }\n\n @HostListener('blur')\n onBlur(): void {\n if (this._focused()) {\n this._focused.set(false);\n this._onTouched();\n this.stateChanges.next();\n }\n }\n\n // Public API\n focus(): void {\n this._elementRef.nativeElement.focus();\n }\n\n blur(): void {\n this._elementRef.nativeElement.blur();\n }\n\n /**\n * Check if the element is a select element\n */\n isSelect(): boolean {\n return this._elementRef.nativeElement.tagName.toLowerCase() === 'select';\n }\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":"raintonic-formaui-components-input.mjs","sources":["../../../lib/components/input/input.directive.ts","../../../lib/components/input/raintonic-formaui-components-input.ts"],"sourcesContent":["import {\r\n computed,\r\n Directive,\r\n DoCheck,\r\n effect,\r\n ElementRef,\r\n HostListener,\r\n inject,\r\n input,\r\n InputSignal,\r\n OnDestroy,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n WritableSignal,\r\n} from '@angular/core';\r\n\r\nimport { ControlValueAccessor, FormGroupDirective, NG_VALUE_ACCESSOR, NgControl, NgForm } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\r\n\r\n/**\r\n * Available input types\r\n */\r\nexport type FuiInputType =\r\n | 'text'\r\n | 'email'\r\n | 'password'\r\n | 'number'\r\n | 'tel'\r\n | 'url'\r\n | 'search'\r\n | 'date'\r\n | 'time'\r\n | 'datetime-local';\r\n\r\n/**\r\n * # FuiInput Directive\r\n *\r\n * An input directive that integrates seamlessly with fui-form-field and Angular Forms.\r\n * Follows Angular Material patterns with Carbon Design System styling.\r\n *\r\n * ## Features\r\n * - Full integration with fui-form-field\r\n * - Reactive Forms and Template-driven Forms support\r\n * - Multiple input types support\r\n * - Error state handling with customizable error messages\r\n * - Accessibility features (ARIA attributes, labels)\r\n * - Smooth animations and transitions\r\n * - Theme-aware styling\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Input with Form Field\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Email</fui-label>\r\n * <input fuiInput type=\"email\" placeholder=\"Enter your email\">\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Reactive Forms\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Username</fui-label>\r\n * <input fuiInput formControlName=\"username\">\r\n * <fui-error *ngIf=\"form.get('username')?.hasError('required')\">\r\n * Username is required\r\n * </fui-error>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### Password Input with Toggle\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Password</fui-label>\r\n * <input fuiInput [type]=\"showPassword ? 'text' : 'password'\">\r\n * <button fuiSuffix fuiButton variant=\"ghost\" (click)=\"togglePassword()\">\r\n * <fui-icon [name]=\"showPassword ? 'eye-slash' : 'eye'\"></fui-icon>\r\n * </button>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * import { FuiInputDirective } from '@raintonic/formaui/components/input';\r\n * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';\r\n *\r\n * @Component({\r\n * standalone: true,\r\n * imports: [FuiInputDirective, FuiFormFieldComponent, ReactiveFormsModule],\r\n * template: `\r\n * <form [formGroup]=\"form\">\r\n * <fui-form-field>\r\n * <fui-label>Email</fui-label>\r\n * <input fuiInput type=\"email\" formControlName=\"email\">\r\n * <fui-error *ngIf=\"emailControl?.invalid && emailControl?.touched\">\r\n * Please enter a valid email\r\n * </fui-error>\r\n * </fui-form-field>\r\n * </form>\r\n * `\r\n * })\r\n * export class MyFormComponent {\r\n * form = this.fb.group({\r\n * email: ['', [Validators.required, Validators.email]]\r\n * });\r\n *\r\n * get emailControl() {\r\n * return this.form.get('email');\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Directive({\r\n selector: 'input[fuiInput], textarea[fuiInput], select[fuiInput]',\r\n standalone: true,\r\n host: {\r\n class: 'fui-input',\r\n '[class.fui-input--select]': 'isSelect()',\r\n '[class.fui-input--disabled]': 'disabled()',\r\n '[class.fui-input--readonly]': 'readonly()',\r\n '[class.fui-input--error]': 'errorState()',\r\n '[attr.id]': 'id',\r\n '[attr.type]': 'type()',\r\n '[attr.placeholder]': 'placeholder()',\r\n '[attr.disabled]': 'disabled() ? \"\" : null',\r\n '[attr.readonly]': 'readonly() ? \"\" : null',\r\n '[attr.required]': 'required() ? \"\" : null',\r\n // constraints\r\n '[attr.maxlength]': 'maxlength()',\r\n '[attr.minlength]': 'minlength()',\r\n '[attr.pattern]': 'pattern()',\r\n // ARIA\r\n '[attr.aria-invalid]': 'errorState() ? \"true\" : null',\r\n '[attr.aria-required]': 'required() ? \"true\" : null',\r\n '[attr.aria-describedby]': '_ariaDescribedby',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '[attr.aria-readonly]': 'readonly() ? \"true\" : null',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiInputDirective,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiInputDirective,\r\n },\r\n ],\r\n})\r\nexport class FuiInputDirective implements ControlValueAccessor, FuiFormFieldControl<string>, DoCheck, OnDestroy {\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-input';\r\n\r\n // Inputs\r\n type: InputSignal<FuiInputType> = input<FuiInputType>('text');\r\n placeholder: InputSignal<string> = input('');\r\n\r\n readonly: InputSignal<boolean> = input(false);\r\n\r\n // Validation/constraint inputs (pass-through to native attributes)\r\n maxlength: InputSignal<number | null> = input<number | null>(null);\r\n minlength: InputSignal<number | null> = input<number | null>(null);\r\n pattern: InputSignal<string | null> = input<string | null>(null);\r\n\r\n // Interface implementation\r\n required: WritableSignal<boolean> = signal(false);\r\n\r\n errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\r\n readonly disabledInput: InputSignal<boolean> = input(false);\r\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\r\n\r\n // Outputs\r\n readonly valueChange: OutputEmitterRef<string> = output<string>();\r\n\r\n // Internal state\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n readonly focused = this._focused;\r\n readonly stateChanges = new Subject<void>();\r\n\r\n private readonly _value: WritableSignal<string> = signal('');\r\n readonly value = this._value;\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n private _uid = `fui-input-${FuiInputDirective.nextId++}`;\r\n _ariaDescribedby: string | null = null;\r\n\r\n // Error state\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n readonly errorState = this._errorState;\r\n\r\n // Form control references\r\n private _parentForm = inject(NgForm, { optional: true });\r\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\r\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\r\n\r\n // Element reference\r\n private readonly _elementRef: ElementRef<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> =\r\n inject(ElementRef);\r\n\r\n // Computed properties\r\n readonly empty = computed(() => {\r\n const v = this._value();\r\n return !v || v.length === 0;\r\n });\r\n readonly id = this._uid;\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: string) => void = () => {\r\n /* noop */\r\n };\r\n private _onTouched: () => void = () => {\r\n /* noop */\r\n };\r\n\r\n private readonly _ngControlRef = injectNgControl();\r\n\r\n get ngControl(): NgControl | null {\r\n return this._ngControlRef.ngControl;\r\n }\r\n\r\n constructor() {\r\n // Set valueAccessor after NgControl is resolved\r\n void Promise.resolve().then(() => {\r\n if (this._ngControlRef.ngControl) {\r\n this._ngControlRef.ngControl.valueAccessor = this;\r\n }\r\n });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n // Track all reactive inputs and internal signals\r\n this.type();\r\n this.placeholder();\r\n this.readonly();\r\n this.maxlength();\r\n this.minlength();\r\n this.pattern();\r\n this.disabledInput();\r\n this.errorStateMatcher();\r\n this._focused();\r\n this._value();\r\n this._disabled();\r\n this._ngControlDisabled();\r\n this.required();\r\n this._errorState();\r\n\r\n // Emit state change\r\n this.stateChanges.next();\r\n });\r\n }\r\n\r\n ngDoCheck(): void {\r\n if (this.ngControl) {\r\n updateErrorState(\r\n this.ngControl,\r\n this._errorState,\r\n this.errorStateMatcher(),\r\n this._defaultErrorStateMatcher,\r\n this._parentForm,\r\n this._parentFormGroup,\r\n this.stateChanges,\r\n );\r\n syncRequiredState(this.ngControl, this.required, this.stateChanges);\r\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: string | null): void {\r\n const v = value ?? '';\r\n this._value.set(v);\r\n // Update the DOM element's value to reflect the new value\r\n this._elementRef.nativeElement.value = v;\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: string) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this._disabled.set(isDisabled);\r\n this.stateChanges.next();\r\n }\r\n\r\n onContainerClick(_event: MouseEvent): void {\r\n if (!this._focused()) {\r\n this._elementRef.nativeElement.focus();\r\n }\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n }\r\n\r\n // Event handlers\r\n @HostListener('input', ['$event'])\r\n onInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const newValue = target.value;\r\n if (newValue !== this._value()) {\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n @HostListener('change', ['$event'])\r\n onChange(event: Event): void {\r\n // Handle change event for select elements\r\n if (this.isSelect()) {\r\n const target = event.target as HTMLSelectElement;\r\n const newValue = target.value;\r\n if (newValue !== this._value()) {\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.stateChanges.next();\r\n }\r\n }\r\n }\r\n\r\n @HostListener('focus')\r\n onFocus(): void {\r\n if (!this._focused()) {\r\n this._focused.set(true);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n @HostListener('blur')\r\n onBlur(): void {\r\n if (this._focused()) {\r\n this._focused.set(false);\r\n this._onTouched();\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n // Public API\r\n focus(): void {\r\n this._elementRef.nativeElement.focus();\r\n }\r\n\r\n blur(): void {\r\n this._elementRef.nativeElement.blur();\r\n }\r\n\r\n /**\r\n * Check if the element is a select element\r\n */\r\n isSelect(): boolean {\r\n return this._elementRef.nativeElement.tagName.toLowerCase() === 'select';\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@ class FuiListItemComponent {
25
25
  this.onClick();
26
26
  }
27
27
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
28
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.6", type: FuiListItemComponent, isStandalone: true, selector: "fui-list-item", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown.enter": "onClick()", "keydown.space": "onSpace($event)" }, properties: { "class.fui-list-item--selected": "_selected()", "class.fui-list-item--disabled": "disabled()", "class.fui-list-item--interactive": "_isInteractive()", "attr.role": "_role()", "attr.aria-selected": "_isSelectable() ? _selected() : null", "attr.aria-disabled": "disabled() || null", "attr.tabindex": "_isInteractive() ? 0 : null" }, classAttribute: "fui-list-item" }, ngImport: i0, template: "<div class=\"fui-list-item__content\">\n <div class=\"fui-list-item__start\">\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\n </div>\n <div class=\"fui-list-item__text\">\n <ng-content></ng-content>\n </div>\n <div class=\"fui-list-item__end\">\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\n </div>\n</div>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
28
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.6", type: FuiListItemComponent, isStandalone: true, selector: "fui-list-item", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown.enter": "onClick()", "keydown.space": "onSpace($event)" }, properties: { "class.fui-list-item--selected": "_selected()", "class.fui-list-item--disabled": "disabled()", "class.fui-list-item--interactive": "_isInteractive()", "attr.role": "_role()", "attr.aria-selected": "_isSelectable() ? _selected() : null", "attr.aria-disabled": "disabled() || null", "attr.tabindex": "_isInteractive() ? 0 : null" }, classAttribute: "fui-list-item" }, ngImport: i0, template: "<div class=\"fui-list-item__content\">\r\n <div class=\"fui-list-item__start\">\r\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__text\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__end\">\r\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
29
29
  }
30
30
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiListItemComponent, decorators: [{
31
31
  type: Component,
@@ -41,7 +41,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
41
41
  '(click)': 'onClick()',
42
42
  '(keydown.enter)': 'onClick()',
43
43
  '(keydown.space)': 'onSpace($event)',
44
- }, template: "<div class=\"fui-list-item__content\">\n <div class=\"fui-list-item__start\">\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\n </div>\n <div class=\"fui-list-item__text\">\n <ng-content></ng-content>\n </div>\n <div class=\"fui-list-item__end\">\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\n </div>\n</div>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"] }]
44
+ }, template: "<div class=\"fui-list-item__content\">\r\n <div class=\"fui-list-item__start\">\r\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__text\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__end\">\r\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"] }]
45
45
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
46
46
 
47
47
  class FuiListComponent {
@@ -127,7 +127,7 @@ class FuiListComponent {
127
127
  }
128
128
  }
129
129
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
130
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.6", type: FuiListComponent, isStandalone: true, selector: "fui-list", inputs: { interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, dividers: { classPropertyName: "dividers", publicName: "dividers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.fui-list--interactive": "interactive() || selectionMode() !== \"none\"", "class.fui-list--dividers": "dividers()", "attr.role": "selectionMode() !== \"none\" ? \"listbox\" : \"list\"", "attr.aria-multiselectable": "selectionMode() === \"multi\" ? true : null" }, classAttribute: "fui-list" }, providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }], queries: [{ propertyName: "items", predicate: FuiListItemComponent, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.6", type: FuiListComponent, isStandalone: true, selector: "fui-list", inputs: { interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, dividers: { classPropertyName: "dividers", publicName: "dividers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.fui-list--interactive": "interactive() || selectionMode() !== \"none\"", "class.fui-list--dividers": "dividers()", "attr.role": "selectionMode() !== \"none\" ? \"listbox\" : \"list\"", "attr.aria-multiselectable": "selectionMode() === \"multi\" ? true : null" }, classAttribute: "fui-list" }, providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }], queries: [{ propertyName: "items", predicate: FuiListItemComponent, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
131
131
  }
132
132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiListComponent, decorators: [{
133
133
  type: Component,
@@ -138,7 +138,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
138
138
  '[attr.role]': 'selectionMode() !== "none" ? "listbox" : "list"',
139
139
  '[attr.aria-multiselectable]': 'selectionMode() === "multi" ? true : null',
140
140
  '(keydown)': 'onKeydown($event)',
141
- }, providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }], template: "<ng-content></ng-content>\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"] }]
141
+ }, providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }], template: "<ng-content></ng-content>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}.fui-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.fui-list--dividers .fui-list-item+.fui-list-item{border-top:1px solid var(--fui-border-color)}.fui-list-item{display:flex;align-items:center;padding:var(--fui-gap-12, .75rem) var(--fui-gap-16, 1rem)}.fui-list-item__content{display:flex;align-items:center;width:100%;gap:var(--fui-gap-12, .75rem)}.fui-list-item__start{flex-shrink:0}.fui-list-item__text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fui-list-item__end{flex-shrink:0;margin-left:auto}.fui-list-item--interactive{cursor:pointer;transition:background-color var(--fui-duration-fast-02, .15s) var(--fui-ease-standard) 0ms}.fui-list-item--interactive:hover{background-color:var(--fui-surface-02, #f1f5f9)}.fui-list-item--interactive:active{background-color:var(--fui-surface-03, #e2e8f0)}.fui-list-item--interactive:focus-visible{outline:2px solid var(--fui-primary);outline-offset:0px}.fui-list-item--selected{background-color:var(--fui-primary-10, #f0e6ff);color:var(--fui-primary)}.fui-list-item--disabled{opacity:var(--fui-opacity-disabled, .38);cursor:not-allowed;pointer-events:none}@media(prefers-contrast:high){.fui-list--dividers .fui-list-item+.fui-list-item{border-color:CanvasText}}\n"] }]
142
142
  }], propDecorators: { interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], dividers: [{ type: i0.Input, args: [{ isSignal: true, alias: "dividers", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FuiListItemComponent), { isSignal: true }] }] } });
143
143
 
144
144
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-list.mjs","sources":["../../../lib/components/list/list.types.ts","../../../lib/components/list/list-item.component.ts","../../../lib/components/list/list-item.component.html","../../../lib/components/list/list.component.ts","../../../lib/components/list/list.component.html","../../../lib/components/list/raintonic-formaui-components-list.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport type FuiListSelectionMode = 'none' | 'single' | 'multi';\n\nexport interface FuiListSelectionChange<T = unknown> {\n source: unknown;\n value: T[];\n}\n\nexport interface FuiListHost {\n interactive(): boolean;\n selectionMode(): FuiListSelectionMode;\n selectItem(item: unknown): void;\n}\n\nexport const FUI_LIST = new InjectionToken<FuiListHost>('FUI_LIST');\n","import {\n Component,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n input,\n computed,\n signal,\n inject,\n ElementRef,\n booleanAttribute,\n} from '@angular/core';\nimport { FUI_LIST } from './list.types';\n\n@Component({\n selector: 'fui-list-item',\n standalone: true,\n imports: [],\n templateUrl: './list-item.component.html',\n styleUrls: ['./list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-list-item',\n '[class.fui-list-item--selected]': '_selected()',\n '[class.fui-list-item--disabled]': 'disabled()',\n '[class.fui-list-item--interactive]': '_isInteractive()',\n '[attr.role]': '_role()',\n '[attr.aria-selected]': '_isSelectable() ? _selected() : null',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.tabindex]': '_isInteractive() ? 0 : null',\n '(click)': 'onClick()',\n '(keydown.enter)': 'onClick()',\n '(keydown.space)': 'onSpace($event)',\n },\n})\nexport class FuiListItemComponent {\n readonly value = input<unknown>(undefined);\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\n\n readonly _selected = signal(false);\n readonly _focused = signal(false);\n\n readonly _elementRef = inject(ElementRef);\n\n private _list = inject(FUI_LIST, { optional: true });\n\n readonly _isInteractive = computed(\n () => (this._list?.interactive() ?? this._list?.selectionMode() !== 'none') && !this.disabled(),\n );\n readonly _isSelectable = computed(() => this._list?.selectionMode() !== 'none');\n readonly _role = computed(() => (this._isSelectable() ? 'option' : 'listitem'));\n\n onClick(): void {\n if (this.disabled() || !this._list) return;\n if (this._isSelectable()) {\n this._list.selectItem(this);\n }\n }\n\n onSpace(event: Event): void {\n event.preventDefault();\n this.onClick();\n }\n}\n","<div class=\"fui-list-item__content\">\n <div class=\"fui-list-item__start\">\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\n </div>\n <div class=\"fui-list-item__text\">\n <ng-content></ng-content>\n </div>\n <div class=\"fui-list-item__end\">\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\n </div>\n</div>\n","import {\n Component,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n input,\n output,\n signal,\n contentChildren,\n} from '@angular/core';\nimport { FuiListSelectionMode, FuiListSelectionChange, FUI_LIST } from './list.types';\nimport { FuiListItemComponent } from './list-item.component';\n\n@Component({\n selector: 'fui-list',\n standalone: true,\n imports: [],\n templateUrl: './list.component.html',\n styleUrls: ['./list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'fui-list',\n '[class.fui-list--interactive]': 'interactive() || selectionMode() !== \"none\"',\n '[class.fui-list--dividers]': 'dividers()',\n '[attr.role]': 'selectionMode() !== \"none\" ? \"listbox\" : \"list\"',\n '[attr.aria-multiselectable]': 'selectionMode() === \"multi\" ? true : null',\n '(keydown)': 'onKeydown($event)',\n },\n providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }],\n})\nexport class FuiListComponent {\n readonly interactive = input(false);\n readonly selectionMode = input<FuiListSelectionMode>('none');\n readonly dividers = input(false);\n\n readonly selectionChange = output<FuiListSelectionChange>();\n\n readonly items = contentChildren(FuiListItemComponent);\n\n readonly _selectedValues = signal(new Set());\n\n selectItem(item: FuiListItemComponent): void {\n if (item.disabled()) return;\n const mode = this.selectionMode();\n if (mode === 'none') return;\n\n const currentSet = new Set(this._selectedValues());\n const value = item.value();\n\n if (mode === 'single') {\n currentSet.clear();\n currentSet.add(value);\n } else {\n // multi\n if (currentSet.has(value)) {\n currentSet.delete(value);\n } else {\n currentSet.add(value);\n }\n }\n\n this._selectedValues.set(currentSet);\n\n // Update all items' selected state\n this.items().forEach((i) => {\n i._selected.set(currentSet.has(i.value()));\n });\n\n this.selectionChange.emit({\n source: this,\n value: Array.from(currentSet),\n });\n }\n\n isSelected(value: unknown): boolean {\n return this._selectedValues().has(value);\n }\n\n onKeydown(event: KeyboardEvent): void {\n const items = this.items();\n if (items.length === 0) return;\n\n const enabledItems = items.filter((i) => !i.disabled());\n if (enabledItems.length === 0) return;\n\n const focusedEl = document.activeElement;\n const currentIdx = enabledItems.findIndex(\n (i) => i._elementRef.nativeElement === focusedEl || i._elementRef.nativeElement.contains(focusedEl),\n );\n\n let targetIdx = -1;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n targetIdx = currentIdx < enabledItems.length - 1 ? currentIdx + 1 : 0;\n break;\n case 'ArrowUp':\n event.preventDefault();\n targetIdx = currentIdx > 0 ? currentIdx - 1 : enabledItems.length - 1;\n break;\n case 'Home':\n event.preventDefault();\n targetIdx = 0;\n break;\n case 'End':\n event.preventDefault();\n targetIdx = enabledItems.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (currentIdx >= 0) {\n this.selectItem(enabledItems[currentIdx]);\n }\n return;\n default:\n return;\n }\n\n if (targetIdx >= 0) {\n enabledItems[targetIdx]._elementRef.nativeElement.focus();\n }\n }\n}\n","<ng-content></ng-content>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"raintonic-formaui-components-list.mjs","sources":["../../../lib/components/list/list.types.ts","../../../lib/components/list/list-item.component.ts","../../../lib/components/list/list-item.component.html","../../../lib/components/list/list.component.ts","../../../lib/components/list/list.component.html","../../../lib/components/list/raintonic-formaui-components-list.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\n\r\nexport type FuiListSelectionMode = 'none' | 'single' | 'multi';\r\n\r\nexport interface FuiListSelectionChange<T = unknown> {\r\n source: unknown;\r\n value: T[];\r\n}\r\n\r\nexport interface FuiListHost {\r\n interactive(): boolean;\r\n selectionMode(): FuiListSelectionMode;\r\n selectItem(item: unknown): void;\r\n}\r\n\r\nexport const FUI_LIST = new InjectionToken<FuiListHost>('FUI_LIST');\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n computed,\r\n signal,\r\n inject,\r\n ElementRef,\r\n booleanAttribute,\r\n} from '@angular/core';\r\nimport { FUI_LIST } from './list.types';\r\n\r\n@Component({\r\n selector: 'fui-list-item',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './list-item.component.html',\r\n styleUrls: ['./list.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-list-item',\r\n '[class.fui-list-item--selected]': '_selected()',\r\n '[class.fui-list-item--disabled]': 'disabled()',\r\n '[class.fui-list-item--interactive]': '_isInteractive()',\r\n '[attr.role]': '_role()',\r\n '[attr.aria-selected]': '_isSelectable() ? _selected() : null',\r\n '[attr.aria-disabled]': 'disabled() || null',\r\n '[attr.tabindex]': '_isInteractive() ? 0 : null',\r\n '(click)': 'onClick()',\r\n '(keydown.enter)': 'onClick()',\r\n '(keydown.space)': 'onSpace($event)',\r\n },\r\n})\r\nexport class FuiListItemComponent {\r\n readonly value = input<unknown>(undefined);\r\n readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });\r\n\r\n readonly _selected = signal(false);\r\n readonly _focused = signal(false);\r\n\r\n readonly _elementRef = inject(ElementRef);\r\n\r\n private _list = inject(FUI_LIST, { optional: true });\r\n\r\n readonly _isInteractive = computed(\r\n () => (this._list?.interactive() ?? this._list?.selectionMode() !== 'none') && !this.disabled(),\r\n );\r\n readonly _isSelectable = computed(() => this._list?.selectionMode() !== 'none');\r\n readonly _role = computed(() => (this._isSelectable() ? 'option' : 'listitem'));\r\n\r\n onClick(): void {\r\n if (this.disabled() || !this._list) return;\r\n if (this._isSelectable()) {\r\n this._list.selectItem(this);\r\n }\r\n }\r\n\r\n onSpace(event: Event): void {\r\n event.preventDefault();\r\n this.onClick();\r\n }\r\n}\r\n","<div class=\"fui-list-item__content\">\r\n <div class=\"fui-list-item__start\">\r\n <ng-content select=\"[fuiListItemIcon], [fuiListItemAvatar]\"></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__text\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"fui-list-item__end\">\r\n <ng-content select=\"[fuiListItemAction]\"></ng-content>\r\n </div>\r\n</div>\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n signal,\r\n contentChildren,\r\n} from '@angular/core';\r\nimport { FuiListSelectionMode, FuiListSelectionChange, FUI_LIST } from './list.types';\r\nimport { FuiListItemComponent } from './list-item.component';\r\n\r\n@Component({\r\n selector: 'fui-list',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './list.component.html',\r\n styleUrls: ['./list.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-list',\r\n '[class.fui-list--interactive]': 'interactive() || selectionMode() !== \"none\"',\r\n '[class.fui-list--dividers]': 'dividers()',\r\n '[attr.role]': 'selectionMode() !== \"none\" ? \"listbox\" : \"list\"',\r\n '[attr.aria-multiselectable]': 'selectionMode() === \"multi\" ? true : null',\r\n '(keydown)': 'onKeydown($event)',\r\n },\r\n providers: [{ provide: FUI_LIST, useExisting: FuiListComponent }],\r\n})\r\nexport class FuiListComponent {\r\n readonly interactive = input(false);\r\n readonly selectionMode = input<FuiListSelectionMode>('none');\r\n readonly dividers = input(false);\r\n\r\n readonly selectionChange = output<FuiListSelectionChange>();\r\n\r\n readonly items = contentChildren(FuiListItemComponent);\r\n\r\n readonly _selectedValues = signal(new Set());\r\n\r\n selectItem(item: FuiListItemComponent): void {\r\n if (item.disabled()) return;\r\n const mode = this.selectionMode();\r\n if (mode === 'none') return;\r\n\r\n const currentSet = new Set(this._selectedValues());\r\n const value = item.value();\r\n\r\n if (mode === 'single') {\r\n currentSet.clear();\r\n currentSet.add(value);\r\n } else {\r\n // multi\r\n if (currentSet.has(value)) {\r\n currentSet.delete(value);\r\n } else {\r\n currentSet.add(value);\r\n }\r\n }\r\n\r\n this._selectedValues.set(currentSet);\r\n\r\n // Update all items' selected state\r\n this.items().forEach((i) => {\r\n i._selected.set(currentSet.has(i.value()));\r\n });\r\n\r\n this.selectionChange.emit({\r\n source: this,\r\n value: Array.from(currentSet),\r\n });\r\n }\r\n\r\n isSelected(value: unknown): boolean {\r\n return this._selectedValues().has(value);\r\n }\r\n\r\n onKeydown(event: KeyboardEvent): void {\r\n const items = this.items();\r\n if (items.length === 0) return;\r\n\r\n const enabledItems = items.filter((i) => !i.disabled());\r\n if (enabledItems.length === 0) return;\r\n\r\n const focusedEl = document.activeElement;\r\n const currentIdx = enabledItems.findIndex(\r\n (i) => i._elementRef.nativeElement === focusedEl || i._elementRef.nativeElement.contains(focusedEl),\r\n );\r\n\r\n let targetIdx = -1;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n targetIdx = currentIdx < enabledItems.length - 1 ? currentIdx + 1 : 0;\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n targetIdx = currentIdx > 0 ? currentIdx - 1 : enabledItems.length - 1;\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n targetIdx = 0;\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n targetIdx = enabledItems.length - 1;\r\n break;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (currentIdx >= 0) {\r\n this.selectItem(enabledItems[currentIdx]);\r\n }\r\n return;\r\n default:\r\n return;\r\n }\r\n\r\n if (targetIdx >= 0) {\r\n enabledItems[targetIdx]._elementRef.nativeElement.focus();\r\n }\r\n }\r\n}\r\n","<ng-content></ng-content>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}