ng-primitives 0.92.0 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/a11y/index.d.ts +3 -1
- package/accordion/index.d.ts +8 -1
- package/autofill/index.d.ts +4 -0
- package/avatar/index.d.ts +11 -2
- package/breadcrumbs/index.d.ts +21 -7
- package/button/index.d.ts +3 -1
- package/checkbox/index.d.ts +3 -1
- package/fesm2022/ng-primitives-checkbox.mjs +7 -8
- package/fesm2022/ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/ng-primitives-file-upload.mjs +39 -38
- package/fesm2022/ng-primitives-file-upload.mjs.map +1 -1
- package/fesm2022/ng-primitives-focus-trap.mjs +107 -138
- package/fesm2022/ng-primitives-focus-trap.mjs.map +1 -1
- package/fesm2022/ng-primitives-form-field.mjs +323 -365
- package/fesm2022/ng-primitives-form-field.mjs.map +1 -1
- package/fesm2022/ng-primitives-interactions.mjs +57 -58
- package/fesm2022/ng-primitives-interactions.mjs.map +1 -1
- package/fesm2022/ng-primitives-listbox.mjs +2 -2
- package/fesm2022/ng-primitives-listbox.mjs.map +1 -1
- package/fesm2022/ng-primitives-slider.mjs +4 -5
- package/fesm2022/ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/ng-primitives-state.mjs +28 -5
- package/fesm2022/ng-primitives-state.mjs.map +1 -1
- package/fesm2022/ng-primitives-switch.mjs +4 -5
- package/fesm2022/ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/ng-primitives-tabs.mjs +194 -192
- package/fesm2022/ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/ng-primitives-toggle-group.mjs +4 -5
- package/fesm2022/ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/ng-primitives-toggle.mjs +4 -5
- package/fesm2022/ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/ng-primitives-tooltip.mjs +4 -4
- package/fesm2022/ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/ng-primitives-utils.mjs.map +1 -1
- package/file-upload/index.d.ts +20 -2
- package/focus-trap/index.d.ts +33 -75
- package/form-field/index.d.ts +320 -123
- package/input/index.d.ts +6 -0
- package/interactions/index.d.ts +16 -16
- package/package.json +1 -1
- package/roving-focus/index.d.ts +6 -2
- package/schematics/ng-generate/templates/tabs/tabs.__fileSuffix@dasherize__.ts.template +2 -2
- package/slider/index.d.ts +14 -6
- package/state/index.d.ts +22 -8
- package/switch/index.d.ts +8 -4
- package/tabs/index.d.ts +333 -84
- package/textarea/index.d.ts +6 -0
- package/toggle/index.d.ts +5 -3
- package/toggle-group/index.d.ts +6 -2
- package/toolbar/index.d.ts +5 -0
- package/utils/index.d.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-primitives-file-upload.mjs","sources":["../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-drop-filter.ts","../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-dropzone-state.ts","../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-dropzone.ts","../../../../packages/ng-primitives/file-upload/src/file-upload/file-upload-state.ts","../../../../packages/ng-primitives/file-upload/src/file-upload/file-upload.ts","../../../../packages/ng-primitives/file-upload/src/ng-primitives-file-upload.ts"],"sourcesContent":["export function fileDropFilter(\n fileList: FileList,\n acceptedTypes: string[] | undefined,\n multiple: boolean,\n) {\n const validFiles = Array.from(fileList).filter(file => isFileTypeAccepted(file, acceptedTypes));\n\n const limitedFiles = multiple ? validFiles : validFiles.slice(0, 1);\n\n return limitedFiles.length > 0 ? filesToFileList(limitedFiles) : null;\n}\n\nexport function isFileTypeAccepted(file: File, acceptedTypes: string[] | undefined) {\n // allow all file types if no types are specified\n if (!acceptedTypes || acceptedTypes.length === 0) return true;\n\n const mimeType = file.type;\n const fileName = file.name.toLowerCase();\n\n return acceptedTypes.some(type => {\n type = type.toLowerCase();\n\n if (type.startsWith('.')) {\n return fileName.endsWith(type);\n }\n\n if (type.endsWith('/*')) {\n const baseType = type.replace('/*', '');\n return mimeType.startsWith(baseType);\n }\n\n return mimeType === type;\n });\n}\n\nfunction filesToFileList(files: File[]): FileList {\n const dataTransfer = new DataTransfer();\n files.forEach(file => dataTransfer.items.add(file));\n return dataTransfer.files;\n}\n","import { Signal, signal } from '@angular/core';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { createPrimitive, dataBinding, listener } from 'ng-primitives/state';\nimport { Observable, Subject } from 'rxjs';\nimport { fileDropFilter } from './file-drop-filter';\n\n/**\n * The state for the NgpFileDropzone directive.\n */\nexport interface NgpFileDropzoneState {\n /**\n * Whether the user is currently dragging over the element.\n */\n readonly isDragOver: Signal<boolean>;\n /**\n * Observable that emits when files are selected.\n */\n readonly selected: Observable<FileList | null>;\n /**\n * Observable that emits when files are rejected.\n */\n readonly rejected: Observable<void>;\n /**\n * Observable that emits when drag over state changes.\n */\n readonly dragOverChanged: Observable<boolean>;\n}\n\n/**\n * The props for the NgpFileDropzone state.\n */\nexport interface NgpFileDropzoneProps {\n /**\n * The accepted file types.\n */\n readonly fileTypes?: Signal<string[] | undefined>;\n /**\n * Whether multiple files can be selected.\n */\n readonly multiple?: Signal<boolean>;\n /**\n * Whether directories can be selected.\n */\n readonly directory?: Signal<boolean>;\n /**\n * Whether the file dropzone is disabled.\n */\n readonly disabled?: Signal<boolean>;\n /**\n * Callback when files are selected.\n */\n readonly onSelected?: (files: FileList | null) => void;\n /**\n * Callback when files are rejected.\n */\n readonly onRejected?: () => void;\n /**\n * Callback when drag over state changes.\n */\n readonly onDragOver?: (isDragOver: boolean) => void;\n}\n\nexport const [\n NgpFileDropzoneStateToken,\n ngpFileDropzone,\n injectFileDropzoneState,\n provideFileDropzoneState,\n] = createPrimitive(\n 'NgpFileDropzone',\n ({\n fileTypes,\n multiple,\n directory,\n disabled,\n onSelected,\n onRejected,\n onDragOver,\n }: NgpFileDropzoneProps) => {\n const element = injectElementRef();\n const isDragOverState = signal(false);\n\n // Create observables\n const selectedSubject = new Subject<FileList | null>();\n const rejectedSubject = new Subject<void>();\n const dragOverSubject = new Subject<boolean>();\n\n // Host bindings\n dataBinding(element, 'data-dragover', () => (isDragOverState() ? '' : null));\n dataBinding(element, 'data-disabled', () => (disabled?.() ? '' : null));\n\n function onDragEnter(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOverState.set(true);\n dragOverSubject.next(true);\n onDragOver?.(true);\n }\n\n function onDragOverHandler(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n isDragOverState.set(true);\n }\n\n function onDragLeave(event: DragEvent): void {\n if (disabled?.() || !isDragOverState()) {\n return;\n }\n\n // if the element we are dragging over is a child of the file dropzone, ignore the event\n if (element.nativeElement.contains(event.relatedTarget as Node)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOverState.set(false);\n dragOverSubject.next(false);\n onDragOver?.(false);\n }\n\n function onDrop(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.preventDefault();\n isDragOverState.set(false);\n dragOverSubject.next(false);\n onDragOver?.(false);\n\n const fileList = event.dataTransfer?.files;\n if (fileList) {\n const filteredFiles = fileDropFilter(fileList, fileTypes?.(), multiple?.() ?? false);\n\n if (filteredFiles) {\n selectedSubject.next(filteredFiles);\n onSelected?.(filteredFiles);\n } else {\n rejectedSubject.next();\n onRejected?.();\n }\n }\n }\n\n // Event listeners\n listener(element, 'dragenter', onDragEnter);\n listener(element, 'dragover', onDragOverHandler);\n listener(element, 'dragleave', onDragLeave);\n listener(element, 'drop', onDrop);\n\n return {\n disabled,\n fileTypes,\n multiple,\n directory,\n isDragOver: isDragOverState,\n selected: selectedSubject.asObservable(),\n rejected: rejectedSubject.asObservable(),\n dragOverChanged: dragOverSubject.asObservable(),\n };\n },\n);\n","import { BooleanInput, coerceStringArray } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, output } from '@angular/core';\nimport { ngpHoverInteraction } from 'ng-primitives/interactions';\nimport { ngpFileDropzone, provideFileDropzoneState } from './file-dropzone-state';\n\n/**\n * Capture files dropped on the element.\n */\n@Directive({\n selector: '[ngpFileDropzone]',\n exportAs: 'ngpFileDropzone',\n providers: [provideFileDropzoneState()],\n})\nexport class NgpFileDropzone {\n /**\n * The accepted file types. This can be an array of strings or a comma-separated string.\n * Accepted types can either be file extensions (e.g. `.jpg`) or MIME types (e.g. `image/jpeg`).\n */\n readonly fileTypes = input<string[], string | string[]>(undefined, {\n alias: 'ngpFileDropzoneFileTypes',\n transform: types => coerceStringArray(types, ','),\n });\n\n /**\n * Whether to allow multiple files to be selected.\n */\n readonly multiple = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneMultiple',\n transform: booleanAttribute,\n });\n\n /**\n * Whether to allow the user to select directories.\n */\n readonly directory = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneDirectory',\n transform: booleanAttribute,\n });\n\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * Emits when the user selects files.\n */\n readonly selected = output<FileList | null>({\n alias: 'ngpFileDropzoneSelected',\n });\n\n /**\n * Emits when uploaded files are rejected because they do not match the allowed {@link fileTypes}.\n */\n readonly rejected = output<void>({\n alias: 'ngpFileDropzoneRejected',\n });\n\n /**\n * Emits when the user drags a file over the file upload.\n */\n readonly dragOver = output<boolean>({\n alias: 'ngpFileDropzoneDragOver',\n });\n\n private readonly state = ngpFileDropzone({\n fileTypes: this.fileTypes,\n multiple: this.multiple,\n directory: this.directory,\n disabled: this.disabled,\n onSelected: files => this.selected.emit(files),\n onRejected: () => this.rejected.emit(),\n onDragOver: isDragOver => this.dragOver.emit(isDragOver),\n });\n\n constructor() {\n ngpHoverInteraction({ disabled: this.disabled });\n }\n\n /**\n * Whether the user is currently dragging a file over the file upload.\n */\n readonly isDragOver = this.state.isDragOver;\n}\n","import { DOCUMENT, inject, Signal, signal } from '@angular/core';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { createPrimitive, dataBinding, listener } from 'ng-primitives/state';\nimport { Observable, Subject } from 'rxjs';\nimport { fileDropFilter } from '../file-dropzone/file-drop-filter';\n\n/**\n * The state for the NgpFileUpload directive.\n */\nexport interface NgpFileUploadState {\n /**\n * Whether the user is currently dragging over the element.\n */\n readonly isDragOver: Signal<boolean>;\n /**\n * Observable that emits when files are selected.\n */\n readonly selected: Observable<FileList | null>;\n /**\n * Observable that emits when file selection is canceled.\n */\n readonly canceled: Observable<void>;\n /**\n * Observable that emits when files are rejected.\n */\n readonly rejected: Observable<void>;\n /**\n * Observable that emits when drag over state changes.\n */\n readonly dragOverChanged: Observable<boolean>;\n /**\n * Show the file dialog.\n */\n showFileDialog(): void;\n}\n\n/**\n * The props for the NgpFileUpload state.\n */\nexport interface NgpFileUploadProps {\n /**\n * The accepted file types.\n */\n readonly fileTypes?: Signal<string[] | undefined>;\n /**\n * Whether multiple files can be selected.\n */\n readonly multiple?: Signal<boolean>;\n /**\n * Whether directories can be selected.\n */\n readonly directory?: Signal<boolean>;\n /**\n * Whether drag and drop is enabled.\n */\n readonly dragAndDrop?: Signal<boolean>;\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled?: Signal<boolean>;\n /**\n * Callback when files are selected.\n */\n readonly onSelected?: (files: FileList | null) => void;\n /**\n * Callback when file selection is canceled.\n */\n readonly onCanceled?: () => void;\n /**\n * Callback when files are rejected.\n */\n readonly onRejected?: () => void;\n /**\n * Callback when drag over state changes.\n */\n readonly onDragOver?: (isDragOver: boolean) => void;\n}\n\nexport const [\n NgpFileUploadStateToken,\n ngpFileUpload,\n injectFileUploadState,\n provideFileUploadState,\n] = createPrimitive(\n 'NgpFileUpload',\n ({\n fileTypes,\n multiple,\n directory,\n dragAndDrop,\n disabled,\n onSelected,\n onCanceled,\n onRejected,\n onDragOver,\n }: NgpFileUploadProps) => {\n const element = injectElementRef();\n const document = inject(DOCUMENT);\n\n const isDragOver = signal(false);\n\n // Create observables\n const selectedSubject = new Subject<FileList | null>();\n const canceledSubject = new Subject<void>();\n const rejectedSubject = new Subject<void>();\n const dragOverSubject = new Subject<boolean>();\n\n // Host bindings\n dataBinding(element, 'data-disabled', () => (disabled?.() ? '' : null));\n dataBinding(element, 'data-dragover', () => (isDragOver() ? '' : null));\n\n // Create file input\n const input: HTMLInputElement = document.createElement('input');\n input.type = 'file';\n input.style.display = 'none';\n\n input.addEventListener('change', () => {\n const files = input.files;\n selectedSubject.next(files);\n onSelected?.(files);\n input.value = '';\n });\n\n input.addEventListener('cancel', () => {\n canceledSubject.next();\n onCanceled?.();\n });\n\n function showFileDialog(): void {\n if (disabled?.()) {\n return;\n }\n\n const fileTypesValue = fileTypes?.()?.join(',');\n if (fileTypesValue) {\n input.accept = fileTypesValue;\n }\n\n input.multiple = multiple?.() ?? false;\n input.webkitdirectory = directory?.() ?? false;\n input.click();\n }\n\n function onDragEnter(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOver.set(true);\n dragOverSubject.next(true);\n onDragOver?.(true);\n }\n\n function onDragOverHandler(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n isDragOver.set(true);\n }\n\n function onDragLeave(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.() || !isDragOver()) {\n return;\n }\n\n // if the element we are dragging over is a child of the file upload, ignore the event\n if (element.nativeElement.contains(event.relatedTarget as Node)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOver.set(false);\n dragOverSubject.next(false);\n onDragOver?.(false);\n }\n\n function onDrop(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.preventDefault();\n isDragOver.set(false);\n dragOverSubject.next(false);\n onDragOver?.(false);\n\n const fileList = event.dataTransfer?.files;\n if (fileList) {\n const filteredFiles = fileDropFilter(fileList, fileTypes?.(), multiple?.() ?? false);\n\n if (filteredFiles) {\n selectedSubject.next(filteredFiles);\n onSelected?.(filteredFiles);\n } else {\n rejectedSubject.next();\n onRejected?.();\n }\n }\n }\n\n // Event listeners\n listener(element, 'click', showFileDialog);\n listener(element, 'dragenter', onDragEnter);\n listener(element, 'dragover', onDragOverHandler);\n listener(element, 'dragleave', onDragLeave);\n listener(element, 'drop', onDrop);\n\n return {\n isDragOver,\n selected: selectedSubject.asObservable(),\n canceled: canceledSubject.asObservable(),\n rejected: rejectedSubject.asObservable(),\n dragOverChanged: dragOverSubject.asObservable(),\n showFileDialog,\n };\n },\n);\n","import { BooleanInput, coerceStringArray } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, output } from '@angular/core';\nimport { ngpInteractions } from 'ng-primitives/interactions';\nimport { ngpFileUpload, provideFileUploadState } from './file-upload-state';\n\n/**\n * A directive that allows you to turn any element into a file upload trigger.\n */\n@Directive({\n selector: '[ngpFileUpload]',\n exportAs: 'ngpFileUpload',\n providers: [provideFileUploadState()],\n})\nexport class NgpFileUpload {\n /**\n * The accepted file types. This can be an array of strings or a comma-separated string.\n * Accepted types can either be file extensions (e.g. `.jpg`) or MIME types (e.g. `image/jpeg`).\n */\n readonly fileTypes = input<string[], string | string[]>(undefined, {\n alias: 'ngpFileUploadFileTypes',\n transform: types => coerceStringArray(types, ','),\n });\n\n /**\n * Whether to allow multiple files to be selected.\n */\n readonly multiple = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadMultiple',\n transform: booleanAttribute,\n });\n\n /**\n * Whether to allow the user to select directories.\n */\n readonly directory = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadDirectory',\n transform: booleanAttribute,\n });\n\n /**\n * Whether drag-and-drop is enabled.\n */\n readonly dragAndDrop = input<boolean, BooleanInput>(true, {\n alias: 'ngpFileUploadDragDrop',\n transform: booleanAttribute,\n });\n\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * Emits when the user selects files.\n */\n readonly selected = output<FileList | null>({\n alias: 'ngpFileUploadSelected',\n });\n\n /**\n * Emits when the user cancel the file selection.\n */\n readonly canceled = output<void>({\n alias: 'ngpFileUploadCanceled',\n });\n\n /**\n * Emits when uploaded files are rejected because they do not match the allowed {@link fileTypes}.\n */\n readonly rejected = output<void>({\n alias: 'ngpFileUploadRejected',\n });\n\n /**\n * Emits when the user drags a file over the file upload.\n */\n readonly dragOver = output<boolean>({\n alias: 'ngpFileUploadDragOver',\n });\n\n private readonly state = ngpFileUpload({\n fileTypes: this.fileTypes,\n multiple: this.multiple,\n directory: this.directory,\n dragAndDrop: this.dragAndDrop,\n disabled: this.disabled,\n onSelected: files => this.selected.emit(files),\n onCanceled: () => this.canceled.emit(),\n onRejected: () => this.rejected.emit(),\n onDragOver: isDragOver => this.dragOver.emit(isDragOver),\n });\n\n constructor() {\n ngpInteractions({\n hover: true,\n press: true,\n focusVisible: true,\n disabled: this.disabled,\n });\n }\n\n /**\n * Whether the user is currently dragging a file over the file upload.\n */\n readonly isDragOver = this.state.isDragOver;\n\n /**\n * Show the file dialog.\n */\n showFileDialog(): void {\n this.state.showFileDialog();\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":"ng-primitives-file-upload.mjs","sources":["../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-drop-filter.ts","../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-dropzone-state.ts","../../../../packages/ng-primitives/file-upload/src/file-dropzone/file-dropzone.ts","../../../../packages/ng-primitives/file-upload/src/file-upload/file-upload-state.ts","../../../../packages/ng-primitives/file-upload/src/file-upload/file-upload.ts","../../../../packages/ng-primitives/file-upload/src/ng-primitives-file-upload.ts"],"sourcesContent":["export function fileDropFilter(\n fileList: FileList,\n acceptedTypes: string[] | undefined,\n multiple: boolean,\n) {\n const validFiles = Array.from(fileList).filter(file => isFileTypeAccepted(file, acceptedTypes));\n\n const limitedFiles = multiple ? validFiles : validFiles.slice(0, 1);\n\n return limitedFiles.length > 0 ? filesToFileList(limitedFiles) : null;\n}\n\nexport function isFileTypeAccepted(file: File, acceptedTypes: string[] | undefined) {\n // allow all file types if no types are specified\n if (!acceptedTypes || acceptedTypes.length === 0) return true;\n\n const mimeType = file.type;\n const fileName = file.name.toLowerCase();\n\n return acceptedTypes.some(type => {\n type = type.toLowerCase();\n\n if (type.startsWith('.')) {\n return fileName.endsWith(type);\n }\n\n if (type.endsWith('/*')) {\n const baseType = type.replace('/*', '');\n return mimeType.startsWith(baseType);\n }\n\n return mimeType === type;\n });\n}\n\nfunction filesToFileList(files: File[]): FileList {\n const dataTransfer = new DataTransfer();\n files.forEach(file => dataTransfer.items.add(file));\n return dataTransfer.files;\n}\n","import { Signal, signal } from '@angular/core';\nimport { ngpHover } from 'ng-primitives/interactions';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { createPrimitive, dataBinding, emitter, listener } from 'ng-primitives/state';\nimport { Observable } from 'rxjs';\nimport { fileDropFilter } from './file-drop-filter';\n\n/**\n * The state for the NgpFileDropzone directive.\n */\nexport interface NgpFileDropzoneState {\n /**\n * Whether the user is currently dragging over the element.\n */\n readonly isDragOver: Signal<boolean>;\n /**\n * Observable that emits when files are selected.\n */\n readonly selected: Observable<FileList | null>;\n /**\n * Observable that emits when files are rejected.\n */\n readonly rejected: Observable<void>;\n /**\n * Observable that emits when drag over state changes.\n */\n readonly dragOverChanged: Observable<boolean>;\n}\n\n/**\n * The props for the NgpFileDropzone state.\n */\nexport interface NgpFileDropzoneProps {\n /**\n * The accepted file types.\n */\n readonly fileTypes?: Signal<string[] | undefined>;\n /**\n * Whether multiple files can be selected.\n */\n readonly multiple?: Signal<boolean>;\n /**\n * Whether directories can be selected.\n */\n readonly directory?: Signal<boolean>;\n /**\n * Whether the file dropzone is disabled.\n */\n readonly disabled?: Signal<boolean>;\n /**\n * Callback when files are selected.\n */\n readonly onSelected?: (files: FileList | null) => void;\n /**\n * Callback when files are rejected.\n */\n readonly onRejected?: () => void;\n /**\n * Callback when drag over state changes.\n */\n readonly onDragOver?: (isDragOver: boolean) => void;\n}\n\nexport const [\n NgpFileDropzoneStateToken,\n ngpFileDropzone,\n injectFileDropzoneState,\n provideFileDropzoneState,\n] = createPrimitive(\n 'NgpFileDropzone',\n ({\n fileTypes,\n multiple,\n directory,\n disabled,\n onSelected,\n onRejected,\n onDragOver,\n }: NgpFileDropzoneProps) => {\n const element = injectElementRef();\n const isDragOverState = signal(false);\n\n // Create observables\n const selected = emitter<FileList | null>();\n const rejected = emitter<void>();\n const dragOver = emitter<boolean>();\n\n // Host bindings\n dataBinding(element, 'data-dragover', () => (isDragOverState() ? '' : null));\n dataBinding(element, 'data-disabled', () => (disabled?.() ? '' : null));\n\n // Setup hover interaction\n ngpHover({ disabled });\n\n function onDragEnter(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOverState.set(true);\n dragOver.emit(true);\n onDragOver?.(true);\n }\n\n function onDragOverHandler(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n isDragOverState.set(true);\n }\n\n function onDragLeave(event: DragEvent): void {\n if (disabled?.() || !isDragOverState()) {\n return;\n }\n\n // if the element we are dragging over is a child of the file dropzone, ignore the event\n if (element.nativeElement.contains(event.relatedTarget as Node)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOverState.set(false);\n dragOver.emit(false);\n onDragOver?.(false);\n }\n\n function onDrop(event: DragEvent): void {\n if (disabled?.()) {\n return;\n }\n\n event.preventDefault();\n isDragOverState.set(false);\n dragOver.emit(false);\n onDragOver?.(false);\n\n const fileList = event.dataTransfer?.files;\n if (fileList) {\n const filteredFiles = fileDropFilter(fileList, fileTypes?.(), multiple?.() ?? false);\n\n if (filteredFiles) {\n selected.emit(filteredFiles);\n onSelected?.(filteredFiles);\n } else {\n rejected.emit();\n onRejected?.();\n }\n }\n }\n\n // Event listeners\n listener(element, 'dragenter', onDragEnter);\n listener(element, 'dragover', onDragOverHandler);\n listener(element, 'dragleave', onDragLeave);\n listener(element, 'drop', onDrop);\n\n return {\n disabled,\n fileTypes,\n multiple,\n directory,\n isDragOver: isDragOverState,\n selected: selected.asObservable(),\n rejected: rejected.asObservable(),\n dragOverChanged: dragOver.asObservable(),\n };\n },\n);\n","import { BooleanInput, coerceStringArray } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, output } from '@angular/core';\nimport { ngpFileDropzone, provideFileDropzoneState } from './file-dropzone-state';\n\n/**\n * Capture files dropped on the element.\n */\n@Directive({\n selector: '[ngpFileDropzone]',\n exportAs: 'ngpFileDropzone',\n providers: [provideFileDropzoneState()],\n})\nexport class NgpFileDropzone {\n /**\n * The accepted file types. This can be an array of strings or a comma-separated string.\n * Accepted types can either be file extensions (e.g. `.jpg`) or MIME types (e.g. `image/jpeg`).\n */\n readonly fileTypes = input<string[], string | string[]>(undefined, {\n alias: 'ngpFileDropzoneFileTypes',\n transform: types => coerceStringArray(types, ','),\n });\n\n /**\n * Whether to allow multiple files to be selected.\n */\n readonly multiple = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneMultiple',\n transform: booleanAttribute,\n });\n\n /**\n * Whether to allow the user to select directories.\n */\n readonly directory = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneDirectory',\n transform: booleanAttribute,\n });\n\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileDropzoneDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * Emits when the user selects files.\n */\n readonly selected = output<FileList | null>({\n alias: 'ngpFileDropzoneSelected',\n });\n\n /**\n * Emits when uploaded files are rejected because they do not match the allowed {@link fileTypes}.\n */\n readonly rejected = output<void>({\n alias: 'ngpFileDropzoneRejected',\n });\n\n /**\n * Emits when the user drags a file over the file upload.\n */\n readonly dragOver = output<boolean>({\n alias: 'ngpFileDropzoneDragOver',\n });\n\n private readonly state = ngpFileDropzone({\n fileTypes: this.fileTypes,\n multiple: this.multiple,\n directory: this.directory,\n disabled: this.disabled,\n onSelected: files => this.selected.emit(files),\n onRejected: () => this.rejected.emit(),\n onDragOver: isDragOver => this.dragOver.emit(isDragOver),\n });\n\n /**\n * Whether the user is currently dragging a file over the file upload.\n */\n readonly isDragOver = this.state.isDragOver;\n}\n","import { DOCUMENT, inject, Signal, signal } from '@angular/core';\nimport { ngpInteractions } from 'ng-primitives/interactions';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { createPrimitive, dataBinding, emitter, listener } from 'ng-primitives/state';\nimport { Observable } from 'rxjs';\nimport { fileDropFilter } from '../file-dropzone/file-drop-filter';\n\n/**\n * The state for the NgpFileUpload directive.\n */\nexport interface NgpFileUploadState {\n /**\n * Whether the user is currently dragging over the element.\n */\n readonly isDragOver: Signal<boolean>;\n /**\n * Observable that emits when files are selected.\n */\n readonly selected: Observable<FileList | null>;\n /**\n * Observable that emits when file selection is canceled.\n */\n readonly canceled: Observable<void>;\n /**\n * Observable that emits when files are rejected.\n */\n readonly rejected: Observable<void>;\n /**\n * Observable that emits when drag over state changes.\n */\n readonly dragOverChanged: Observable<boolean>;\n /**\n * Show the file dialog.\n */\n showFileDialog(): void;\n}\n\n/**\n * The props for the NgpFileUpload state.\n */\nexport interface NgpFileUploadProps {\n /**\n * The accepted file types.\n */\n readonly fileTypes?: Signal<string[] | undefined>;\n /**\n * Whether multiple files can be selected.\n */\n readonly multiple?: Signal<boolean>;\n /**\n * Whether directories can be selected.\n */\n readonly directory?: Signal<boolean>;\n /**\n * Whether drag and drop is enabled.\n */\n readonly dragAndDrop?: Signal<boolean>;\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled?: Signal<boolean>;\n /**\n * Callback when files are selected.\n */\n readonly onSelected?: (files: FileList | null) => void;\n /**\n * Callback when file selection is canceled.\n */\n readonly onCanceled?: () => void;\n /**\n * Callback when files are rejected.\n */\n readonly onRejected?: () => void;\n /**\n * Callback when drag over state changes.\n */\n readonly onDragOver?: (isDragOver: boolean) => void;\n}\n\nexport const [\n NgpFileUploadStateToken,\n ngpFileUpload,\n injectFileUploadState,\n provideFileUploadState,\n] = createPrimitive(\n 'NgpFileUpload',\n ({\n fileTypes,\n multiple,\n directory,\n dragAndDrop,\n disabled,\n onSelected,\n onCanceled,\n onRejected,\n onDragOver,\n }: NgpFileUploadProps) => {\n const element = injectElementRef();\n const document = inject(DOCUMENT);\n\n const isDragOver = signal(false);\n\n // Create observables\n const selected = emitter<FileList | null>();\n const canceled = emitter<void>();\n const rejected = emitter<void>();\n const dragOver = emitter<boolean>();\n\n // Host bindings\n dataBinding(element, 'data-disabled', () => (disabled?.() ? '' : null));\n dataBinding(element, 'data-dragover', () => (isDragOver() ? '' : null));\n\n // Setup interactions\n ngpInteractions({\n hover: true,\n press: true,\n focusVisible: true,\n disabled,\n });\n\n // Create file input\n const input: HTMLInputElement = document.createElement('input');\n input.type = 'file';\n input.style.display = 'none';\n\n input.addEventListener('change', () => {\n const files = input.files;\n selected.emit(files);\n onSelected?.(files);\n input.value = '';\n });\n\n input.addEventListener('cancel', () => {\n canceled.emit();\n onCanceled?.();\n });\n\n function showFileDialog(): void {\n if (disabled?.()) {\n return;\n }\n\n const fileTypesValue = fileTypes?.()?.join(',');\n if (fileTypesValue) {\n input.accept = fileTypesValue;\n }\n\n input.multiple = multiple?.() ?? false;\n input.webkitdirectory = directory?.() ?? false;\n input.click();\n }\n\n function onDragEnter(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOver.set(true);\n dragOver.emit(true);\n onDragOver?.(true);\n }\n\n function onDragOverHandler(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n isDragOver.set(true);\n }\n\n function onDragLeave(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.() || !isDragOver()) {\n return;\n }\n\n // if the element we are dragging over is a child of the file upload, ignore the event\n if (element.nativeElement.contains(event.relatedTarget as Node)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n isDragOver.set(false);\n dragOver.emit(false);\n onDragOver?.(false);\n }\n\n function onDrop(event: DragEvent): void {\n if (disabled?.() || !dragAndDrop?.()) {\n return;\n }\n\n event.preventDefault();\n isDragOver.set(false);\n dragOver.emit(false);\n onDragOver?.(false);\n\n const fileList = event.dataTransfer?.files;\n if (fileList) {\n const filteredFiles = fileDropFilter(fileList, fileTypes?.(), multiple?.() ?? false);\n\n if (filteredFiles) {\n selected.emit(filteredFiles);\n onSelected?.(filteredFiles);\n } else {\n rejected.emit();\n onRejected?.();\n }\n }\n }\n\n // Event listeners\n listener(element, 'click', showFileDialog);\n listener(element, 'dragenter', onDragEnter);\n listener(element, 'dragover', onDragOverHandler);\n listener(element, 'dragleave', onDragLeave);\n listener(element, 'drop', onDrop);\n\n return {\n isDragOver,\n selected: selected.asObservable(),\n canceled: canceled.asObservable(),\n rejected: rejected.asObservable(),\n dragOverChanged: dragOver.asObservable(),\n showFileDialog,\n };\n },\n);\n","import { BooleanInput, coerceStringArray } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, output } from '@angular/core';\nimport { ngpFileUpload, provideFileUploadState } from './file-upload-state';\n\n/**\n * A directive that allows you to turn any element into a file upload trigger.\n */\n@Directive({\n selector: '[ngpFileUpload]',\n exportAs: 'ngpFileUpload',\n providers: [provideFileUploadState()],\n})\nexport class NgpFileUpload {\n /**\n * The accepted file types. This can be an array of strings or a comma-separated string.\n * Accepted types can either be file extensions (e.g. `.jpg`) or MIME types (e.g. `image/jpeg`).\n */\n readonly fileTypes = input<string[], string | string[]>(undefined, {\n alias: 'ngpFileUploadFileTypes',\n transform: types => coerceStringArray(types, ','),\n });\n\n /**\n * Whether to allow multiple files to be selected.\n */\n readonly multiple = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadMultiple',\n transform: booleanAttribute,\n });\n\n /**\n * Whether to allow the user to select directories.\n */\n readonly directory = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadDirectory',\n transform: booleanAttribute,\n });\n\n /**\n * Whether drag-and-drop is enabled.\n */\n readonly dragAndDrop = input<boolean, BooleanInput>(true, {\n alias: 'ngpFileUploadDragDrop',\n transform: booleanAttribute,\n });\n\n /**\n * Whether the file upload is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFileUploadDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * Emits when the user selects files.\n */\n readonly selected = output<FileList | null>({\n alias: 'ngpFileUploadSelected',\n });\n\n /**\n * Emits when the user cancel the file selection.\n */\n readonly canceled = output<void>({\n alias: 'ngpFileUploadCanceled',\n });\n\n /**\n * Emits when uploaded files are rejected because they do not match the allowed {@link fileTypes}.\n */\n readonly rejected = output<void>({\n alias: 'ngpFileUploadRejected',\n });\n\n /**\n * Emits when the user drags a file over the file upload.\n */\n readonly dragOver = output<boolean>({\n alias: 'ngpFileUploadDragOver',\n });\n\n private readonly state = ngpFileUpload({\n fileTypes: this.fileTypes,\n multiple: this.multiple,\n directory: this.directory,\n dragAndDrop: this.dragAndDrop,\n disabled: this.disabled,\n onSelected: files => this.selected.emit(files),\n onCanceled: () => this.canceled.emit(),\n onRejected: () => this.rejected.emit(),\n onDragOver: isDragOver => this.dragOver.emit(isDragOver),\n });\n\n /**\n * Whether the user is currently dragging a file over the file upload.\n */\n readonly isDragOver = this.state.isDragOver;\n\n /**\n * Show the file dialog.\n */\n showFileDialog(): void {\n this.state.showFileDialog();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,11 @@
|
|
|
1
|
-
import { FocusMonitor, InteractivityChecker } from '@angular/cdk/a11y';
|
|
2
1
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, Injector,
|
|
2
|
+
import { inject, Injector, NgZone, signal, afterNextRender, input, booleanAttribute, Directive } from '@angular/core';
|
|
3
|
+
import { FocusMonitor, InteractivityChecker } from '@angular/cdk/a11y';
|
|
4
|
+
import { injectElementRef } from 'ng-primitives/internal';
|
|
4
5
|
import { NgpOverlay } from 'ng-primitives/portal';
|
|
6
|
+
import { createPrimitive, attrBinding, dataBinding, onDestroy, listener } from 'ng-primitives/state';
|
|
5
7
|
import { safeTakeUntilDestroyed } from 'ng-primitives/utils';
|
|
6
|
-
import { createStateToken, createStateProvider, createStateInjector, createState } from 'ng-primitives/state';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The state token for the FocusTrap primitive.
|
|
10
|
-
*/
|
|
11
|
-
const NgpFocusTrapStateToken = createStateToken('FocusTrap');
|
|
12
|
-
/**
|
|
13
|
-
* Provides the FocusTrap state.
|
|
14
|
-
*/
|
|
15
|
-
const provideFocusTrapState = createStateProvider(NgpFocusTrapStateToken);
|
|
16
|
-
/**
|
|
17
|
-
* Injects the FocusTrap state.
|
|
18
|
-
*/
|
|
19
|
-
const injectFocusTrapState = createStateInjector(NgpFocusTrapStateToken);
|
|
20
|
-
/**
|
|
21
|
-
* The FocusTrap state registration function.
|
|
22
|
-
*/
|
|
23
|
-
const focusTrapState = createState(NgpFocusTrapStateToken);
|
|
24
8
|
|
|
25
|
-
/**
|
|
26
|
-
* This implementation is based on the Radix UI FocusScope:
|
|
27
|
-
* https://github.com/radix-ui/primitives/blob/main/packages/react/focus-scope/src/FocusScope.tsx#L306
|
|
28
|
-
*/
|
|
29
9
|
class FocusTrap {
|
|
30
10
|
constructor() {
|
|
31
11
|
/**
|
|
@@ -81,149 +61,111 @@ class FocusTrapStack {
|
|
|
81
61
|
}
|
|
82
62
|
// create a global stack of focus traps
|
|
83
63
|
const focusTrapStack = new FocusTrapStack();
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
*/
|
|
108
|
-
this.interactivityChecker = inject(InteractivityChecker);
|
|
109
|
-
/**
|
|
110
|
-
* Get the focus trap container element.
|
|
111
|
-
*/
|
|
112
|
-
this.elementRef = inject(ElementRef);
|
|
113
|
-
/**
|
|
114
|
-
* Access NgZone to run the focus trap events outside of Angular's zone.
|
|
115
|
-
*/
|
|
116
|
-
this.ngZone = inject(NgZone);
|
|
117
|
-
/**
|
|
118
|
-
* Store the mutation observer.
|
|
119
|
-
*/
|
|
120
|
-
this.mutationObserver = null;
|
|
121
|
-
/**
|
|
122
|
-
* Store the last focused element.
|
|
123
|
-
*/
|
|
124
|
-
this.lastFocusedElement = null;
|
|
125
|
-
/**
|
|
126
|
-
* Whether the focus trap is disabled.
|
|
127
|
-
*/
|
|
128
|
-
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", alias: 'ngpFocusTrapDisabled',
|
|
129
|
-
transform: booleanAttribute }] : [{
|
|
130
|
-
alias: 'ngpFocusTrapDisabled',
|
|
131
|
-
transform: booleanAttribute,
|
|
132
|
-
}]));
|
|
133
|
-
/**
|
|
134
|
-
* The focus trap state.
|
|
135
|
-
*/
|
|
136
|
-
this.state = focusTrapState(this);
|
|
137
|
-
// if this is used within an overlay we must disable the focus trap as soon as the overlay is closing
|
|
138
|
-
this.overlay?.closing
|
|
139
|
-
.pipe(safeTakeUntilDestroyed())
|
|
140
|
-
.subscribe(() => this.focusTrap.deactivate());
|
|
141
|
-
}
|
|
142
|
-
ngOnInit() {
|
|
143
|
-
focusTrapStack.add(this.focusTrap);
|
|
144
|
-
this.mutationObserver = new MutationObserver(this.handleMutations.bind(this));
|
|
145
|
-
// setup event listeners
|
|
146
|
-
this.ngZone.runOutsideAngular(() => {
|
|
147
|
-
this.mutationObserver.observe(this.elementRef.nativeElement, {
|
|
64
|
+
const [NgpFocusTrapStateToken, ngpFocusTrap, injectFocusTrapState, provideFocusTrapState] = createPrimitive('NgpFocusTrap', ({ disabled = signal(false) }) => {
|
|
65
|
+
const element = injectElementRef();
|
|
66
|
+
const overlay = inject(NgpOverlay, { optional: true });
|
|
67
|
+
const injector = inject(Injector);
|
|
68
|
+
const focusMonitor = inject(FocusMonitor);
|
|
69
|
+
const interactivityChecker = inject(InteractivityChecker);
|
|
70
|
+
const ngZone = inject(NgZone);
|
|
71
|
+
// Create a new focus trap
|
|
72
|
+
const focusTrap = new FocusTrap();
|
|
73
|
+
// Store the mutation observer
|
|
74
|
+
let mutationObserver = null;
|
|
75
|
+
// Store the last focused element
|
|
76
|
+
let lastFocusedElement = null;
|
|
77
|
+
// Host bindings
|
|
78
|
+
attrBinding(element, 'tabindex', '-1');
|
|
79
|
+
dataBinding(element, 'data-focus-trap', () => (disabled() ? null : ''));
|
|
80
|
+
// Setup the focus trap
|
|
81
|
+
function setupFocusTrap() {
|
|
82
|
+
focusTrapStack.add(focusTrap);
|
|
83
|
+
mutationObserver = new MutationObserver(handleMutations);
|
|
84
|
+
// Setup event listeners
|
|
85
|
+
ngZone.runOutsideAngular(() => {
|
|
86
|
+
mutationObserver.observe(element.nativeElement, {
|
|
148
87
|
childList: true,
|
|
149
88
|
subtree: true,
|
|
150
89
|
});
|
|
151
|
-
document.addEventListener('focusin',
|
|
152
|
-
document.addEventListener('focusout',
|
|
90
|
+
document.addEventListener('focusin', handleFocusIn);
|
|
91
|
+
document.addEventListener('focusout', handleFocusOut);
|
|
153
92
|
});
|
|
154
93
|
const previouslyFocusedElement = document.activeElement;
|
|
155
|
-
const hasFocusedCandidate =
|
|
94
|
+
const hasFocusedCandidate = element.nativeElement.contains(previouslyFocusedElement);
|
|
156
95
|
if (!hasFocusedCandidate) {
|
|
157
96
|
// we do this to ensure the content is rendered before we try to find the first focusable element
|
|
158
97
|
// and focus it
|
|
159
98
|
afterNextRender({
|
|
160
99
|
write: () => {
|
|
161
|
-
|
|
100
|
+
focusFirst();
|
|
162
101
|
// if the focus didn't change, focus the container
|
|
163
102
|
if (document.activeElement === previouslyFocusedElement) {
|
|
164
|
-
|
|
103
|
+
focus(element.nativeElement);
|
|
165
104
|
}
|
|
166
105
|
},
|
|
167
|
-
}, { injector
|
|
106
|
+
}, { injector });
|
|
168
107
|
}
|
|
169
108
|
}
|
|
170
|
-
|
|
171
|
-
focusTrapStack.remove(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
109
|
+
function teardownFocusTrap() {
|
|
110
|
+
focusTrapStack.remove(focusTrap);
|
|
111
|
+
mutationObserver?.disconnect();
|
|
112
|
+
mutationObserver = null;
|
|
113
|
+
focusTrap.deactivate();
|
|
114
|
+
// Remove event listeners
|
|
115
|
+
document.removeEventListener('focusin', handleFocusIn);
|
|
116
|
+
document.removeEventListener('focusout', handleFocusOut);
|
|
175
117
|
}
|
|
176
|
-
handleFocusIn(event) {
|
|
177
|
-
if (!
|
|
118
|
+
function handleFocusIn(event) {
|
|
119
|
+
if (!focusTrap.active || disabled?.()) {
|
|
178
120
|
return;
|
|
179
121
|
}
|
|
180
122
|
const target = event.target;
|
|
181
|
-
if (
|
|
182
|
-
|
|
123
|
+
if (element.nativeElement.contains(target)) {
|
|
124
|
+
lastFocusedElement = target;
|
|
183
125
|
}
|
|
184
126
|
else {
|
|
185
|
-
|
|
127
|
+
focus(lastFocusedElement);
|
|
186
128
|
}
|
|
187
129
|
}
|
|
188
130
|
/**
|
|
189
131
|
* Handles the `focusout` event.
|
|
190
132
|
*/
|
|
191
|
-
handleFocusOut(event) {
|
|
192
|
-
if (!
|
|
133
|
+
function handleFocusOut(event) {
|
|
134
|
+
if (!focusTrap.active || disabled?.() || event.relatedTarget === null) {
|
|
193
135
|
return;
|
|
194
136
|
}
|
|
195
137
|
const relatedTarget = event.relatedTarget;
|
|
196
|
-
if (!
|
|
197
|
-
|
|
138
|
+
if (!element.nativeElement.contains(relatedTarget)) {
|
|
139
|
+
focus(lastFocusedElement);
|
|
198
140
|
}
|
|
199
141
|
}
|
|
200
142
|
/**
|
|
201
143
|
* If the focused element gets removed from the DOM, browsers move focus back to the document.body.
|
|
202
144
|
* We move focus to the container to keep focus trapped correctly.
|
|
203
145
|
*/
|
|
204
|
-
handleMutations(mutations) {
|
|
146
|
+
function handleMutations(mutations) {
|
|
205
147
|
const focusedElement = document.activeElement;
|
|
206
148
|
if (focusedElement !== document.body) {
|
|
207
149
|
return;
|
|
208
150
|
}
|
|
209
151
|
for (const mutation of mutations) {
|
|
210
152
|
if (mutation.removedNodes.length > 0) {
|
|
211
|
-
|
|
153
|
+
focus(element.nativeElement);
|
|
212
154
|
}
|
|
213
155
|
}
|
|
214
156
|
}
|
|
215
157
|
/**
|
|
216
158
|
* Handles the `keydown` event.
|
|
217
159
|
*/
|
|
218
|
-
handleKeyDown(event) {
|
|
219
|
-
if (!
|
|
160
|
+
function handleKeyDown(event) {
|
|
161
|
+
if (!focusTrap.active || disabled?.()) {
|
|
220
162
|
return;
|
|
221
163
|
}
|
|
222
164
|
const isTabKey = event.key === 'Tab' && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
223
165
|
const focusedElement = document.activeElement;
|
|
224
166
|
if (isTabKey && focusedElement) {
|
|
225
167
|
const container = event.currentTarget;
|
|
226
|
-
const [first, last] =
|
|
168
|
+
const [first, last] = getTabbableEdges(container);
|
|
227
169
|
const hasTabbableElementsInside = first && last;
|
|
228
170
|
// we can only wrap focus if we have tabbable edges
|
|
229
171
|
if (!hasTabbableElementsInside) {
|
|
@@ -234,11 +176,11 @@ class NgpFocusTrap {
|
|
|
234
176
|
else {
|
|
235
177
|
if (!event.shiftKey && focusedElement === last) {
|
|
236
178
|
event.preventDefault();
|
|
237
|
-
|
|
179
|
+
focus(first);
|
|
238
180
|
}
|
|
239
181
|
else if (event.shiftKey && focusedElement === first) {
|
|
240
182
|
event.preventDefault();
|
|
241
|
-
|
|
183
|
+
focus(last);
|
|
242
184
|
}
|
|
243
185
|
}
|
|
244
186
|
}
|
|
@@ -246,19 +188,19 @@ class NgpFocusTrap {
|
|
|
246
188
|
/**
|
|
247
189
|
* Returns the first and last tabbable elements inside a container.
|
|
248
190
|
*/
|
|
249
|
-
getTabbableEdges(container) {
|
|
250
|
-
const candidates =
|
|
251
|
-
const first =
|
|
252
|
-
const last =
|
|
191
|
+
function getTabbableEdges(container) {
|
|
192
|
+
const candidates = getTabbableCandidates(container);
|
|
193
|
+
const first = findVisible(candidates);
|
|
194
|
+
const last = findVisible(candidates.reverse());
|
|
253
195
|
return [first, last];
|
|
254
196
|
}
|
|
255
197
|
/**
|
|
256
198
|
* Returns a list of potential focusable elements inside a container.
|
|
257
199
|
*/
|
|
258
|
-
getTabbableCandidates(container) {
|
|
200
|
+
function getTabbableCandidates(container) {
|
|
259
201
|
const nodes = [];
|
|
260
202
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
261
|
-
acceptNode: (node) =>
|
|
203
|
+
acceptNode: (node) => interactivityChecker.isFocusable(node)
|
|
262
204
|
? NodeFilter.FILTER_ACCEPT
|
|
263
205
|
: NodeFilter.FILTER_SKIP,
|
|
264
206
|
});
|
|
@@ -270,30 +212,64 @@ class NgpFocusTrap {
|
|
|
270
212
|
/**
|
|
271
213
|
* Returns the first visible element in a list..
|
|
272
214
|
*/
|
|
273
|
-
findVisible(elements) {
|
|
274
|
-
return elements.find(element =>
|
|
215
|
+
function findVisible(elements) {
|
|
216
|
+
return elements.find(element => interactivityChecker.isVisible(element)) ?? null;
|
|
275
217
|
}
|
|
276
|
-
focus(element) {
|
|
218
|
+
function focus(element) {
|
|
277
219
|
if (!element) {
|
|
278
220
|
return;
|
|
279
221
|
}
|
|
280
222
|
// Its not great that we are relying on an internal API here, but we need to in order to
|
|
281
223
|
// try and best determine the focus origin when it is programmatically closed by the user.
|
|
282
|
-
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
225
|
+
focusMonitor.focusVia(element, focusMonitor._lastFocusOrigin, {
|
|
283
226
|
preventScroll: true,
|
|
284
227
|
});
|
|
285
228
|
}
|
|
286
|
-
focusFirst() {
|
|
229
|
+
function focusFirst() {
|
|
287
230
|
const previouslyFocusedElement = document.activeElement;
|
|
288
|
-
for (const candidate of
|
|
289
|
-
|
|
231
|
+
for (const candidate of getTabbableCandidates(element.nativeElement)) {
|
|
232
|
+
focus(candidate);
|
|
290
233
|
if (document.activeElement !== previouslyFocusedElement) {
|
|
291
234
|
return;
|
|
292
235
|
}
|
|
293
236
|
}
|
|
294
237
|
}
|
|
238
|
+
// Setup the focus trap
|
|
239
|
+
setupFocusTrap();
|
|
240
|
+
// Teardown the focus trap on destroy
|
|
241
|
+
onDestroy(teardownFocusTrap);
|
|
242
|
+
// Listen to keydown events
|
|
243
|
+
listener(element, 'keydown', handleKeyDown);
|
|
244
|
+
// if this is used within an overlay we must disable the focus trap as soon as the overlay is closing
|
|
245
|
+
overlay?.closing.pipe(safeTakeUntilDestroyed()).subscribe(() => focusTrap.deactivate());
|
|
246
|
+
return {};
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* This implementation is based on the Radix UI FocusScope:
|
|
251
|
+
* https://github.com/radix-ui/primitives/blob/main/packages/react/focus-scope/src/FocusScope.tsx#L306
|
|
252
|
+
*/
|
|
253
|
+
/**
|
|
254
|
+
* The `NgpFocusTrap` directive traps focus within the host element.
|
|
255
|
+
*/
|
|
256
|
+
class NgpFocusTrap {
|
|
257
|
+
/**
|
|
258
|
+
* The focus trap state.
|
|
259
|
+
*/
|
|
260
|
+
constructor() {
|
|
261
|
+
/**
|
|
262
|
+
* Whether the focus trap is disabled.
|
|
263
|
+
*/
|
|
264
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", alias: 'ngpFocusTrapDisabled',
|
|
265
|
+
transform: booleanAttribute }] : [{
|
|
266
|
+
alias: 'ngpFocusTrapDisabled',
|
|
267
|
+
transform: booleanAttribute,
|
|
268
|
+
}]));
|
|
269
|
+
ngpFocusTrap({ disabled: this.disabled });
|
|
270
|
+
}
|
|
295
271
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpFocusTrap, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
296
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpFocusTrap, isStandalone: true, selector: "[ngpFocusTrap]", inputs: { disabled: { classPropertyName: "disabled", publicName: "ngpFocusTrapDisabled", isSignal: true, isRequired: false, transformFunction: null } },
|
|
272
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpFocusTrap, isStandalone: true, selector: "[ngpFocusTrap]", inputs: { disabled: { classPropertyName: "disabled", publicName: "ngpFocusTrapDisabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideFocusTrapState()], exportAs: ["ngpFocusTrap"], ngImport: i0 }); }
|
|
297
273
|
}
|
|
298
274
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpFocusTrap, decorators: [{
|
|
299
275
|
type: Directive,
|
|
@@ -301,19 +277,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
301
277
|
selector: '[ngpFocusTrap]',
|
|
302
278
|
exportAs: 'ngpFocusTrap',
|
|
303
279
|
providers: [provideFocusTrapState()],
|
|
304
|
-
host: {
|
|
305
|
-
'[attr.tabindex]': '-1',
|
|
306
|
-
'[attr.data-focus-trap]': '!disabled() ? "" : null',
|
|
307
|
-
},
|
|
308
280
|
}]
|
|
309
|
-
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpFocusTrapDisabled", required: false }] }]
|
|
310
|
-
type: HostListener,
|
|
311
|
-
args: ['keydown', ['$event']]
|
|
312
|
-
}] } });
|
|
281
|
+
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpFocusTrapDisabled", required: false }] }] } });
|
|
313
282
|
|
|
314
283
|
/**
|
|
315
284
|
* Generated bundle index. Do not edit.
|
|
316
285
|
*/
|
|
317
286
|
|
|
318
|
-
export { NgpFocusTrap, injectFocusTrapState, provideFocusTrapState };
|
|
287
|
+
export { NgpFocusTrap, injectFocusTrapState, ngpFocusTrap, provideFocusTrapState };
|
|
319
288
|
//# sourceMappingURL=ng-primitives-focus-trap.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-primitives-focus-trap.mjs","sources":["../../../../packages/ng-primitives/focus-trap/src/focus-trap/focus-trap-state.ts","../../../../packages/ng-primitives/focus-trap/src/focus-trap/focus-trap.ts","../../../../packages/ng-primitives/focus-trap/src/ng-primitives-focus-trap.ts"],"sourcesContent":["import {\n createState,\n createStateInjector,\n createStateProvider,\n createStateToken,\n} from 'ng-primitives/state';\nimport type { NgpFocusTrap } from './focus-trap';\n\n/**\n * The state token for the FocusTrap primitive.\n */\nexport const NgpFocusTrapStateToken = createStateToken<NgpFocusTrap>('FocusTrap');\n\n/**\n * Provides the FocusTrap state.\n */\nexport const provideFocusTrapState = createStateProvider(NgpFocusTrapStateToken);\n\n/**\n * Injects the FocusTrap state.\n */\nexport const injectFocusTrapState = createStateInjector<NgpFocusTrap>(NgpFocusTrapStateToken);\n\n/**\n * The FocusTrap state registration function.\n */\nexport const focusTrapState = createState(NgpFocusTrapStateToken);\n","import { FocusMonitor, InteractivityChecker } from '@angular/cdk/a11y';\nimport { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n booleanAttribute,\n Directive,\n ElementRef,\n HostListener,\n inject,\n Injector,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { NgpOverlay } from 'ng-primitives/portal';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { focusTrapState, provideFocusTrapState } from './focus-trap-state';\n\n/**\n * This implementation is based on the Radix UI FocusScope:\n * https://github.com/radix-ui/primitives/blob/main/packages/react/focus-scope/src/FocusScope.tsx#L306\n */\n\nclass FocusTrap {\n /**\n * Whether the focus trap is active.\n */\n active: boolean = false;\n\n /**\n * Activates the focus trap.\n */\n activate(): void {\n this.active = true;\n }\n\n /**\n * Deactivates the focus trap.\n */\n deactivate(): void {\n this.active = false;\n }\n}\n\nclass FocusTrapStack {\n /**\n * The stack of focus traps.\n */\n private readonly stack: FocusTrap[] = [];\n\n /**\n * Adds a focus trap to the stack.\n */\n add(focusTrap: FocusTrap): void {\n // deactivate the previous focus trap\n this.stack.forEach(t => t.deactivate());\n\n // add the new focus trap and activate it\n this.stack.push(focusTrap);\n focusTrap.activate();\n }\n\n /**\n * Removes a focus trap from the stack.\n */\n remove(focusTrap: FocusTrap): void {\n // remove the focus trap\n const index = this.stack.indexOf(focusTrap);\n\n if (index >= 0) {\n this.stack.splice(index, 1);\n }\n\n // activate the previous focus trap\n const previous = this.stack[this.stack.length - 1];\n\n if (previous) {\n previous.activate();\n }\n }\n}\n\n// create a global stack of focus traps\nconst focusTrapStack = new FocusTrapStack();\n\n/**\n * The `NgpFocusTrap` directive traps focus within the host element.\n */\n@Directive({\n selector: '[ngpFocusTrap]',\n exportAs: 'ngpFocusTrap',\n providers: [provideFocusTrapState()],\n host: {\n '[attr.tabindex]': '-1',\n '[attr.data-focus-trap]': '!disabled() ? \"\" : null',\n },\n})\nexport class NgpFocusTrap implements OnInit, OnDestroy {\n /**\n * Access any parent overlay.\n */\n private readonly overlay = inject(NgpOverlay, { optional: true });\n\n /**\n * Create a new focus trap.\n */\n private readonly focusTrap = new FocusTrap();\n\n /**\n * Access the injector.\n */\n private readonly injector = inject(Injector);\n\n /**\n * Access the focus monitor.\n */\n private readonly focusMonitor = inject(FocusMonitor);\n\n /**\n * Access the interactivity checker.\n */\n private readonly interactivityChecker = inject(InteractivityChecker);\n\n /**\n * Get the focus trap container element.\n */\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /**\n * Access NgZone to run the focus trap events outside of Angular's zone.\n */\n private readonly ngZone = inject(NgZone);\n\n /**\n * Store the mutation observer.\n */\n private mutationObserver: MutationObserver | null = null;\n\n /**\n * Store the last focused element.\n */\n private lastFocusedElement: HTMLElement | null = null;\n\n /**\n * Whether the focus trap is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFocusTrapDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * The focus trap state.\n */\n protected readonly state = focusTrapState<NgpFocusTrap>(this);\n\n constructor() {\n // if this is used within an overlay we must disable the focus trap as soon as the overlay is closing\n this.overlay?.closing\n .pipe(safeTakeUntilDestroyed())\n .subscribe(() => this.focusTrap.deactivate());\n }\n\n ngOnInit(): void {\n focusTrapStack.add(this.focusTrap);\n\n this.mutationObserver = new MutationObserver(this.handleMutations.bind(this));\n\n // setup event listeners\n this.ngZone.runOutsideAngular(() => {\n this.mutationObserver!.observe(this.elementRef.nativeElement, {\n childList: true,\n subtree: true,\n });\n document.addEventListener('focusin', this.handleFocusIn.bind(this));\n document.addEventListener('focusout', this.handleFocusOut.bind(this));\n });\n\n const previouslyFocusedElement = document.activeElement as HTMLElement | null;\n const hasFocusedCandidate = this.elementRef.nativeElement.contains(previouslyFocusedElement);\n\n if (!hasFocusedCandidate) {\n // we do this to ensure the content is rendered before we try to find the first focusable element\n // and focus it\n afterNextRender(\n {\n write: () => {\n this.focusFirst();\n\n // if the focus didn't change, focus the container\n if (document.activeElement === previouslyFocusedElement) {\n this.focus(this.elementRef.nativeElement);\n }\n },\n },\n { injector: this.injector },\n );\n }\n }\n\n ngOnDestroy(): void {\n focusTrapStack.remove(this.focusTrap);\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n this.focusTrap.deactivate();\n }\n\n private handleFocusIn(event: FocusEvent): void {\n if (!this.focusTrap.active || this.state.disabled()) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n\n if (this.elementRef.nativeElement.contains(target)) {\n this.lastFocusedElement = target;\n } else {\n this.focus(this.lastFocusedElement);\n }\n }\n\n /**\n * Handles the `focusout` event.\n */\n private handleFocusOut(event: FocusEvent) {\n if (!this.focusTrap.active || this.state.disabled() || event.relatedTarget === null) {\n return;\n }\n\n const relatedTarget = event.relatedTarget as HTMLElement;\n\n if (!this.elementRef.nativeElement.contains(relatedTarget)) {\n this.focus(this.lastFocusedElement);\n }\n }\n\n /**\n * If the focused element gets removed from the DOM, browsers move focus back to the document.body.\n * We move focus to the container to keep focus trapped correctly.\n */\n private handleMutations(mutations: MutationRecord[]): void {\n const focusedElement = document.activeElement as HTMLElement | null;\n\n if (focusedElement !== document.body) {\n return;\n }\n\n for (const mutation of mutations) {\n if (mutation.removedNodes.length > 0) {\n this.focus(this.elementRef.nativeElement);\n }\n }\n }\n\n /**\n * Handles the `keydown` event.\n */\n @HostListener('keydown', ['$event'])\n protected handleKeyDown(event: KeyboardEvent): void {\n if (!this.focusTrap.active || this.state.disabled()) {\n return;\n }\n\n const isTabKey = event.key === 'Tab' && !event.altKey && !event.ctrlKey && !event.metaKey;\n const focusedElement = document.activeElement as HTMLElement | null;\n\n if (isTabKey && focusedElement) {\n const container = event.currentTarget as HTMLElement;\n const [first, last] = this.getTabbableEdges(container);\n const hasTabbableElementsInside = first && last;\n\n // we can only wrap focus if we have tabbable edges\n if (!hasTabbableElementsInside) {\n if (focusedElement === container) {\n event.preventDefault();\n }\n } else {\n if (!event.shiftKey && focusedElement === last) {\n event.preventDefault();\n this.focus(first);\n } else if (event.shiftKey && focusedElement === first) {\n event.preventDefault();\n this.focus(last);\n }\n }\n }\n }\n\n /**\n * Returns the first and last tabbable elements inside a container.\n */\n private getTabbableEdges(container: HTMLElement) {\n const candidates = this.getTabbableCandidates(container);\n const first = this.findVisible(candidates);\n const last = this.findVisible(candidates.reverse());\n return [first, last] as const;\n }\n\n /**\n * Returns a list of potential focusable elements inside a container.\n */\n private getTabbableCandidates(container: HTMLElement) {\n const nodes: HTMLElement[] = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node: HTMLElement) =>\n this.interactivityChecker.isFocusable(node)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP,\n });\n while (walker.nextNode()) {\n nodes.push(walker.currentNode as HTMLElement);\n }\n return nodes;\n }\n\n /**\n * Returns the first visible element in a list..\n */\n private findVisible(elements: HTMLElement[]) {\n return elements.find(element => this.interactivityChecker.isVisible(element)) ?? null;\n }\n\n private focus(element: HTMLElement | null): void {\n if (!element) {\n return;\n }\n // Its not great that we are relying on an internal API here, but we need to in order to\n // try and best determine the focus origin when it is programmatically closed by the user.\n this.focusMonitor.focusVia(element, (this.focusMonitor as any)._lastFocusOrigin, {\n preventScroll: true,\n });\n }\n\n private focusFirst(): void {\n const previouslyFocusedElement = document.activeElement;\n\n for (const candidate of this.getTabbableCandidates(this.elementRef.nativeElement)) {\n this.focus(candidate);\n\n if (document.activeElement !== previouslyFocusedElement) {\n return;\n }\n }\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":"ng-primitives-focus-trap.mjs","sources":["../../../../packages/ng-primitives/focus-trap/src/focus-trap/focus-trap-state.ts","../../../../packages/ng-primitives/focus-trap/src/focus-trap/focus-trap.ts","../../../../packages/ng-primitives/focus-trap/src/ng-primitives-focus-trap.ts"],"sourcesContent":["import { FocusMonitor, InteractivityChecker } from '@angular/cdk/a11y';\nimport { afterNextRender, inject, Injector, NgZone, signal, Signal } from '@angular/core';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { NgpOverlay } from 'ng-primitives/portal';\nimport {\n attrBinding,\n createPrimitive,\n dataBinding,\n listener,\n onDestroy,\n} from 'ng-primitives/state';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\n\nclass FocusTrap {\n /**\n * Whether the focus trap is active.\n */\n active: boolean = false;\n\n /**\n * Activates the focus trap.\n */\n activate(): void {\n this.active = true;\n }\n\n /**\n * Deactivates the focus trap.\n */\n deactivate(): void {\n this.active = false;\n }\n}\n\nclass FocusTrapStack {\n /**\n * The stack of focus traps.\n */\n private readonly stack: FocusTrap[] = [];\n\n /**\n * Adds a focus trap to the stack.\n */\n add(focusTrap: FocusTrap): void {\n // deactivate the previous focus trap\n this.stack.forEach(t => t.deactivate());\n\n // add the new focus trap and activate it\n this.stack.push(focusTrap);\n focusTrap.activate();\n }\n\n /**\n * Removes a focus trap from the stack.\n */\n remove(focusTrap: FocusTrap): void {\n // remove the focus trap\n const index = this.stack.indexOf(focusTrap);\n\n if (index >= 0) {\n this.stack.splice(index, 1);\n }\n\n // activate the previous focus trap\n const previous = this.stack[this.stack.length - 1];\n\n if (previous) {\n previous.activate();\n }\n }\n}\n\n// create a global stack of focus traps\nconst focusTrapStack = new FocusTrapStack();\n\n/**\n * The state for the FocusTrap primitive.\n */\nexport interface NgpFocusTrapState {\n // No public API\n}\n\n/**\n * The props for the FocusTrap primitive.\n */\nexport interface NgpFocusTrapProps {\n /**\n * Whether the focus trap is disabled.\n */\n readonly disabled?: Signal<boolean>;\n}\n\nexport const [NgpFocusTrapStateToken, ngpFocusTrap, injectFocusTrapState, provideFocusTrapState] =\n createPrimitive('NgpFocusTrap', ({ disabled = signal(false) }: NgpFocusTrapProps) => {\n const element = injectElementRef();\n const overlay = inject(NgpOverlay, { optional: true });\n const injector = inject(Injector);\n const focusMonitor = inject(FocusMonitor);\n const interactivityChecker = inject(InteractivityChecker);\n const ngZone = inject(NgZone);\n\n // Create a new focus trap\n const focusTrap = new FocusTrap();\n\n // Store the mutation observer\n let mutationObserver: MutationObserver | null = null;\n\n // Store the last focused element\n let lastFocusedElement: HTMLElement | null = null;\n\n // Host bindings\n attrBinding(element, 'tabindex', '-1');\n dataBinding(element, 'data-focus-trap', () => (disabled() ? null : ''));\n\n // Setup the focus trap\n function setupFocusTrap(): void {\n focusTrapStack.add(focusTrap);\n\n mutationObserver = new MutationObserver(handleMutations);\n\n // Setup event listeners\n ngZone.runOutsideAngular(() => {\n mutationObserver!.observe(element.nativeElement, {\n childList: true,\n subtree: true,\n });\n document.addEventListener('focusin', handleFocusIn);\n document.addEventListener('focusout', handleFocusOut);\n });\n\n const previouslyFocusedElement = document.activeElement as HTMLElement | null;\n const hasFocusedCandidate = element.nativeElement.contains(previouslyFocusedElement);\n\n if (!hasFocusedCandidate) {\n // we do this to ensure the content is rendered before we try to find the first focusable element\n // and focus it\n afterNextRender(\n {\n write: () => {\n focusFirst();\n\n // if the focus didn't change, focus the container\n if (document.activeElement === previouslyFocusedElement) {\n focus(element.nativeElement);\n }\n },\n },\n { injector },\n );\n }\n }\n\n function teardownFocusTrap(): void {\n focusTrapStack.remove(focusTrap);\n mutationObserver?.disconnect();\n mutationObserver = null;\n focusTrap.deactivate();\n\n // Remove event listeners\n document.removeEventListener('focusin', handleFocusIn);\n document.removeEventListener('focusout', handleFocusOut);\n }\n\n function handleFocusIn(event: FocusEvent): void {\n if (!focusTrap.active || disabled?.()) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n\n if (element.nativeElement.contains(target)) {\n lastFocusedElement = target;\n } else {\n focus(lastFocusedElement);\n }\n }\n\n /**\n * Handles the `focusout` event.\n */\n function handleFocusOut(event: FocusEvent) {\n if (!focusTrap.active || disabled?.() || event.relatedTarget === null) {\n return;\n }\n\n const relatedTarget = event.relatedTarget as HTMLElement;\n\n if (!element.nativeElement.contains(relatedTarget)) {\n focus(lastFocusedElement);\n }\n }\n\n /**\n * If the focused element gets removed from the DOM, browsers move focus back to the document.body.\n * We move focus to the container to keep focus trapped correctly.\n */\n function handleMutations(mutations: MutationRecord[]): void {\n const focusedElement = document.activeElement as HTMLElement | null;\n\n if (focusedElement !== document.body) {\n return;\n }\n\n for (const mutation of mutations) {\n if (mutation.removedNodes.length > 0) {\n focus(element.nativeElement);\n }\n }\n }\n\n /**\n * Handles the `keydown` event.\n */\n function handleKeyDown(event: KeyboardEvent): void {\n if (!focusTrap.active || disabled?.()) {\n return;\n }\n\n const isTabKey = event.key === 'Tab' && !event.altKey && !event.ctrlKey && !event.metaKey;\n const focusedElement = document.activeElement as HTMLElement | null;\n\n if (isTabKey && focusedElement) {\n const container = event.currentTarget as HTMLElement;\n const [first, last] = getTabbableEdges(container);\n const hasTabbableElementsInside = first && last;\n\n // we can only wrap focus if we have tabbable edges\n if (!hasTabbableElementsInside) {\n if (focusedElement === container) {\n event.preventDefault();\n }\n } else {\n if (!event.shiftKey && focusedElement === last) {\n event.preventDefault();\n focus(first);\n } else if (event.shiftKey && focusedElement === first) {\n event.preventDefault();\n focus(last);\n }\n }\n }\n }\n\n /**\n * Returns the first and last tabbable elements inside a container.\n */\n function getTabbableEdges(container: HTMLElement) {\n const candidates = getTabbableCandidates(container);\n const first = findVisible(candidates);\n const last = findVisible(candidates.reverse());\n return [first, last] as const;\n }\n\n /**\n * Returns a list of potential focusable elements inside a container.\n */\n function getTabbableCandidates(container: HTMLElement) {\n const nodes: HTMLElement[] = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node: HTMLElement) =>\n interactivityChecker.isFocusable(node)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP,\n });\n while (walker.nextNode()) {\n nodes.push(walker.currentNode as HTMLElement);\n }\n return nodes;\n }\n\n /**\n * Returns the first visible element in a list..\n */\n function findVisible(elements: HTMLElement[]) {\n return elements.find(element => interactivityChecker.isVisible(element)) ?? null;\n }\n\n function focus(element: HTMLElement | null): void {\n if (!element) {\n return;\n }\n // Its not great that we are relying on an internal API here, but we need to in order to\n // try and best determine the focus origin when it is programmatically closed by the user.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n focusMonitor.focusVia(element, (focusMonitor as any)._lastFocusOrigin, {\n preventScroll: true,\n });\n }\n\n function focusFirst(): void {\n const previouslyFocusedElement = document.activeElement;\n\n for (const candidate of getTabbableCandidates(element.nativeElement)) {\n focus(candidate);\n\n if (document.activeElement !== previouslyFocusedElement) {\n return;\n }\n }\n }\n\n // Setup the focus trap\n setupFocusTrap();\n\n // Teardown the focus trap on destroy\n onDestroy(teardownFocusTrap);\n\n // Listen to keydown events\n listener(element, 'keydown', handleKeyDown);\n\n // if this is used within an overlay we must disable the focus trap as soon as the overlay is closing\n overlay?.closing.pipe(safeTakeUntilDestroyed()).subscribe(() => focusTrap.deactivate());\n\n return {};\n });\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input } from '@angular/core';\nimport { ngpFocusTrap, provideFocusTrapState } from './focus-trap-state';\n\n/**\n * This implementation is based on the Radix UI FocusScope:\n * https://github.com/radix-ui/primitives/blob/main/packages/react/focus-scope/src/FocusScope.tsx#L306\n */\n\n/**\n * The `NgpFocusTrap` directive traps focus within the host element.\n */\n@Directive({\n selector: '[ngpFocusTrap]',\n exportAs: 'ngpFocusTrap',\n providers: [provideFocusTrapState()],\n})\nexport class NgpFocusTrap {\n /**\n * Whether the focus trap is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpFocusTrapDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * The focus trap state.\n */\n constructor() {\n ngpFocusTrap({ disabled: this.disabled });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|