@yuuvis/client-framework 2.6.2 → 2.7.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/common/lib/components/busy-overlay/busy-overlay.component.d.ts +0 -1
- package/common/lib/directives/busy-overlay.directive.d.ts +4 -4
- package/fesm2022/yuuvis-client-framework-common.mjs +9 -15
- package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-forms.mjs +7 -4
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-list.mjs +92 -58
- package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs +2 -2
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-summary.mjs +4 -2
- package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +269 -0
- package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -0
- package/fesm2022/yuuvis-client-framework-renderer.mjs +4 -9
- package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +97 -208
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tree.mjs +8 -5
- package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework.mjs +727 -132
- package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
- package/lib/assets/i18n/en.json +19 -19
- package/lib/config/halo-focus-defaults/halo-excluded-elements.const.d.ts +26 -0
- package/lib/config/halo-focus-defaults/halo-focus-navigation-keys.const.d.ts +25 -0
- package/lib/config/halo-focus-defaults/halo-focus-offset.const.d.ts +25 -0
- package/lib/config/halo-focus-defaults/halo-focus-styles.const.d.ts +26 -0
- package/lib/config/halo-focus-defaults/index.d.ts +4 -0
- package/lib/config/index.d.ts +1 -0
- package/lib/models/halo-focus-config/halo-focus-config.model.d.ts +48 -0
- package/lib/models/halo-focus-config/index.d.ts +1 -0
- package/lib/models/index.d.ts +1 -0
- package/lib/providers/halo-focus/index.d.ts +1 -0
- package/lib/providers/halo-focus/provide-halo-focus.d.ts +58 -6
- package/lib/providers/index.d.ts +1 -1
- package/lib/services/halo-focus/halo-focus.service.d.ts +89 -1
- package/lib/services/halo-utility/halo-utility.service.d.ts +230 -0
- package/lib/services/index.d.ts +1 -0
- package/list/lib/list.component.d.ts +35 -6
- package/package.json +24 -20
- package/query-list/README.md +3 -0
- package/query-list/index.d.ts +2 -0
- package/query-list/lib/query-list.component.d.ts +139 -0
- package/query-list/lib/query-list.module.d.ts +7 -0
- package/renderer/lib/property-renderer/organization.renderer.d.ts +1 -1
- package/tile-list/lib/tile-config/property-select/property-select.component.d.ts +3 -1
- package/tile-list/lib/tile-list/tile-list.component.d.ts +52 -34
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yuuvis-client-framework.mjs","sources":["../../../../../libs/yuuvis/client-framework/src/lib/yuuvis-client-framework.module.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/halo-focus/halo-focus.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/snack-bar/snack-bar.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/providers/halo-focus/provide-halo-focus.ts","../../../../../libs/yuuvis/client-framework/src/yuuvis-client-framework.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class YuuvisClientFrameworkModule {}\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class HaloFocusService {\n #haloEl: HTMLDivElement | null = null;\n #currentEl: HTMLElement | null = null;\n #rafId: number | null = null; //Request Animation Frame ID\n #resizeObserver?: ResizeObserver;\n #mutationObserver?: MutationObserver;\n\n readonly #defaultPadding = 3;\n readonly #noPaddingComponents = ['yuv-shell-logo'];\n\n init() {\n this.#appendHaloElementToDOM();\n this.#initListeners();\n this.#initObservers();\n }\n\n #appendHaloElementToDOM(): void {\n this.#haloEl = document.createElement('div');\n this.#haloEl.id = 'focus-halo';\n this.#haloEl.setAttribute('aria-hidden', 'true');\n Object.assign(this.#haloEl.style, {\n position: 'fixed',\n pointerEvents: 'none',\n zIndex: '9999',\n border: '2px solid var(--ymt-primary)',\n boxShadow: '0 0 0 4px rgba(from var(--ymt-primary) r g b / 0.2)',\n borderRadius: '8px',\n opacity: '0',\n transform: 'translateZ(0)'\n // transition: 'opacity 120ms ease, transform 120ms ease, width 120ms ease, height 120ms ease, left 120ms ease, top 120ms ease'\n });\n document.body.appendChild(this.#haloEl);\n }\n\n #initListeners(): void {\n document.addEventListener('focus', this.#onFocus, true);\n document.addEventListener('blur', this.#onBlur, true);\n window.addEventListener('scroll', this.#scheduleUpdate, true);\n window.addEventListener('resize', this.#scheduleUpdate);\n document.addEventListener('keydown', this.#onKeydown, true);\n }\n\n #initObservers(): void {\n if ('ResizeObserver' in window) {\n this.#resizeObserver = new ResizeObserver(() => {\n if (this.#currentEl) this.#scheduleUpdate();\n });\n }\n\n if ('MutationObserver' in window) {\n this.#mutationObserver = new MutationObserver(() => {\n if (this.#currentEl) this.#scheduleUpdate();\n });\n }\n }\n\n #isFocusable(el: Element | null): el is HTMLElement {\n if (!el) return false;\n const h = el as HTMLElement;\n if (h.tabIndex >= 0) return true;\n return /^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(h.tagName) || h.isContentEditable;\n }\n\n #matchesFocusVisible(el: HTMLElement): boolean {\n try {\n return el.matches(':focus-visible');\n } catch {\n return true;\n }\n }\n\n #isElementVisible(el: HTMLElement): boolean {\n const rect = el.getBoundingClientRect();\n\n // Check if element has dimensions\n if (rect.width === 0 || rect.height === 0) {\n return false;\n }\n\n // Check computed style on element itself\n const style = getComputedStyle(el);\n if (style.visibility === 'hidden' || style.display === 'none' || parseFloat(style.opacity) === 0) {\n return false;\n }\n\n // Check if element is clipped by overflow:hidden parent OR if any parent is hidden\n return this.#isParentVisible(el, rect);\n }\n\n #isParentVisible(el: HTMLElement, rect: DOMRect): boolean {\n let parent = el.parentElement;\n while (parent && parent !== document.body) {\n const parentStyle = getComputedStyle(parent);\n\n // Check if parent is hidden\n if (parentStyle.display === 'none' || parentStyle.visibility === 'hidden' || parseFloat(parentStyle.opacity) === 0) {\n return false;\n }\n\n const parentOverflow = parentStyle.overflow + parentStyle.overflowX + parentStyle.overflowY;\n\n if (parentOverflow.includes('hidden') || parentOverflow.includes('clip')) {\n const parentRect = parent.getBoundingClientRect();\n // Calculate intersection - if there's no visible area, element is hidden\n const visibleRight = Math.min(rect.right, parentRect.right);\n const visibleLeft = Math.max(rect.left, parentRect.left);\n const visibleBottom = Math.min(rect.bottom, parentRect.bottom);\n const visibleTop = Math.max(rect.top, parentRect.top);\n\n const visibleWidth = visibleRight - visibleLeft;\n const visibleHeight = visibleBottom - visibleTop;\n\n // If no intersection or intersection is too small (less than 1px), element is not visible\n if (visibleWidth <= 0 || visibleHeight <= 0) {\n return false;\n }\n }\n parent = parent.parentElement;\n }\n return true;\n }\n\n #updateHaloRect = () => {\n if (!this.#currentEl || !this.#haloEl || !document.contains(this.#currentEl)) {\n this.#haloEl && (this.#haloEl.style.opacity = '0');\n this.#currentEl = null;\n return;\n }\n\n // Check if element is actually visible\n if (!this.#isElementVisible(this.#currentEl)) {\n this.#haloEl.style.opacity = '0';\n return;\n }\n\n const rect = this.#currentEl.getBoundingClientRect();\n const padding = this.#getTargetPadding();\n\n const left = Math.floor(rect.left - padding);\n const top = Math.floor(rect.top - padding);\n const width = Math.ceil(rect.width + padding * 2);\n const height = Math.ceil(rect.height + padding * 2);\n\n const cs = getComputedStyle(this.#currentEl);\n this.#haloEl.style.left = `${left}px`;\n this.#haloEl.style.top = `${top}px`;\n this.#haloEl.style.width = `${width}px`;\n this.#haloEl.style.height = `${height}px`;\n this.#haloEl.style.borderRadius = cs.borderRadius || '8px';\n this.#haloEl.style.opacity = '1';\n };\n\n #getTargetPadding(): number {\n const parent = this.#currentEl?.parentElement;\n if (parent && this.#noPaddingComponents.includes(parent.nodeName.toLowerCase())) {\n return 0;\n }\n return this.#defaultPadding;\n }\n\n #scheduleUpdate = () => {\n if (this.#rafId != null) cancelAnimationFrame(this.#rafId);\n this.#rafId = requestAnimationFrame(this.#updateHaloRect);\n };\n\n #onKeydown = (e: KeyboardEvent) => {\n // Track arrow keys and other navigation keys that might move focused element\n const navigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown'];\n if (this.#currentEl && navigationKeys.includes(e.key)) {\n this.#scheduleUpdate();\n }\n };\n\n #startTracking(target: HTMLElement) {\n this.#currentEl = target;\n this.#scheduleUpdate();\n\n // Track size changes on target element\n if (this.#resizeObserver) {\n this.#resizeObserver.observe(target);\n\n // Also observe all parent elements with overflow (they might clip the element)\n let parent = target.parentElement;\n while (parent && parent !== document.body) {\n const style = getComputedStyle(parent);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n if (overflow.includes('hidden') || overflow.includes('clip') || overflow.includes('auto') || overflow.includes('scroll')) {\n this.#resizeObserver.observe(parent);\n }\n parent = parent.parentElement;\n }\n }\n\n // Track style/attribute changes (for position, transform changes)\n if (this.#mutationObserver) {\n this.#mutationObserver.observe(target, {\n attributes: true,\n attributeFilter: ['style', 'class'],\n subtree: false\n });\n }\n }\n\n #stopTracking() {\n if (this.#resizeObserver) this.#resizeObserver.disconnect();\n if (this.#mutationObserver) this.#mutationObserver.disconnect();\n }\n\n #onFocus = (e: FocusEvent) => {\n const target = e.target as HTMLElement;\n if (!this.#isFocusable(target)) return;\n if (!this.#matchesFocusVisible(target)) {\n this.#haloEl && (this.#haloEl.style.opacity = '0');\n this.#currentEl = null;\n return;\n }\n this.#stopTracking();\n this.#startTracking(target);\n };\n\n #onBlur = (e: FocusEvent) => {\n if ((e.target as HTMLElement) === this.#currentEl && this.#haloEl) {\n this.#haloEl.style.opacity = '0';\n this.#currentEl = null;\n this.#stopTracking();\n }\n };\n\n /** Optional: allow manual control from directives/components */\n // public showFor(el: HTMLElement) {\n // this.#currentEl = el;\n // this.#scheduleUpdate();\n // if (this.#ro) {\n // this.#ro.disconnect();\n // this.#ro.observe(el);\n // }\n // }\n\n // public hide() {\n // if (this.#haloEl) this.#haloEl.style.opacity = '0';\n // this.#currentEl = null;\n // if (this.#ro) this.#ro.disconnect();\n // }\n}\n","import { Component, inject, Injectable, signal } from '@angular/core';\nimport { MAT_SNACK_BAR_DATA, MatSnackBar, MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel, MatSnackBarRef } from '@angular/material/snack-bar';\nimport { SnackBarData, SnackBarLevel, SnackBarOptions } from './snack-bar.interface';\nimport { MatButtonModule } from '@angular/material/button';\n@Injectable({\n providedIn: 'root'\n})\nexport class SnackBarService {\n #snackBar = inject(MatSnackBar);\n\n info(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'info' });\n }\n\n success(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'success' });\n }\n\n warning(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'warning' });\n }\n\n danger(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'danger' });\n }\n\n snack(message: string, options: SnackBarOptions): MatSnackBarRef<SnackBarComponent> {\n return this.#snackBar.openFromComponent(SnackBarComponent, {\n data: {\n level: options.level,\n message,\n action: options.action\n },\n duration: options.duration || 3000,\n horizontalPosition: options.horizontalPosition,\n verticalPosition: options.verticalPosition,\n panelClass: ['yuv-snack-bar', 'level-' + options.level]\n });\n }\n}\n\n@Component({\n selector: 'yuv-snack-bar-component',\n template: `\n <span matSnackBarLabel (click)=\"dismiss()\"> {{ message() }} </span>\n @let a = action();\n @if (a) {\n <span matSnackBarActions>\n <button mat-button matSnackBarAction (click)=\"dismiss(!!a)\">{{ action() }}</button>\n </span>\n }\n `,\n styles: `\n :host {\n display: flex;\n }\n `,\n imports: [MatButtonModule, MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction],\n host: {\n '[class.info]': \"level() === 'info'\",\n '[class.success]': \"level() === 'success'\",\n '[class.warning]': \"level() === 'warning'\",\n '[class.danger]': \"level() === 'danger'\"\n }\n})\nexport class SnackBarComponent {\n #snackBarRef = inject(MatSnackBarRef);\n #snackData = inject<SnackBarData>(MAT_SNACK_BAR_DATA);\n level = signal<SnackBarLevel>(this.#snackData.level);\n message = signal<string>(this.#snackData.message);\n action = signal<string | undefined>(this.#snackData.action);\n\n dismiss(withAction = false) {\n if (withAction) {\n this.#snackBarRef.dismissWithAction();\n } else if (!this.action()) {\n this.#snackBarRef.dismiss();\n }\n }\n}\n","import { EnvironmentProviders, inject, NgZone, provideAppInitializer } from '@angular/core';\nimport { HaloFocusService } from '../../services';\n\n/**\n * Provides and initializes the HaloFocusService.\n * By calling this function in your ApplicationConfig providers,\n * the Halo Focus feature will be activated, allowing users to see a visual focus indicator.\n * The service will be initialized outside Angular zone for optimal performance.\n *\n * @returns EnvironmentProviders\n */\nexport function provideHaloFocus(): EnvironmentProviders {\n return provideAppInitializer(() => {\n const zone = inject(NgZone);\n const haloFocus = inject(HaloFocusService);\n zone.runOutsideAngular(() => haloFocus.init());\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":"yuuvis-client-framework.mjs","sources":["../../../../../libs/yuuvis/client-framework/src/lib/yuuvis-client-framework.module.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-excluded-elements.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-navigation-keys.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-offset.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-styles.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/halo-focus/halo-focus.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/snack-bar/snack-bar.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/halo-utility/halo-utility.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/providers/halo-focus/provide-halo-focus.ts","../../../../../libs/yuuvis/client-framework/src/yuuvis-client-framework.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class YuuvisClientFrameworkModule {}\n","/**\n * List of element selectors that should be excluded from halo focus\n * when they are inside a Material form field component (mat-form-field).\n *\n * These elements typically have their own built-in focus indicators provided\n * by Angular Material, making the halo focus redundant or visually conflicting.\n *\n * **Included Selectors:**\n * - `input` - Text inputs, number inputs, etc. inside mat-form-field\n * - `textarea` - Multi-line text inputs inside mat-form-field\n * - `mat-select` - Material select dropdowns inside mat-form-field\n *\n * **Why Exclude These:**\n * Angular Material form fields provide their own focus styling with floating labels,\n * underlines, and color changes. Adding a halo around these elements would:\n * - Create visual clutter and redundancy\n * - Potentially conflict with Material's focus styling\n * - Reduce the clarity of Material Design's established patterns\n *\n * **Note:** These elements will still receive halo focus if they appear OUTSIDE\n * of mat-form-field containers. The exclusion only applies when they're wrapped\n * in a mat-form-field.\n *\n * @see {@link HaloUtilityService.shouldSkipElementInMatFormField} for implementation\n */\nexport const haloExcludedElementsInMatFormField = ['input', 'textarea', 'mat-select'];\n","/**\n * List of keyboard navigation keys that trigger halo position updates.\n *\n * When any of these keys are pressed while an element is focused, the halo service\n * schedules an immediate position update to ensure the halo follows the focused element\n * if it moves within the page (e.g., scrolling a list, moving through a table).\n *\n * **Included Keys:**\n * - `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown` - Directional navigation\n * - `Home`, `End` - Jump to start/end of content\n * - `PageUp`, `PageDown` - Page-level scrolling\n *\n * **Why This Matters:**\n * Arrow keys and navigation keys can cause the focused element to scroll or move within\n * its container (e.g., scrolling a select dropdown, moving focus in a grid). By tracking\n * these keys, the halo can immediately update its position to follow the element, preventing\n * visual misalignment.\n *\n * **Performance Note:**\n * Updates are scheduled using requestAnimationFrame, so even rapid key presses won't\n * cause performance issues.\n *\n * @see {@link HaloFocusService} for the implementation of keydown handling\n */\nexport const haloFocusNavigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown'];\n","/**\n * Default offset (in pixels) between the halo border and the focused element's edges.\n *\n * This value determines how far the halo appears from the focused element:\n * - **Positive value** (default: 3): Halo appears outside the element\n * - **Zero (0)**: Halo aligns exactly with element edges (neutral offset)\n * - **Negative value**: Halo appears inside the element (inset)\n *\n * **Override Methods:**\n * - **Per-element**: Use `halo-offset=\"value\"` attribute\n * - **Per-container**: Use `halo-container-offset=\"value\"` or preset attributes\n *\n * @example\n * ```html\n * <!-- Uses default 3px offset (outside) -->\n * <button>Default</button>\n *\n * <!-- Custom 5px offset -->\n * <input halo-offset=\"5\" />\n *\n * ```\n *\n * @default 3\n */\nexport const defaultHaloFocusOffset = 3;\n","/**\n * Default CSS styles for the halo focus element.\n *\n * These styles define the visual appearance and behavior of the halo border that\n * highlights keyboard-focused elements. The halo is a fixed-position overlay that\n * follows the focused element across the page.\n *\n * **Style Properties:**\n * - `position: 'fixed'` - Keeps halo in viewport regardless of scroll position\n * - `pointerEvents: 'none'` - Allows click-through; halo doesn't block interactions\n * - `zIndex: '9999'` - Ensures halo appears above most other elements\n * - `border` - Primary border using CSS variable `--ymt-primary` (2px solid)\n * - `boxShadow` - Soft shadow with 20% opacity for subtle depth effect\n * - `borderRadius` - Default 8px rounded corners for modern appearance\n * - `opacity: '0'` - Initially hidden; visibility controlled by service\n * - `transform: 'translateZ(0)'` - Creates GPU layer for smoother animations\n *\n * **CSS Variable Dependencies:**\n * - `--ymt-primary` - Primary theme color for border and shadow\n *\n * **Note:** These are base styles that can be overridden globally via HaloFocusConfig\n * or per-element using halo-* attributes.\n *\n * @see {@link HaloFocusConfig} for global style customization\n */\nexport const haloFocusStyles: Partial<CSSStyleDeclaration> = {\n position: 'fixed',\n pointerEvents: 'none',\n zIndex: '9999',\n border: '2px solid var(--ymt-primary)',\n boxShadow: '0 0 0 4px rgba(from var(--ymt-primary) r g b / 0.2)',\n borderRadius: '8px',\n opacity: '0',\n transform: 'translateZ(0)'\n};\n","import { inject, Injectable } from '@angular/core';\nimport { HaloFocusConfig } from '../../models';\nimport { HaloUtilityService } from '..';\nimport { haloFocusNavigationKeys } from '../../config';\n\n/**\n * Service that creates and manages a visual \"halo\" border around keyboard-focused elements\n * to enhance navigation visibility and improve accessibility.\n *\n * This service operates globally across the application, automatically tracking focus events\n * and dynamically positioning a halo element around the currently focused element. The halo\n * responds to window scrolls, resizes, and DOM mutations to maintain accurate positioning.\n *\n * **Key Features:**\n * - Keyboard-only focus indication (respects :focus-visible)\n * - Performance-optimized with requestAnimationFrame and runs outside Angular zone\n * - Element-level and container-level customization support\n * - Automatic visibility detection (handles clipping, hidden elements, etc.)\n * - Responsive to dynamic DOM changes via ResizeObserver and MutationObserver\n * - Smart exclusion for Angular Material form fields (prevents redundant styling)\n *\n * **Usage:**\n * 1. Add `provideHaloFocus()` to your providers array in app.config.ts\n * 2. The service initializes automatically and appends a halo element to the DOM\n * 3. Optionally customize appearance globally or per-element using attributes\n *\n * **Element-Level Attributes:**\n * - `halo-skip` - Excludes element from halo highlighting\n * - `halo-color=\"color\"` - Custom halo color (e.g., \"blue\", \"#00ff00\", \"rgb(255,0,0)\")\n * - `halo-offset=\"value\"` - Custom numeric offset in pixels (default: 3)\n *\n * **Container-Level Attributes:**\n * Define default halo styles for all focused children. Child elements can override\n * container settings with their own halo-* attributes.\n *\n * - `halo-container` - Marks element as a halo container (required for other attributes)\n * - `halo-container-skip` - Excludes all focused children from halo highlighting\n * - `halo-container-color=\"color\"` - Default halo color for focused children\n * - `halo-container-offset=\"value\"` - Default offset for focused children\n *\n * **Material Form Field Integration:**\n * Elements inside Angular Material form fields (mat-form-field) are automatically excluded\n * from halo focus to prevent visual conflicts with Material's built-in focus styling.\n * Excluded elements: input, mat-select (configurable via haloExcludedElementsInMatFormField)\n *\n * @example\n * ```html\n * <!-- Element-level customization -->\n * <button halo-color=\"red\">Custom Red Halo</button>\n * <input halo-offset=\"5\" />\n * <select halo-skip>No Halo</select>\n *\n * <!-- Container-level defaults -->\n * <form halo-container halo-container-color=\"blue\" halo-container-offset=\"5\">\n * <input /> <!-- Inherits blue color and 5px offset -->\n * <button halo-color=\"red\">Submit</button> <!-- Overrides with red, keeps 5px offset -->\n * </form>\n * ```\n *\n * **Performance Notes:**\n * - Service runs outside Angular's zone to prevent unnecessary change detection\n * - Uses requestAnimationFrame for smooth rendering\n * - Only shows halo for keyboard interactions (respects :focus-visible)\n *\n * @see {@link provideHaloFocus} for initialization and configuration\n * @see {@link HaloFocusConfig} for global configuration options\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class HaloFocusService {\n //#region Properties\n\n #utility = inject(HaloUtilityService);\n #config: HaloFocusConfig | undefined;\n\n #haloElement: HTMLDivElement | null = null;\n #currentElement: HTMLElement | null = null;\n #lastInteractionWasKeyboard = false;\n\n #rafId: number | null = null; //Request Animation Frame ID\n #resizeObserver?: ResizeObserver;\n #mutationObserver?: MutationObserver;\n\n //#endregion\n\n //#region Init\n\n /**\n * Initializes the Halo Focus service and sets up the global halo tracking system.\n *\n * This method performs the following initialization steps:\n * 1. Applies optional configuration for halo appearance (inner and outer colors)\n * 2. Creates and appends the halo DIV element to the document body\n * 3. Attaches global event listeners for focus, blur, keyboard, mouse, scroll, and resize events\n * 4. Sets up ResizeObserver and MutationObserver for tracking dynamic DOM changes\n *\n * **Lifecycle:**\n * - Called automatically by `provideHaloFocus()` during app initialization\n * - Runs outside Angular's zone to prevent triggering change detection\n * - Initializes only once per application lifecycle\n *\n * **Performance:**\n * - Uses passive event listeners where applicable\n * - Leverages requestAnimationFrame for efficient rendering\n * - Observers are conditionally created only if browser supports them\n *\n * @param config - Optional configuration object for customizing halo appearance\n * @param config.innerColor - Custom inner color (overrides default primary color)\n * @param config.outerColor - Custom outer color (overrides default shadow)\n *\n * @internal This method should not be called manually; use `provideHaloFocus()` instead\n */\n public init(config?: HaloFocusConfig): void {\n this.#initConfig(config);\n this.#appendHaloElementToDOM();\n this.#initListeners();\n this.#initObservers();\n }\n\n #initConfig(config?: HaloFocusConfig): void {\n this.#config = config;\n }\n\n #appendHaloElementToDOM(): void {\n this.#haloElement = document.createElement('div');\n this.#haloElement.id = 'focus-halo';\n this.#haloElement.setAttribute('aria-hidden', 'true');\n Object.assign(this.#haloElement.style, this.#utility.getHaloFocusStyles(this.#config));\n document.body.appendChild(this.#haloElement);\n }\n\n #initListeners(): void {\n document.addEventListener('focus', this.#onFocus, true);\n document.addEventListener('blur', this.#onBlur, true);\n window.addEventListener('scroll', this.#scheduleUpdate, true);\n window.addEventListener('resize', this.#scheduleUpdate);\n document.addEventListener('keydown', this.#onKeydown, true);\n document.addEventListener('mousedown', this.#onMouseDown, true);\n }\n\n #initObservers(): void {\n if ('ResizeObserver' in window) {\n this.#resizeObserver = new ResizeObserver(() => {\n if (this.#currentElement) this.#scheduleUpdate();\n });\n }\n\n if ('MutationObserver' in window) {\n this.#mutationObserver = new MutationObserver(() => {\n if (this.#currentElement) this.#scheduleUpdate();\n });\n }\n }\n\n // #endregion\n\n //#region Rendering\n\n #updateHaloRect = () => {\n if (!this.#currentElement || !this.#haloElement || !document.contains(this.#currentElement)) {\n this.#haloElement && (this.#haloElement.style.opacity = '0');\n this.#currentElement = null;\n return;\n }\n\n // Check if element is actually visible\n if (!this.#utility.isElementVisible(this.#currentElement)) {\n this.#haloElement.style.opacity = '0';\n return;\n }\n\n this.#utility.setHaloElementSize(this.#currentElement, this.#haloElement);\n this.#utility.setCustomColor(this.#currentElement, this.#haloElement, this.#config);\n this.#haloElement.style.opacity = '1';\n };\n\n #scheduleUpdate = () => {\n if (this.#rafId != null) cancelAnimationFrame(this.#rafId);\n this.#rafId = requestAnimationFrame(this.#updateHaloRect);\n };\n\n #startTracking(target: HTMLElement) {\n this.#currentElement = target;\n this.#scheduleUpdate();\n\n // Track size changes on target element\n if (this.#resizeObserver) {\n this.#resizeObserver.observe(target);\n\n // Also observe all parent elements with overflow (they might clip the element)\n let parent = target.parentElement;\n while (parent && parent !== document.body) {\n const style = getComputedStyle(parent);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n if (overflow.includes('hidden') || overflow.includes('clip') || overflow.includes('auto') || overflow.includes('scroll')) {\n this.#resizeObserver.observe(parent);\n }\n parent = parent.parentElement;\n }\n }\n\n // Track style/attribute changes (for position, transform changes)\n if (this.#mutationObserver) {\n this.#mutationObserver.observe(target, {\n attributes: true,\n attributeFilter: ['style', 'class'],\n subtree: false\n });\n }\n }\n\n #stopTracking() {\n if (this.#resizeObserver) this.#resizeObserver.disconnect();\n if (this.#mutationObserver) this.#mutationObserver.disconnect();\n }\n //#endregion\n\n //#region Event handlers\n\n #onKeydown = (e: KeyboardEvent) => {\n this.#lastInteractionWasKeyboard = true;\n // Track arrow keys and other navigation keys that might move focused element\n if (this.#currentElement && haloFocusNavigationKeys.includes(e.key)) {\n this.#scheduleUpdate();\n }\n };\n\n #onMouseDown = () => {\n this.#lastInteractionWasKeyboard = false;\n if (this.#haloElement) {\n this.#haloElement.style.opacity = '0';\n this.#currentElement = null;\n this.#stopTracking();\n }\n };\n\n #onFocus = (e: FocusEvent) => {\n const target = e.target as HTMLElement;\n if (!this.#utility.isFocusable(target)) return;\n\n const container = this.#utility.getHaloContainer(target);\n\n // Check all skip conditions\n if (\n target.hasAttribute('halo-skip') ||\n this.#utility.shouldSkipElementInMatFormField(target) ||\n (container && container.hasAttribute('halo-container-skip')) ||\n !this.#utility.matchesFocusVisible(target, this.#lastInteractionWasKeyboard)\n ) {\n this.#haloElement && (this.#haloElement.style.opacity = '0');\n this.#currentElement = null;\n return;\n }\n\n this.#stopTracking();\n this.#startTracking(target);\n };\n\n #onBlur = (e: FocusEvent) => {\n if ((e.target as HTMLElement) === this.#currentElement && this.#haloElement) {\n this.#haloElement.style.opacity = '0';\n this.#currentElement = null;\n this.#stopTracking();\n }\n };\n\n //#endregion\n\n /** Optional: allow manual control from directives/components */\n // public showFor(el: HTMLElement) {\n // this.#currentEl = el;\n // this.#scheduleUpdate();\n // if (this.#ro) {\n // this.#ro.disconnect();\n // this.#ro.observe(el);\n // }\n // }\n\n // public hide() {\n // if (this.#haloEl) this.#haloEl.style.opacity = '0';\n // this.#currentEl = null;\n // if (this.#ro) this.#ro.disconnect();\n // }\n}\n","import { Component, inject, Injectable, signal } from '@angular/core';\nimport { MAT_SNACK_BAR_DATA, MatSnackBar, MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel, MatSnackBarRef } from '@angular/material/snack-bar';\nimport { SnackBarData, SnackBarLevel, SnackBarOptions } from './snack-bar.interface';\nimport { MatButtonModule } from '@angular/material/button';\n@Injectable({\n providedIn: 'root'\n})\nexport class SnackBarService {\n #snackBar = inject(MatSnackBar);\n\n info(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'info' });\n }\n\n success(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'success' });\n }\n\n warning(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'warning' });\n }\n\n danger(message: string, action?: string): MatSnackBarRef<SnackBarComponent> {\n return this.snack(message, { action, level: 'danger' });\n }\n\n snack(message: string, options: SnackBarOptions): MatSnackBarRef<SnackBarComponent> {\n return this.#snackBar.openFromComponent(SnackBarComponent, {\n data: {\n level: options.level,\n message,\n action: options.action\n },\n duration: options.duration || 3000,\n horizontalPosition: options.horizontalPosition,\n verticalPosition: options.verticalPosition,\n panelClass: ['yuv-snack-bar', 'level-' + options.level]\n });\n }\n}\n\n@Component({\n selector: 'yuv-snack-bar-component',\n template: `\n <span matSnackBarLabel (click)=\"dismiss()\"> {{ message() }} </span>\n @let a = action();\n @if (a) {\n <span matSnackBarActions>\n <button mat-button matSnackBarAction (click)=\"dismiss(!!a)\">{{ action() }}</button>\n </span>\n }\n `,\n styles: `\n :host {\n display: flex;\n }\n `,\n imports: [MatButtonModule, MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction],\n host: {\n '[class.info]': \"level() === 'info'\",\n '[class.success]': \"level() === 'success'\",\n '[class.warning]': \"level() === 'warning'\",\n '[class.danger]': \"level() === 'danger'\"\n }\n})\nexport class SnackBarComponent {\n #snackBarRef = inject(MatSnackBarRef);\n #snackData = inject<SnackBarData>(MAT_SNACK_BAR_DATA);\n level = signal<SnackBarLevel>(this.#snackData.level);\n message = signal<string>(this.#snackData.message);\n action = signal<string | undefined>(this.#snackData.action);\n\n dismiss(withAction = false) {\n if (withAction) {\n this.#snackBarRef.dismissWithAction();\n } else if (!this.action()) {\n this.#snackBarRef.dismiss();\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport { defaultHaloFocusOffset, haloFocusStyles, haloExcludedElementsInMatFormField } from '../../config';\nimport { HaloFocusConfig } from '../../models';\n\n/**\n * Utility service providing helper methods for the Halo Focus feature.\n *\n * This service contains pure utility functions for:\n * - Element validation (focusability, visibility, focus-visible state)\n * - Material form field detection and exclusion logic\n * - Style calculations (colors, offsets, positioning)\n * - DOM traversal (finding halo containers, checking parent visibility)\n * - Halo element manipulation (size, color, position)\n *\n * **Scope & Performance:**\n * This service is intentionally NOT provided in root (`providedIn: 'root'` is omitted).\n * Instead, it's provided locally via `provideHaloFocus()`, ensuring it's only instantiated\n * when the Halo Focus feature is actually used. This optimization prevents unnecessary\n * service creation in applications that don't use halo focus.\n *\n * **Note:** This service is used exclusively by `HaloFocusService` and should not be\n * injected or used elsewhere in the application.\n *\n * @internal\n */\n@Injectable()\nexport class HaloUtilityService {\n //#region Validations\n\n /**\n * Checks if an element is focusable (can receive keyboard focus).\n *\n * An element is considered focusable if:\n * - It has a non-negative tabIndex (>= 0), OR\n * - It's a natively focusable element (A, BUTTON, INPUT, SELECT, TEXTAREA), OR\n * - It has contentEditable enabled\n *\n * @param element - Element to check\n * @returns true if element can receive focus, false otherwise\n */\n isFocusable(element: Element | null): element is HTMLElement {\n if (!element) return false;\n const h = element as HTMLElement;\n if (h.tabIndex >= 0) return true;\n return /^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(h.tagName) || h.isContentEditable;\n }\n\n /**\n * Checks if an element is inside a Material form field (mat-form-field).\n *\n * Traverses up the DOM tree from the element to check if any parent\n * has the `mat-form-field` tag name. This is used to determine if\n * certain elements should skip halo focus because they're already\n * styled by Angular Material.\n *\n * **Search Scope:**\n * - Starts from element itself\n * - Stops at document.body\n * - Returns true on first mat-form-field match\n *\n * @param element - The element to check\n * @returns true if element is inside a mat-form-field, false otherwise\n */\n isElementInsideMatFormField(element: HTMLElement): boolean {\n let current: HTMLElement | null = element;\n while (current && current !== document.body) {\n if (current.tagName.toLowerCase() === 'mat-form-field') {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n }\n\n /**\n * Determines if an element should be excluded from halo focus when inside mat-form-field.\n *\n * Checks two conditions:\n * 1. Element tag name matches one of the excluded selectors (input, mat-select, etc.)\n * 2. Element is inside a mat-form-field component\n *\n * If both conditions are true, the element should skip halo focus because\n * Angular Material already provides adequate focus styling.\n *\n * **Excluded Elements (configurable via haloExcludedElementsInMatFormField):**\n * - `input` elements inside mat-form-field\n * - `textarea` elements inside mat-form-field\n * - `mat-select` elements inside mat-form-field\n *\n * **Note:** Elements outside mat-form-field will NOT be skipped, even if\n * their tag matches the exclusion list.\n *\n * @param element - The focused element to check\n * @returns true if element should be skipped (no halo), false if halo should be shown\n */\n shouldSkipElementInMatFormField(element: HTMLElement): boolean {\n const tagName = element.tagName.toLowerCase();\n const isExcludedElement = haloExcludedElementsInMatFormField.includes(tagName);\n\n if (!isExcludedElement) {\n return false;\n }\n\n return this.isElementInsideMatFormField(element);\n }\n\n /**\n * Determines if an element should display the halo based on :focus-visible state.\n *\n * This method respects the CSS :focus-visible pseudo-class, which indicates that\n * focus was triggered by keyboard navigation (not mouse clicks). The halo only appears\n * when both conditions are met:\n * 1. Element matches :focus-visible (browser determines this)\n * 2. Last user interaction was via keyboard (tracked by service)\n *\n * **Fallback:** If browser doesn't support :focus-visible, falls back to checking\n * lastInteractionWasKeyboard only.\n *\n * @param element - The currently focused element\n * @param lastInteractionWasKeyboard - Whether the last interaction was a keyboard event\n * @returns true if halo should be visible, false otherwise\n */\n matchesFocusVisible(element: HTMLElement, lastInteractionWasKeyboard: boolean): boolean {\n try {\n const matches = element.matches(':focus-visible');\n if (!matches) return false;\n return matches && lastInteractionWasKeyboard;\n } catch {\n return lastInteractionWasKeyboard;\n }\n }\n\n /**\n * Checks if an element is actually visible on the page.\n *\n * Performs comprehensive visibility checks including:\n * - Element has non-zero dimensions (width and height > 0)\n * - Element is not hidden via CSS (display: none, visibility: hidden, opacity: 0)\n * - Element is not clipped by parent containers with overflow: hidden/clip\n * - All parent elements in the hierarchy are visible\n *\n * This prevents the halo from appearing around technically focused but visually\n * hidden elements (e.g., elements in collapsed sections, off-screen elements).\n *\n * @param element - Element to check for visibility\n * @returns true if element is visible to the user, false otherwise\n */\n isElementVisible(element: HTMLElement): boolean {\n const rect = element.getBoundingClientRect();\n\n // Check if element has dimensions\n if (rect.width === 0 || rect.height === 0) {\n return false;\n }\n\n // Check computed style on element itself\n const style = getComputedStyle(element);\n if (style.visibility === 'hidden' || style.display === 'none' || parseFloat(style.opacity) === 0) {\n return false;\n }\n\n // Check if element is clipped by overflow:hidden parent OR if any parent is hidden\n return this.isParentVisible(element, rect);\n }\n\n /**\n * Recursively checks if all parent elements are visible and not clipping the target element.\n *\n * Traverses up the DOM tree from the element to document.body, checking each parent for:\n * - Hidden state (display: none, visibility: hidden, opacity: 0)\n * - Overflow clipping (overflow: hidden/clip) that completely hides the element\n *\n * If any parent has overflow clipping, calculates the visible intersection area.\n * Returns false if element is completely clipped (no visible area).\n *\n * @param element - The element whose parents should be checked\n * @param rect - The bounding rectangle of the element\n * @returns true if element has visible area within all parent containers, false otherwise\n */\n isParentVisible(element: HTMLElement, rect: DOMRect): boolean {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n const parentStyle = getComputedStyle(parent);\n\n // Check if parent is hidden\n if (parentStyle.display === 'none' || parentStyle.visibility === 'hidden' || parseFloat(parentStyle.opacity) === 0) {\n return false;\n }\n\n const parentOverflow = parentStyle.overflow + parentStyle.overflowX + parentStyle.overflowY;\n\n if (parentOverflow.includes('hidden') || parentOverflow.includes('clip')) {\n const parentRect = parent.getBoundingClientRect();\n // Calculate intersection - if there's no visible area, element is hidden\n const visibleRight = Math.min(rect.right, parentRect.right);\n const visibleLeft = Math.max(rect.left, parentRect.left);\n const visibleBottom = Math.min(rect.bottom, parentRect.bottom);\n const visibleTop = Math.max(rect.top, parentRect.top);\n\n const visibleWidth = visibleRight - visibleLeft;\n const visibleHeight = visibleBottom - visibleTop;\n\n // If no intersection or intersection is too small (less than 1px), element is not visible\n if (visibleWidth <= 0 || visibleHeight <= 0) {\n return false;\n }\n }\n parent = parent.parentElement;\n }\n return true;\n }\n\n //#endregion\n\n // #region Utilities\n\n /**\n * Generates the complete CSS styles for the halo element, merging defaults with custom config.\n *\n * Takes the base styles from `haloFocusStyles` constant and overrides specific properties\n * if custom configuration is provided. This allows global style customization while\n * maintaining all required base styles.\n *\n * **Configurable Properties:**\n * - Inner color (via config.innerColor)\n * - Outer color (via config.outerColor)\n *\n * **Non-configurable Properties:**\n * - position, pointerEvents, zIndex, opacity, transform (always use defaults)\n *\n * @param config - Optional global configuration object\n * @returns Complete CSS style declaration object for the halo element\n */\n getHaloFocusStyles(config?: HaloFocusConfig): Partial<CSSStyleDeclaration> {\n return {\n ...haloFocusStyles,\n border: config?.innerColor ? `2px solid ${config.innerColor}` : haloFocusStyles.border,\n boxShadow: config?.outerColor ? `0 0 0 4px ${config.outerColor}` : haloFocusStyles.boxShadow\n };\n }\n\n /**\n * Finds the nearest parent element marked as a halo container.\n *\n * Traverses up the DOM tree looking for an element with the `halo-container` attribute.\n * Container elements can define default halo styles (color, offset) that apply to all\n * their focused children, unless overridden by child-specific halo-* attributes.\n *\n * **Search Scope:**\n * - Starts from element's immediate parent\n * - Stops at document.body (does not check body itself)\n * - Returns first matching ancestor\n *\n * @param element - The focused element to search from\n * @returns The nearest halo container element, or null if none found\n */\n getHaloContainer(element: HTMLElement): HTMLElement | null {\n let parent = element.parentElement;\n while (parent && parent !== document.body) {\n if (parent.hasAttribute('halo-container')) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n }\n\n /**\n * Converts any CSS color format to rgba with specified alpha transparency.\n *\n * Handles multiple color formats:\n * - **rgba**: Replaces existing alpha value\n * - **rgb**: Converts to rgba by appending alpha\n * - **Hex** (#RRGGBB): Converts to rgba format\n * - **Named colors**: Uses modern CSS `color-mix` function with alpha\n *\n * Used internally to create outer colors with reduced opacity from inner colors.\n *\n * @param color - CSS color in any valid format (rgba, rgb, hex, named)\n * @param alpha - Alpha transparency value (0-1)\n * @returns Color in rgba format with specified alpha\n */\n getColorWithAlpha(color: string, alpha: number): string {\n // If already rgba, try to replace alpha\n if (color.startsWith('rgba')) {\n return color.replace(/[\\d.]+\\)$/, `${alpha})`);\n }\n\n // If rgb, convert to rgba\n if (color.startsWith('rgb')) {\n return color.replace('rgb', 'rgba').replace(')', `, ${alpha})`);\n }\n\n // If hex color, convert to rgba\n if (color.startsWith('#')) {\n const hex = color.replace('#', '');\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n\n // For named colors or other formats, wrap in rgba with color-mix (modern approach)\n // Fallback to appending alpha as hex if browser doesn't support color-mix\n return `rgba(from ${color} r g b / ${alpha})`;\n }\n\n /**\n * Calculates the offset (distance) between the halo border and element edges.\n *\n * Determines offset using the following priority order:\n * 1. **Element's own attributes** (highest priority):\n * - `halo-offset=\"value\"` - Custom numeric value\n * 2. **Parent container attributes** (if element has no offset):\n * - `halo-container-offset=\"value\"`\n * 3. **Default offset** (if nothing specified): 3px\n *\n * @param element - The focused element to calculate offset for\n * @returns Offset value in pixels\n */\n getTargetOffset(element: HTMLElement | null): number {\n if (!element) return defaultHaloFocusOffset;\n\n // 1. Check element's own attributes first\n const customOffset = element.getAttribute('halo-offset');\n if (customOffset !== null) {\n const parsed = parseFloat(customOffset);\n if (!isNaN(parsed)) return parsed;\n }\n\n // 2. Check container attributes as fallback\n const container = this.getHaloContainer(element);\n if (container) {\n const containerOffset = container.getAttribute('halo-container-offset');\n if (containerOffset !== null) {\n const parsed = parseFloat(containerOffset);\n if (!isNaN(parsed)) return parsed;\n }\n }\n\n // 3. Default: positive offset (halo outside element)\n return defaultHaloFocusOffset;\n }\n\n /**\n * Applies custom color styling to the halo element based on element or container attributes.\n *\n * Color resolution priority:\n * 1. **Element's own color**: `halo-color=\"color\"` attribute (highest priority)\n * 2. **Container's color**: `halo-container-color=\"color\"` from nearest halo container\n * 3. **Default color**: From global config or base styles (if no custom color found)\n *\n * When custom color is found:\n * - Sets inner color (2px solid border) with the custom color\n * - Sets outer color (shadow) to match, with 20% alpha transparency for subtle depth\n *\n * When no custom color:\n * - Resets to default styles from config or haloFocusStyles constant\n *\n * @param element - The focused element (checked for halo-color attribute)\n * @param haloElement - The halo DIV element to apply styles to\n * @param config - Optional global config for default colors\n */\n setCustomColor(element: HTMLElement, haloElement: HTMLDivElement, config?: HaloFocusConfig): void {\n // 1. Check element's own color first\n let customColor = element.getAttribute('halo-color');\n\n // 2. If not found, check container color\n if (!customColor) {\n const container = this.getHaloContainer(element);\n if (container) {\n customColor = container.getAttribute('halo-container-color');\n }\n }\n // Apply color or reset to default\n if (customColor) {\n haloElement.style.border = `2px solid ${customColor}`;\n haloElement.style.boxShadow = `0 0 0 4px ${this.getColorWithAlpha(customColor, 0.2)}`;\n } else {\n // Reset to default styles\n haloElement.style.border = this.getHaloFocusStyles(config).border!;\n haloElement.style.boxShadow = this.getHaloFocusStyles(config).boxShadow!;\n }\n }\n\n /**\n * Positions and sizes the halo element to surround the focused element.\n *\n * Calculates halo dimensions and position based on:\n * - Element's bounding rectangle (viewport-relative position)\n * - Calculated offset from getTargetOffset() (custom or default)\n * - Element's border-radius for matching rounded corners\n *\n * **Calculation Details:**\n * - Position: Element's top/left minus offset (for outside positioning)\n * - Size: Element's width/height plus 2× offset (to extend on all sides)\n * - Border radius: Inherited from focused element's computed style\n *\n * Uses Math.floor for position and Math.ceil for dimensions to prevent\n * subpixel rendering issues and ensure full element coverage.\n *\n * @param currentElement - The currently focused element to surround\n * @param haloElement - The halo DIV element to position and size\n */\n setHaloElementSize(currentElement: HTMLElement, haloElement: HTMLDivElement): void {\n const rect = currentElement.getBoundingClientRect();\n const offset = this.getTargetOffset(currentElement);\n\n const left = Math.floor(rect.left - offset);\n const top = Math.floor(rect.top - offset);\n const width = Math.ceil(rect.width + offset * 2);\n const height = Math.ceil(rect.height + offset * 2);\n\n const cs = getComputedStyle(currentElement);\n haloElement.style.left = `${left}px`;\n haloElement.style.top = `${top}px`;\n haloElement.style.width = `${width}px`;\n haloElement.style.height = `${height}px`;\n haloElement.style.borderRadius = cs.borderRadius || '8px';\n }\n\n //#endregion\n}\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, NgZone, provideAppInitializer } from '@angular/core';\nimport { HaloFocusService, HaloUtilityService } from '../../services';\nimport { HaloFocusConfig } from '../../models';\n\n/**\n * Provides and initializes the Halo Focus feature for the Angular application.\n *\n * This function sets up a global visual accessibility enhancement that creates a\n * \"halo\" border around keyboard-focused elements, making navigation more visible\n * and improving the user experience for keyboard users.\n *\n * **What It Does:**\n * - Registers HaloFocusService and HaloUtility as application-wide providers\n * - Automatically initializes the service during app startup via APP_INITIALIZER\n * - Runs initialization outside Angular zone for optimal performance\n * - Creates a persistent halo element that tracks focus throughout the application\n *\n * **Key Features:**\n * - Keyboard-only focus indication (respects CSS :focus-visible)\n * - Performance-optimized with requestAnimationFrame and zone-free execution\n * - Fully customizable via global config or per-element attributes\n * - Supports container-level defaults for consistent styling\n * - Automatic visibility detection and responsive to DOM changes\n *\n * **Configuration Options:**\n * @param config - Optional global configuration object\n * @param config.innerColor - Inner color of the halo (default: 'var(--ymt-primary)')\n * @param config.outerColor - Outer color around the halo (default: 'rgba(from var(--ymt-primary) r g b / 0.2)')\n *\n * @returns EnvironmentProviders for the Halo Focus feature\n *\n * @example\n * // Basic usage in app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHaloFocus()\n * ]\n * };\n *\n * @example\n * // With custom configuration\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHaloFocus({\n * innerColor: '#007bff',\n * outerColor: 'rgba(0, 123, 255, 0.25)'\n * })\n * ]\n * };\n *\n * @example\n * // Using element-level attributes in your template\n * <button halo-color=\"red\">Custom Red Halo</button>\n * <input halo-offset=\"5\" />\n * <select halo-skip>No Halo</select>\n *\n * @example\n * // Using container-level attributes\n * <form halo-container halo-container-color=\"blue\" halo-container-offset=\"5\">\n * <input /> <!-- Will use blue color and 5px offset -->\n * <button halo-color=\"red\">Submit</button> <!-- Overrides with red -->\n * </form>\n */\nexport function provideHaloFocus(config?: HaloFocusConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n HaloUtilityService,\n provideAppInitializer(() => {\n const zone = inject(NgZone);\n const haloFocus = inject(HaloFocusService);\n zone.runOutsideAngular(() => haloFocus.init(config));\n })\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/lib/assets/i18n/en.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"yuv.action-menu.action.cut.dms.object.description": "",
|
|
5
5
|
"yuv.action-menu.action.cut.dms.object.label": "Cut",
|
|
6
6
|
"yuv.action-menu.action.delete.dms.object.confirm.cancel": "Cancel",
|
|
7
|
-
"yuv.action-menu.action.delete.dms.object.confirm.message": "
|
|
7
|
+
"yuv.action-menu.action.delete.dms.object.confirm.message": "Are you sure you want to delete the selected object(s)?",
|
|
8
8
|
"yuv.action-menu.action.delete.dms.object.confirm.ok": "Delete",
|
|
9
9
|
"yuv.action-menu.action.delete.dms.object.description": "Deletes the object.",
|
|
10
10
|
"yuv.action-menu.action.delete.dms.object.label": "Delete",
|
|
@@ -119,28 +119,28 @@
|
|
|
119
119
|
"yuv.object-flavor.picker.text": "Types are extensions for files that provide additional information about their content/meaning.",
|
|
120
120
|
"yuv.object-flavor.picker.title": "Add type",
|
|
121
121
|
"yuv.object-preview.tiff-warning": "This document is not the original *.tiff file, but only a representation. The preview does not support *.tiff files. Please download the document to view the original.",
|
|
122
|
-
"cm.app.cases.action.add-link.search.relation.label": "
|
|
122
|
+
"cm.app.cases.action.add-link.search.relation.label": "Reference type",
|
|
123
123
|
"yuv.object-relationship.action.add-relationship.description": "",
|
|
124
|
-
"yuv.object-relationship.action.add-relationship.label": "Add
|
|
125
|
-
"yuv.object-relationship.add-relation.error-message": "
|
|
124
|
+
"yuv.object-relationship.action.add-relationship.label": "Add reference",
|
|
125
|
+
"yuv.object-relationship.add-relation.error-message": "Error while adding the reference.",
|
|
126
126
|
"yuv.object-relationship.add-relationship.action.cancel": "Cancel",
|
|
127
|
-
"yuv.object-relationship.add-relationship.action.submit": "Add
|
|
128
|
-
"yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination": "The selected
|
|
129
|
-
"yuv.object-relationship.add-relationship.headline": "Add new
|
|
130
|
-
"yuv.object-relationship.add-relationship.target-search.label": "Target",
|
|
131
|
-
"yuv.object-relationship.add.tooltip": "
|
|
132
|
-
"yuv.object-relationship.delete-relation.confirm-message": "
|
|
133
|
-
"yuv.object-relationship.delete-relation.error-message": "
|
|
134
|
-
"yuv.object-relationship.delete-relation.tooltip": "
|
|
135
|
-
"yuv.object-relationship.download.tooltip": "Download as
|
|
136
|
-
"yuv.object-relationship.list.incoming": "Incoming
|
|
137
|
-
"yuv.object-relationship.list.outgoing": "Outgoing
|
|
127
|
+
"yuv.object-relationship.add-relationship.action.submit": "Add reference",
|
|
128
|
+
"yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination": "The selected reference type is not valid for the selected target object.",
|
|
129
|
+
"yuv.object-relationship.add-relationship.headline": "Add new reference",
|
|
130
|
+
"yuv.object-relationship.add-relationship.target-search.label": "Target object",
|
|
131
|
+
"yuv.object-relationship.add.tooltip": "Add new reference",
|
|
132
|
+
"yuv.object-relationship.delete-relation.confirm-message": "Do you really want to delete the selected reference?",
|
|
133
|
+
"yuv.object-relationship.delete-relation.error-message": "Error while deleting the selected reference.",
|
|
134
|
+
"yuv.object-relationship.delete-relation.tooltip": "Delete selected reference",
|
|
135
|
+
"yuv.object-relationship.download.tooltip": "Download as image",
|
|
136
|
+
"yuv.object-relationship.list.incoming": "Incoming references",
|
|
137
|
+
"yuv.object-relationship.list.outgoing": "Outgoing references",
|
|
138
138
|
"yuv.object-relationship.mode.graph.tooltip": "Graph view",
|
|
139
139
|
"yuv.object-relationship.mode.list.tooltip": "List view",
|
|
140
|
-
"yuv.object-relationship.no-relations": "No
|
|
140
|
+
"yuv.object-relationship.no-relations": "No references found.",
|
|
141
141
|
"yuv.object-relationship.node-summary.open-object.button": "Open",
|
|
142
|
-
"yuv.object-relationship.selected.add-relationship.tooltip": "
|
|
143
|
-
"yuv.object-relationship.selected.expand.tooltip": "
|
|
142
|
+
"yuv.object-relationship.selected.add-relationship.tooltip": "Add new reference",
|
|
143
|
+
"yuv.object-relationship.selected.expand.tooltip": "Expand selected reference",
|
|
144
144
|
"yuv.object-summary-data.base.headline": "Basic metadata",
|
|
145
145
|
"yuv.object-summary.load.error": "Error while loading the summary",
|
|
146
146
|
"yuv.object-versions.actions.download": "Download version",
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
"yuv.upload-progress.header.uploading": "Upload of {{count}} file(s)",
|
|
176
176
|
"yuv.widget-grid.button.cancel": "Cancel",
|
|
177
177
|
"yuv.widget-grid.button.save": "Save",
|
|
178
|
-
"yuv.widget-grid.empty": "No widgets have been added to this workspace.",
|
|
178
|
+
"yuv.widget-grid.empty": "No widgets have been added to this workspace yet.",
|
|
179
179
|
"yuv.widget-grid.empty.create": "Edit workspace",
|
|
180
180
|
"yuv.widget-grid.widget-picker.empty": "No widgets available.",
|
|
181
181
|
"yuv.widget-grid.widget-picker.title": "Widgets",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List of element selectors that should be excluded from halo focus
|
|
3
|
+
* when they are inside a Material form field component (mat-form-field).
|
|
4
|
+
*
|
|
5
|
+
* These elements typically have their own built-in focus indicators provided
|
|
6
|
+
* by Angular Material, making the halo focus redundant or visually conflicting.
|
|
7
|
+
*
|
|
8
|
+
* **Included Selectors:**
|
|
9
|
+
* - `input` - Text inputs, number inputs, etc. inside mat-form-field
|
|
10
|
+
* - `textarea` - Multi-line text inputs inside mat-form-field
|
|
11
|
+
* - `mat-select` - Material select dropdowns inside mat-form-field
|
|
12
|
+
*
|
|
13
|
+
* **Why Exclude These:**
|
|
14
|
+
* Angular Material form fields provide their own focus styling with floating labels,
|
|
15
|
+
* underlines, and color changes. Adding a halo around these elements would:
|
|
16
|
+
* - Create visual clutter and redundancy
|
|
17
|
+
* - Potentially conflict with Material's focus styling
|
|
18
|
+
* - Reduce the clarity of Material Design's established patterns
|
|
19
|
+
*
|
|
20
|
+
* **Note:** These elements will still receive halo focus if they appear OUTSIDE
|
|
21
|
+
* of mat-form-field containers. The exclusion only applies when they're wrapped
|
|
22
|
+
* in a mat-form-field.
|
|
23
|
+
*
|
|
24
|
+
* @see {@link HaloUtilityService.shouldSkipElementInMatFormField} for implementation
|
|
25
|
+
*/
|
|
26
|
+
export declare const haloExcludedElementsInMatFormField: string[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List of keyboard navigation keys that trigger halo position updates.
|
|
3
|
+
*
|
|
4
|
+
* When any of these keys are pressed while an element is focused, the halo service
|
|
5
|
+
* schedules an immediate position update to ensure the halo follows the focused element
|
|
6
|
+
* if it moves within the page (e.g., scrolling a list, moving through a table).
|
|
7
|
+
*
|
|
8
|
+
* **Included Keys:**
|
|
9
|
+
* - `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown` - Directional navigation
|
|
10
|
+
* - `Home`, `End` - Jump to start/end of content
|
|
11
|
+
* - `PageUp`, `PageDown` - Page-level scrolling
|
|
12
|
+
*
|
|
13
|
+
* **Why This Matters:**
|
|
14
|
+
* Arrow keys and navigation keys can cause the focused element to scroll or move within
|
|
15
|
+
* its container (e.g., scrolling a select dropdown, moving focus in a grid). By tracking
|
|
16
|
+
* these keys, the halo can immediately update its position to follow the element, preventing
|
|
17
|
+
* visual misalignment.
|
|
18
|
+
*
|
|
19
|
+
* **Performance Note:**
|
|
20
|
+
* Updates are scheduled using requestAnimationFrame, so even rapid key presses won't
|
|
21
|
+
* cause performance issues.
|
|
22
|
+
*
|
|
23
|
+
* @see {@link HaloFocusService} for the implementation of keydown handling
|
|
24
|
+
*/
|
|
25
|
+
export declare const haloFocusNavigationKeys: string[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default offset (in pixels) between the halo border and the focused element's edges.
|
|
3
|
+
*
|
|
4
|
+
* This value determines how far the halo appears from the focused element:
|
|
5
|
+
* - **Positive value** (default: 3): Halo appears outside the element
|
|
6
|
+
* - **Zero (0)**: Halo aligns exactly with element edges (neutral offset)
|
|
7
|
+
* - **Negative value**: Halo appears inside the element (inset)
|
|
8
|
+
*
|
|
9
|
+
* **Override Methods:**
|
|
10
|
+
* - **Per-element**: Use `halo-offset="value"` attribute
|
|
11
|
+
* - **Per-container**: Use `halo-container-offset="value"` or preset attributes
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```html
|
|
15
|
+
* <!-- Uses default 3px offset (outside) -->
|
|
16
|
+
* <button>Default</button>
|
|
17
|
+
*
|
|
18
|
+
* <!-- Custom 5px offset -->
|
|
19
|
+
* <input halo-offset="5" />
|
|
20
|
+
*
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @default 3
|
|
24
|
+
*/
|
|
25
|
+
export declare const defaultHaloFocusOffset = 3;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default CSS styles for the halo focus element.
|
|
3
|
+
*
|
|
4
|
+
* These styles define the visual appearance and behavior of the halo border that
|
|
5
|
+
* highlights keyboard-focused elements. The halo is a fixed-position overlay that
|
|
6
|
+
* follows the focused element across the page.
|
|
7
|
+
*
|
|
8
|
+
* **Style Properties:**
|
|
9
|
+
* - `position: 'fixed'` - Keeps halo in viewport regardless of scroll position
|
|
10
|
+
* - `pointerEvents: 'none'` - Allows click-through; halo doesn't block interactions
|
|
11
|
+
* - `zIndex: '9999'` - Ensures halo appears above most other elements
|
|
12
|
+
* - `border` - Primary border using CSS variable `--ymt-primary` (2px solid)
|
|
13
|
+
* - `boxShadow` - Soft shadow with 20% opacity for subtle depth effect
|
|
14
|
+
* - `borderRadius` - Default 8px rounded corners for modern appearance
|
|
15
|
+
* - `opacity: '0'` - Initially hidden; visibility controlled by service
|
|
16
|
+
* - `transform: 'translateZ(0)'` - Creates GPU layer for smoother animations
|
|
17
|
+
*
|
|
18
|
+
* **CSS Variable Dependencies:**
|
|
19
|
+
* - `--ymt-primary` - Primary theme color for border and shadow
|
|
20
|
+
*
|
|
21
|
+
* **Note:** These are base styles that can be overridden globally via HaloFocusConfig
|
|
22
|
+
* or per-element using halo-* attributes.
|
|
23
|
+
*
|
|
24
|
+
* @see {@link HaloFocusConfig} for global style customization
|
|
25
|
+
*/
|
|
26
|
+
export declare const haloFocusStyles: Partial<CSSStyleDeclaration>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './halo-focus-defaults';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for the Halo Focus service.
|
|
3
|
+
*
|
|
4
|
+
* These settings define the default visual appearance of the focus halo.
|
|
5
|
+
* Individual elements can override these defaults using halo-* attributes,
|
|
6
|
+
* and containers can set defaults for their children using halo-container-* attributes.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const config: HaloFocusConfig = {
|
|
10
|
+
* innerColor: '#007bff',
|
|
11
|
+
* outerColor: 'rgba(0, 123, 255, 0.25)'
|
|
12
|
+
* };
|
|
13
|
+
*/
|
|
14
|
+
export interface HaloFocusConfig {
|
|
15
|
+
/**
|
|
16
|
+
* Inner color for the halo element.
|
|
17
|
+
*
|
|
18
|
+
* Accepts any valid CSS color value:
|
|
19
|
+
* - Named colors: 'blue', 'red'
|
|
20
|
+
* - Hex: '#007bff', '#f00'
|
|
21
|
+
* - RGB: 'rgb(0, 123, 255)'
|
|
22
|
+
* - RGBA: 'rgba(0, 123, 255, 0.5)'
|
|
23
|
+
* - CSS variables: 'var(--primary-color)'
|
|
24
|
+
* - Modern CSS: 'rgba(from var(--color) r g b / 0.5)'
|
|
25
|
+
*
|
|
26
|
+
* @default 'var(--ymt-primary)'
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* innerColor: '#007bff'
|
|
30
|
+
* innerColor: 'var(--accent-color)'
|
|
31
|
+
*/
|
|
32
|
+
innerColor?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Outer color that appears around the halo element.
|
|
35
|
+
*
|
|
36
|
+
* Creates a subtle glow effect around the focused element.
|
|
37
|
+
* The outer color is 4px wide and surrounds the inner color.
|
|
38
|
+
*
|
|
39
|
+
* Accepts any valid CSS color value with alpha transparency recommended.
|
|
40
|
+
*
|
|
41
|
+
* @default 'rgba(from var(--ymt-primary) r g b / 0.2)'
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* outerColor: 'rgba(0, 123, 255, 0.25)'
|
|
45
|
+
* outerColor: 'rgba(from var(--accent) r g b / 0.3)'
|
|
46
|
+
*/
|
|
47
|
+
outerColor?: string;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './halo-focus-config.model';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './halo-focus-config';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './provide-halo-focus';
|
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
import { EnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { HaloFocusConfig } from '../../models';
|
|
2
3
|
/**
|
|
3
|
-
* Provides and initializes the
|
|
4
|
-
* By calling this function in your ApplicationConfig providers,
|
|
5
|
-
* the Halo Focus feature will be activated, allowing users to see a visual focus indicator.
|
|
6
|
-
* The service will be initialized outside Angular zone for optimal performance.
|
|
4
|
+
* Provides and initializes the Halo Focus feature for the Angular application.
|
|
7
5
|
*
|
|
8
|
-
*
|
|
6
|
+
* This function sets up a global visual accessibility enhancement that creates a
|
|
7
|
+
* "halo" border around keyboard-focused elements, making navigation more visible
|
|
8
|
+
* and improving the user experience for keyboard users.
|
|
9
|
+
*
|
|
10
|
+
* **What It Does:**
|
|
11
|
+
* - Registers HaloFocusService and HaloUtility as application-wide providers
|
|
12
|
+
* - Automatically initializes the service during app startup via APP_INITIALIZER
|
|
13
|
+
* - Runs initialization outside Angular zone for optimal performance
|
|
14
|
+
* - Creates a persistent halo element that tracks focus throughout the application
|
|
15
|
+
*
|
|
16
|
+
* **Key Features:**
|
|
17
|
+
* - Keyboard-only focus indication (respects CSS :focus-visible)
|
|
18
|
+
* - Performance-optimized with requestAnimationFrame and zone-free execution
|
|
19
|
+
* - Fully customizable via global config or per-element attributes
|
|
20
|
+
* - Supports container-level defaults for consistent styling
|
|
21
|
+
* - Automatic visibility detection and responsive to DOM changes
|
|
22
|
+
*
|
|
23
|
+
* **Configuration Options:**
|
|
24
|
+
* @param config - Optional global configuration object
|
|
25
|
+
* @param config.innerColor - Inner color of the halo (default: 'var(--ymt-primary)')
|
|
26
|
+
* @param config.outerColor - Outer color around the halo (default: 'rgba(from var(--ymt-primary) r g b / 0.2)')
|
|
27
|
+
*
|
|
28
|
+
* @returns EnvironmentProviders for the Halo Focus feature
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Basic usage in app.config.ts
|
|
32
|
+
* export const appConfig: ApplicationConfig = {
|
|
33
|
+
* providers: [
|
|
34
|
+
* provideHaloFocus()
|
|
35
|
+
* ]
|
|
36
|
+
* };
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // With custom configuration
|
|
40
|
+
* export const appConfig: ApplicationConfig = {
|
|
41
|
+
* providers: [
|
|
42
|
+
* provideHaloFocus({
|
|
43
|
+
* innerColor: '#007bff',
|
|
44
|
+
* outerColor: 'rgba(0, 123, 255, 0.25)'
|
|
45
|
+
* })
|
|
46
|
+
* ]
|
|
47
|
+
* };
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Using element-level attributes in your template
|
|
51
|
+
* <button halo-color="red">Custom Red Halo</button>
|
|
52
|
+
* <input halo-offset="5" />
|
|
53
|
+
* <select halo-skip>No Halo</select>
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // Using container-level attributes
|
|
57
|
+
* <form halo-container halo-container-color="blue" halo-container-offset="5">
|
|
58
|
+
* <input /> <!-- Will use blue color and 5px offset -->
|
|
59
|
+
* <button halo-color="red">Submit</button> <!-- Overrides with red -->
|
|
60
|
+
* </form>
|
|
9
61
|
*/
|
|
10
|
-
export declare function provideHaloFocus(): EnvironmentProviders;
|
|
62
|
+
export declare function provideHaloFocus(config?: HaloFocusConfig): EnvironmentProviders;
|
package/lib/providers/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './halo-focus
|
|
1
|
+
export * from './halo-focus';
|
|
@@ -1,7 +1,95 @@
|
|
|
1
|
+
import { HaloFocusConfig } from '../../models';
|
|
1
2
|
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Service that creates and manages a visual "halo" border around keyboard-focused elements
|
|
5
|
+
* to enhance navigation visibility and improve accessibility.
|
|
6
|
+
*
|
|
7
|
+
* This service operates globally across the application, automatically tracking focus events
|
|
8
|
+
* and dynamically positioning a halo element around the currently focused element. The halo
|
|
9
|
+
* responds to window scrolls, resizes, and DOM mutations to maintain accurate positioning.
|
|
10
|
+
*
|
|
11
|
+
* **Key Features:**
|
|
12
|
+
* - Keyboard-only focus indication (respects :focus-visible)
|
|
13
|
+
* - Performance-optimized with requestAnimationFrame and runs outside Angular zone
|
|
14
|
+
* - Element-level and container-level customization support
|
|
15
|
+
* - Automatic visibility detection (handles clipping, hidden elements, etc.)
|
|
16
|
+
* - Responsive to dynamic DOM changes via ResizeObserver and MutationObserver
|
|
17
|
+
* - Smart exclusion for Angular Material form fields (prevents redundant styling)
|
|
18
|
+
*
|
|
19
|
+
* **Usage:**
|
|
20
|
+
* 1. Add `provideHaloFocus()` to your providers array in app.config.ts
|
|
21
|
+
* 2. The service initializes automatically and appends a halo element to the DOM
|
|
22
|
+
* 3. Optionally customize appearance globally or per-element using attributes
|
|
23
|
+
*
|
|
24
|
+
* **Element-Level Attributes:**
|
|
25
|
+
* - `halo-skip` - Excludes element from halo highlighting
|
|
26
|
+
* - `halo-color="color"` - Custom halo color (e.g., "blue", "#00ff00", "rgb(255,0,0)")
|
|
27
|
+
* - `halo-offset="value"` - Custom numeric offset in pixels (default: 3)
|
|
28
|
+
*
|
|
29
|
+
* **Container-Level Attributes:**
|
|
30
|
+
* Define default halo styles for all focused children. Child elements can override
|
|
31
|
+
* container settings with their own halo-* attributes.
|
|
32
|
+
*
|
|
33
|
+
* - `halo-container` - Marks element as a halo container (required for other attributes)
|
|
34
|
+
* - `halo-container-skip` - Excludes all focused children from halo highlighting
|
|
35
|
+
* - `halo-container-color="color"` - Default halo color for focused children
|
|
36
|
+
* - `halo-container-offset="value"` - Default offset for focused children
|
|
37
|
+
*
|
|
38
|
+
* **Material Form Field Integration:**
|
|
39
|
+
* Elements inside Angular Material form fields (mat-form-field) are automatically excluded
|
|
40
|
+
* from halo focus to prevent visual conflicts with Material's built-in focus styling.
|
|
41
|
+
* Excluded elements: input, mat-select (configurable via haloExcludedElementsInMatFormField)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```html
|
|
45
|
+
* <!-- Element-level customization -->
|
|
46
|
+
* <button halo-color="red">Custom Red Halo</button>
|
|
47
|
+
* <input halo-offset="5" />
|
|
48
|
+
* <select halo-skip>No Halo</select>
|
|
49
|
+
*
|
|
50
|
+
* <!-- Container-level defaults -->
|
|
51
|
+
* <form halo-container halo-container-color="blue" halo-container-offset="5">
|
|
52
|
+
* <input /> <!-- Inherits blue color and 5px offset -->
|
|
53
|
+
* <button halo-color="red">Submit</button> <!-- Overrides with red, keeps 5px offset -->
|
|
54
|
+
* </form>
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* **Performance Notes:**
|
|
58
|
+
* - Service runs outside Angular's zone to prevent unnecessary change detection
|
|
59
|
+
* - Uses requestAnimationFrame for smooth rendering
|
|
60
|
+
* - Only shows halo for keyboard interactions (respects :focus-visible)
|
|
61
|
+
*
|
|
62
|
+
* @see {@link provideHaloFocus} for initialization and configuration
|
|
63
|
+
* @see {@link HaloFocusConfig} for global configuration options
|
|
64
|
+
*/
|
|
2
65
|
export declare class HaloFocusService {
|
|
3
66
|
#private;
|
|
4
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Initializes the Halo Focus service and sets up the global halo tracking system.
|
|
69
|
+
*
|
|
70
|
+
* This method performs the following initialization steps:
|
|
71
|
+
* 1. Applies optional configuration for halo appearance (inner and outer colors)
|
|
72
|
+
* 2. Creates and appends the halo DIV element to the document body
|
|
73
|
+
* 3. Attaches global event listeners for focus, blur, keyboard, mouse, scroll, and resize events
|
|
74
|
+
* 4. Sets up ResizeObserver and MutationObserver for tracking dynamic DOM changes
|
|
75
|
+
*
|
|
76
|
+
* **Lifecycle:**
|
|
77
|
+
* - Called automatically by `provideHaloFocus()` during app initialization
|
|
78
|
+
* - Runs outside Angular's zone to prevent triggering change detection
|
|
79
|
+
* - Initializes only once per application lifecycle
|
|
80
|
+
*
|
|
81
|
+
* **Performance:**
|
|
82
|
+
* - Uses passive event listeners where applicable
|
|
83
|
+
* - Leverages requestAnimationFrame for efficient rendering
|
|
84
|
+
* - Observers are conditionally created only if browser supports them
|
|
85
|
+
*
|
|
86
|
+
* @param config - Optional configuration object for customizing halo appearance
|
|
87
|
+
* @param config.innerColor - Custom inner color (overrides default primary color)
|
|
88
|
+
* @param config.outerColor - Custom outer color (overrides default shadow)
|
|
89
|
+
*
|
|
90
|
+
* @internal This method should not be called manually; use `provideHaloFocus()` instead
|
|
91
|
+
*/
|
|
92
|
+
init(config?: HaloFocusConfig): void;
|
|
5
93
|
static ɵfac: i0.ɵɵFactoryDeclaration<HaloFocusService, never>;
|
|
6
94
|
static ɵprov: i0.ɵɵInjectableDeclaration<HaloFocusService>;
|
|
7
95
|
}
|