@spectrum-web-components/reactive-controllers 1.7.0 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/reactive-controllers",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -89,7 +89,7 @@
89
89
  "css"
90
90
  ],
91
91
  "dependencies": {
92
- "@spectrum-web-components/progress-circle": "1.7.0",
92
+ "@spectrum-web-components/progress-circle": "1.8.0",
93
93
  "colorjs.io": "^0.5.2",
94
94
  "lit": "^2.5.0 || ^3.1.3"
95
95
  },
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveElement } from 'lit';
2
13
  import Color from 'colorjs.io';
3
14
  import type { ColorObject, ColorTypes as DefaultColorTypes } from 'colorjs.io/types/src/color';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["ColorController.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveElement } from 'lit';\nimport Color from 'colorjs.io';\nimport type {\n ColorObject,\n ColorTypes as DefaultColorTypes,\n} from 'colorjs.io/types/src/color';\nimport type ColorSpace from 'colorjs.io/types/src/space';\n\n/**\n * Represents various color types that can be used in the application.\n *\n * This type can be one of the following:\n * - `DefaultColorTypes`: A predefined set of color types.\n * - An object representing an RGBA color with properties:\n * - `r`: Red component, can be a number or string.\n * - `g`: Green component, can be a number or string.\n * - `b`: Blue component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSLA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `l`: Lightness component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSVA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `v`: Value component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n */\ntype ColorTypes =\n | DefaultColorTypes\n | {\n r: number | string;\n g: number | string;\n b: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n l: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n v: number | string;\n a?: number | string;\n };\n\nexport type { Color, ColorTypes };\n\ntype ColorValidationResult = {\n spaceId: string | null;\n coords: number[];\n isValid: boolean;\n alpha: number;\n};\n\n/**\n * The `ColorController` class is responsible for managing and validating color values\n * in various color spaces (RGB, HSL, HSV, Hex). It provides methods to set, get, and\n * validate colors, as well as convert between different color formats.\n *\n * @class\n * @property {Color} color - Gets or sets the current color value.\n * @property {ColorTypes} colorValue - Gets the color value in various formats based on the original color input.\n * @property {number} hue - Gets or sets the hue value of the current color.\n *\n * @method validateColorString(color: string): ColorValidationResult - Validates a color string and returns the validation result.\n * @method getColor(format: string | ColorSpace): ColorObject - Converts the current color to the specified format.\n * @method getHslString(): string - Returns the current color in HSL string format.\n * @method savePreviousColor(): void - Saves the current color as the previous color.\n * @method restorePreviousColor(): void - Restores the previous color.\n *\n * @constructor\n * @param {ReactiveElement} host - The host element that uses this controller.\n * @param {Object} [options] - Optional configuration options.\n * @param {string} [options.manageAs] - Specifies the color space to manage the color as.\n */\n\nexport class ColorController {\n get color(): Color {\n return this._color;\n }\n\n /**\n * Validates a color string and returns a result indicating the color space,\n * coordinates, alpha value, and whether the color is valid.\n *\n * @param color - The color string to validate. Supported formats include:\n * - RGB: `rgb(r, g, b)`, `rgba(r, g, b, a)`, `rgb r g b`, `rgba r g b a`\n * - HSL: `hsl(h, s, l)`, `hsla(h, s, l, a)`, `hsl h s l`, `hsla h s l a`\n * - HSV: `hsv(h, s, v)`, `hsva(h, s, v, a)`, `hsv h s v`, `hsva h s v a`\n * - HEX: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`\n *\n * @returns An object containing the following properties:\n * - `spaceId`: The color space identifier (`'srgb'`, `'hsl'`, or `'hsv'`).\n * - `coords`: An array of numeric values representing the color coordinates.\n * - `alpha`: The alpha value of the color (0 to 1).\n * - `isValid`: A boolean indicating whether the color string is valid.\n */\n public validateColorString(color: string): ColorValidationResult {\n const result: ColorValidationResult = {\n spaceId: null,\n coords: [0, 0, 0],\n isValid: false,\n alpha: 1,\n };\n\n // RGB color formats\n const rgbRegExpArray = [\n // With commas\n /rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r, g, b, a)\n /rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)/i, // rgb(r, g, b)\n\n // With spaces\n /^rgba\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(0|0?\\.\\d+|1)\\s*$/i, // rgba r g b a\n /^rgb\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$/i, // rgb r g b\n\n // Spaces inside parentheses\n /^rgba\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // rgba(r g b a)\n /^rgb\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*\\)$/i, // rgb(r g b)\n\n // Percentage values\n /rgb\\(\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*\\)/i, // rgb(r%, g%, b%)\n /rgba\\(\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r%, g%, b%, a)\n ];\n\n // HSL color formats\n const hslRegExpArray = [\n // With commas\n /hsla\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsla(h, s, l, a)\n /hsl\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsl(h, s, l)\n\n // With spaces\n /^hsla\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsla h s l a\n /^hsl\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsl h s l\n\n // Spaces inside parentheses\n /^hsla\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsla(h s l a)\n /^hsl\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsl(h s l)\n ];\n\n // HSV color formats\n const hsvRegExpArray = [\n // With commas\n /hsva\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsva(h, s, v, a)\n /hsv\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsv(h, s, v)\n\n // With spaces\n /^hsva\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsva h s v a\n /^hsv\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsv h s v\n\n // Spaces inside parentheses\n /^hsva\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsva(h s v a)\n /^hsv\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsv(h s v)\n ];\n\n // HEX color formats\n const hexRegExpArray = [\n /^#([A-Fa-f0-9]{6})([A-Fa-f0-9]{2})?$/, // 6-digit hex with optional hex alpha\n /^#([A-Fa-f0-9]{3})([A-Fa-f0-9]{1})?$/, // 3-digit hex with optional hex alpha\n ];\n\n const rgbaMatch = rgbRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hslaMatch = hslRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hsvaMatch = hsvRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hexMatch = hexRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch.filter(\n (element) => typeof element === 'string'\n );\n const alpha = a === undefined ? 1 : Number(a);\n const processValue = (value: string): number => {\n if (value.includes('%')) {\n return Number(value.replace('%', '')) / 100;\n } else {\n return Number(value) / 255;\n }\n };\n const numericR = processValue(r);\n const numericG = processValue(g);\n const numericB = processValue(b);\n\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = alpha;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n alpha >= 0 &&\n alpha <= 1;\n } else if (hslaMatch) {\n const [, h, s, l, a] = hslaMatch;\n const values = [h, s, l, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericL, numericA] = values;\n\n result.spaceId = 'hsl';\n result.coords = [numericH, numericS, numericL];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericL >= 0 &&\n numericL <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hsvaMatch) {\n const [, h, s, v, a] = hsvaMatch;\n const values = [h, s, v, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericV, numericA] = values;\n\n result.spaceId = 'hsv';\n result.coords = [numericH, numericS, numericV];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericV >= 0 &&\n numericV <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hexMatch) {\n const [, hex, alphaHex] = hexMatch;\n\n // Function to process 2-digit or repeated 1-digit hex\n const processHex = (hex: string): number => {\n // For 3-digit hex values, repeat each digit\n if (hex.length === 1) {\n hex = hex + hex;\n }\n return parseInt(hex, 16) / 255;\n };\n\n // Handle both 3-digit and 6-digit hex\n let numericR, numericG, numericB;\n if (hex.length === 3) {\n // 3-digit hex (e.g., #3a7 -> #33aa77)\n numericR = processHex(hex.substring(0, 1));\n numericG = processHex(hex.substring(1, 2));\n numericB = processHex(hex.substring(2, 3));\n } else {\n // 6-digit hex (e.g., #33aa77)\n numericR = processHex(hex.substring(0, 2));\n numericG = processHex(hex.substring(2, 4));\n numericB = processHex(hex.substring(4, 6));\n }\n\n // Process hex alpha if provided (convert from 0-255 to 0-1)\n const numericA = alphaHex ? processHex(alphaHex) : 1;\n\n // Validate the color values\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = numericA;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n numericA >= 0 &&\n numericA <= 1;\n }\n\n return result;\n }\n\n /**\n * Represents the color state of the component.\n * Initialized with an HSV color model with hue 0, saturation 100, and value 100, and an alpha value of 1.\n *\n * @private\n * @type {Color}\n */\n private _color: Color = new Color('hsv', [0, 100, 100], 1);\n\n /**\n * Represents the original color value provided by the user.\n *\n * @private\n * @type {ColorTypes}\n */\n private _colorOrigin!: ColorTypes;\n\n /**\n * Gets the original color value provided by the user.\n *\n * @returns {ColorTypes} The original color value.\n */\n get colorOrigin(): ColorTypes {\n return this._colorOrigin;\n }\n\n /**\n * Sets the original color value provided by the user.\n *\n * @param {ColorTypes} colorOrigin - The original color value to set.\n */\n set colorOrigin(colorOrigin: ColorTypes) {\n this._colorOrigin = colorOrigin;\n }\n\n /**\n * An optional string property that specifies how the color should be managed(its value is the name of color space in which color object will be managed).\n * This property can be used to define a specific management strategy or identifier.\n */\n private manageAs?: string;\n\n /**\n * Stores the previous color value.\n * This is used to keep track of the color before any changes are made.\n *\n * @private\n */\n private _previousColor!: Color;\n\n /**\n * Private helper method to convert RGB color to hex format with optional alpha\n *\n * @private\n * @param {boolean} includeHash - Whether to include the # prefix in the returned string\n * @param {boolean} includeAlpha - Whether to include the alpha channel in the returned string\n * @returns {string} The color in hex format\n */\n private _getHexString(includeHash: boolean, includeAlpha: boolean): string {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const a = this._color.alpha;\n\n const rHex = Math.round(r * 255)\n .toString(16)\n .padStart(2, '0');\n const gHex = Math.round(g * 255)\n .toString(16)\n .padStart(2, '0');\n const bHex = Math.round(b * 255)\n .toString(16)\n .padStart(2, '0');\n const aHex = Math.round(a * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `${includeHash ? '#' : ''}${rHex}${gHex}${bHex}${includeAlpha ? aHex : ''}`;\n }\n\n /**\n * Sets the color value for the controller. The color can be provided in various formats:\n * - A string representing a color name, hex code, or other color format.\n * - An instance of the `Color` class.\n * - An object containing color properties such as `h`, `s`, `l`, `v`, `r`, `g`, `b`, and optionally `a`.\n *\n * The method validates and parses the input color, converting it to a `Color` instance.\n * If the color is invalid, it attempts to parse it as a hex code or returns without setting a new color.\n *\n * @param {ColorTypes} color - The color value to set. It can be a string, an instance of `Color`, or an object with color properties.\n */\n set color(color: ColorTypes) {\n this._colorOrigin = color;\n let newColor!: Color;\n if (typeof color === 'string') {\n const colorValidationResult = this.validateColorString(\n color as string\n );\n if (colorValidationResult.isValid) {\n const [coord1, coord2, coord3] = colorValidationResult.coords;\n newColor = new Color(\n `${colorValidationResult.spaceId}`,\n [coord1, coord2, coord3],\n colorValidationResult.alpha\n );\n } else {\n try {\n Color.parse(color);\n } catch (error) {\n try {\n newColor = new Color(`#${color}`);\n } catch (error) {\n return;\n }\n }\n }\n } else if (color instanceof Color) {\n newColor = color;\n } else if (!Array.isArray(color)) {\n const { h, s, l, v, r, g, b, a } = color as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n a?: string;\n };\n if (typeof h !== 'undefined' && typeof s !== 'undefined') {\n const lv = l ?? v;\n newColor = new Color(\n typeof l !== 'undefined' ? 'hsl' : 'hsv',\n [\n parseFloat(h),\n typeof s !== 'string' ? s * 100 : parseFloat(s),\n typeof lv !== 'string' ? lv * 100 : parseFloat(lv),\n ],\n parseFloat(a || '1')\n );\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n newColor = new Color(\n 'srgb',\n [\n parseFloat(r) / 255,\n parseFloat(g) / 255,\n parseFloat(b) / 255,\n ],\n parseFloat(a || '1')\n );\n }\n }\n\n if (!newColor) {\n newColor = new Color(color as DefaultColorTypes);\n }\n\n if (this.manageAs) {\n this._color = newColor.to(this.manageAs) as Color;\n } else {\n this._color = newColor;\n }\n this.host.requestUpdate();\n }\n\n /**\n * Gets the color value in various formats based on the original color input.\n *\n * The method determines the color space of the original color input and converts\n * the color to the appropriate format. The supported color spaces are:\n * - HSV (Hue, Saturation, Value)\n * - HSL (Hue, Saturation, Lightness)\n * - Hexadecimal (with or without alpha)\n * - RGB (Red, Green, Blue) with optional alpha\n *\n * @returns {ColorTypes} The color value in the appropriate format.\n *\n * The method handles the following cases:\n * - If the original color input is a string, it checks the prefix to determine the color space.\n * - If the original color input is an object, it checks the properties to determine the color space.\n * - If the original color input is not provided, it defaults to the current color space of the color object.\n *\n * The returned color value can be in one of the following formats:\n * - `hsv(h, s%, v%)` or `hsva(h, s%, v%, a)`\n * - `hsl(h, s%, l%)` or `hsla(h, s%, l%, a)`\n * - `#rrggbb` or `#rrggbbaa`\n * - `rgb(r, g, b)` or `rgba(r, g, b, a)`\n * - `{ h, s, v, a }` for HSV object\n * - `{ h, s, l, a }` for HSL object\n * - `{ r, g, b, a }` for RGB object\n */\n get colorValue(): ColorTypes {\n if (typeof this._colorOrigin === 'string') {\n let spaceId = '';\n if (this._colorOrigin.startsWith('#')) {\n spaceId = 'hex string';\n } else if (this._colorOrigin.startsWith('rgb')) {\n spaceId = 'rgb';\n } else if (this._colorOrigin.startsWith('hsl')) {\n spaceId = 'hsl';\n } else if (this._colorOrigin.startsWith('hsv')) {\n spaceId = 'hsv';\n } else {\n spaceId = 'hex';\n }\n switch (spaceId) {\n case 'hsv': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n const a = this._color.alpha;\n return `hsv${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(v)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hsl': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n const a = this._color.alpha;\n return `hsl${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(l)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hex string': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 9 || // #RRGGBBAA format\n this._colorOrigin.length === 5; // #RGBA format\n return this._getHexString(true, hadAlpha);\n }\n case 'hex': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 8 || // RRGGBBAA format (no #)\n this._colorOrigin.length === 4; // RGBA format (no #)\n return this._getHexString(false, hadAlpha);\n }\n //rgb\n default: {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const hadAlpha = this._colorOrigin[3] === 'a';\n const a = this._color.alpha;\n if (this._colorOrigin.search('%') > -1) {\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 100)}%, ${Math.round(\n g * 100\n )}%, ${Math.round(b * 100)}%${hadAlpha ? `,${Math.round(a * 100)}%` : ''})`;\n }\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 255)}, ${Math.round(\n g * 255\n )}, ${Math.round(b * 255)}${hadAlpha ? `, ${a}` : ''})`;\n }\n }\n }\n let spaceId;\n if (this._colorOrigin) {\n try {\n ({ spaceId } = new Color(\n this._colorOrigin as DefaultColorTypes\n ));\n } catch (error) {\n const { h, s, l, v, r, g, b } = this._colorOrigin as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n };\n if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof l !== 'undefined'\n ) {\n spaceId = 'hsl';\n } else if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof v !== 'undefined'\n ) {\n spaceId = 'hsv';\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n spaceId = 'srgb';\n }\n }\n } else {\n ({ spaceId } = this.color);\n }\n switch (spaceId) {\n case 'hsv': {\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n return {\n h,\n s: s / 100,\n v: v / 100,\n a: this._color.alpha,\n };\n }\n case 'hsl': {\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n return {\n h,\n s: s / 100,\n l: l / 100,\n a: this._color.alpha,\n };\n }\n case 'srgb': {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n if (\n this._colorOrigin &&\n typeof (this._colorOrigin as { r: string }).r ===\n 'string' &&\n (this._colorOrigin as { r: string }).r.search('%')\n ) {\n return {\n r: `${Math.round(r * 255)}%`,\n g: `${Math.round(g * 255)}%`,\n b: `${Math.round(b * 255)}%`,\n a: this._color.alpha,\n };\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: this._color.alpha,\n };\n }\n }\n return this._color;\n }\n\n protected host: ReactiveElement;\n\n /**\n * Gets the hue value of the current color in HSL format.\n *\n * @returns {number} The hue value as a number.\n */\n get hue(): number {\n return Number((this._color.to('hsl') as Color).hsl.h);\n }\n\n /**\n * Sets the hue value of the color and requests an update from the host.\n *\n * @param hue - The hue value to set, represented as a number.\n */\n set hue(hue: number) {\n this._color.set('h', hue);\n this.host.requestUpdate();\n }\n\n /**\n * Creates an instance of ColorController.\n *\n * @param host - The ReactiveElement that this controller is associated with.\n * @param options - An object containing optional parameters.\n * @param options.manageAs - A string to manage the controller as a specific type.\n */\n constructor(\n host: ReactiveElement,\n {\n manageAs,\n }: {\n manageAs?: string;\n } = {}\n ) {\n this.host = host;\n this.manageAs = manageAs;\n }\n\n /**\n * Converts the current color to the specified format.\n *\n * @param format - The desired color format. It can be a string representing one of the valid formats\n * ('srgb', 'hsva', 'hsv', 'hsl', 'hsla') or a ColorSpace object.\n * @returns The color object in the specified format.\n * @throws Will throw an error if the provided format is not a valid string format.\n */\n getColor(format: string | ColorSpace): ColorObject {\n const validFormats = ['srgb', 'hsva', 'hsv', 'hsl', 'hsla'];\n if (typeof format === 'string' && !validFormats.includes(format)) {\n throw new Error('not a valid format');\n }\n\n return this._color.to(format);\n }\n\n /**\n * Converts the current color to an HSL string representation.\n *\n * @returns {string} The HSL string representation of the current color.\n */\n getHslString(): string {\n return this._color.to('hsl').toString();\n }\n\n /**\n * Saves the current color state by cloning the current color and storing it\n * as the previous color. This allows for the ability to revert to the previous\n * color state if needed.\n *\n * @returns {void}\n */\n savePreviousColor(): void {\n this._previousColor = this._color.clone();\n }\n\n /**\n * Restores the color to the previously saved color value.\n *\n * This method sets the current color (`_color`) to the previously stored color (`_previousColor`).\n */\n restorePreviousColor(): void {\n this._color = this._previousColor;\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveElement } from 'lit';\nimport Color from 'colorjs.io';\nimport type {\n ColorObject,\n ColorTypes as DefaultColorTypes,\n} from 'colorjs.io/types/src/color';\nimport type ColorSpace from 'colorjs.io/types/src/space';\n\n/**\n * Represents various color types that can be used in the application.\n *\n * This type can be one of the following:\n * - `DefaultColorTypes`: A predefined set of color types.\n * - An object representing an RGBA color with properties:\n * - `r`: Red component, can be a number or string.\n * - `g`: Green component, can be a number or string.\n * - `b`: Blue component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSLA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `l`: Lightness component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSVA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `v`: Value component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n */\ntype ColorTypes =\n | DefaultColorTypes\n | {\n r: number | string;\n g: number | string;\n b: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n l: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n v: number | string;\n a?: number | string;\n };\n\nexport type { Color, ColorTypes };\n\ntype ColorValidationResult = {\n spaceId: string | null;\n coords: number[];\n isValid: boolean;\n alpha: number;\n};\n\n/**\n * The `ColorController` class is responsible for managing and validating color values\n * in various color spaces (RGB, HSL, HSV, Hex). It provides methods to set, get, and\n * validate colors, as well as convert between different color formats.\n *\n * @class\n * @property {Color} color - Gets or sets the current color value.\n * @property {ColorTypes} colorValue - Gets the color value in various formats based on the original color input.\n * @property {number} hue - Gets or sets the hue value of the current color.\n *\n * @method validateColorString(color: string): ColorValidationResult - Validates a color string and returns the validation result.\n * @method getColor(format: string | ColorSpace): ColorObject - Converts the current color to the specified format.\n * @method getHslString(): string - Returns the current color in HSL string format.\n * @method savePreviousColor(): void - Saves the current color as the previous color.\n * @method restorePreviousColor(): void - Restores the previous color.\n *\n * @constructor\n * @param {ReactiveElement} host - The host element that uses this controller.\n * @param {Object} [options] - Optional configuration options.\n * @param {string} [options.manageAs] - Specifies the color space to manage the color as.\n */\n\nexport class ColorController {\n get color(): Color {\n return this._color;\n }\n\n /**\n * Validates a color string and returns a result indicating the color space,\n * coordinates, alpha value, and whether the color is valid.\n *\n * @param color - The color string to validate. Supported formats include:\n * - RGB: `rgb(r, g, b)`, `rgba(r, g, b, a)`, `rgb r g b`, `rgba r g b a`\n * - HSL: `hsl(h, s, l)`, `hsla(h, s, l, a)`, `hsl h s l`, `hsla h s l a`\n * - HSV: `hsv(h, s, v)`, `hsva(h, s, v, a)`, `hsv h s v`, `hsva h s v a`\n * - HEX: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`\n *\n * @returns An object containing the following properties:\n * - `spaceId`: The color space identifier (`'srgb'`, `'hsl'`, or `'hsv'`).\n * - `coords`: An array of numeric values representing the color coordinates.\n * - `alpha`: The alpha value of the color (0 to 1).\n * - `isValid`: A boolean indicating whether the color string is valid.\n */\n public validateColorString(color: string): ColorValidationResult {\n const result: ColorValidationResult = {\n spaceId: null,\n coords: [0, 0, 0],\n isValid: false,\n alpha: 1,\n };\n\n // RGB color formats\n const rgbRegExpArray = [\n // With commas\n /rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r, g, b, a)\n /rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)/i, // rgb(r, g, b)\n\n // With spaces\n /^rgba\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(0|0?\\.\\d+|1)\\s*$/i, // rgba r g b a\n /^rgb\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$/i, // rgb r g b\n\n // Spaces inside parentheses\n /^rgba\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // rgba(r g b a)\n /^rgb\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*\\)$/i, // rgb(r g b)\n\n // Percentage values\n /rgb\\(\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*\\)/i, // rgb(r%, g%, b%)\n /rgba\\(\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r%, g%, b%, a)\n ];\n\n // HSL color formats\n const hslRegExpArray = [\n // With commas\n /hsla\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsla(h, s, l, a)\n /hsl\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsl(h, s, l)\n\n // With spaces\n /^hsla\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsla h s l a\n /^hsl\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsl h s l\n\n // Spaces inside parentheses\n /^hsla\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsla(h s l a)\n /^hsl\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsl(h s l)\n ];\n\n // HSV color formats\n const hsvRegExpArray = [\n // With commas\n /hsva\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsva(h, s, v, a)\n /hsv\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsv(h, s, v)\n\n // With spaces\n /^hsva\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsva h s v a\n /^hsv\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsv h s v\n\n // Spaces inside parentheses\n /^hsva\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsva(h s v a)\n /^hsv\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsv(h s v)\n ];\n\n // HEX color formats\n const hexRegExpArray = [\n /^#([A-Fa-f0-9]{6})([A-Fa-f0-9]{2})?$/, // 6-digit hex with optional hex alpha\n /^#([A-Fa-f0-9]{3})([A-Fa-f0-9]{1})?$/, // 3-digit hex with optional hex alpha\n ];\n\n const rgbaMatch = rgbRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hslaMatch = hslRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hsvaMatch = hsvRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hexMatch = hexRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch.filter(\n (element) => typeof element === 'string'\n );\n const alpha = a === undefined ? 1 : Number(a);\n const processValue = (value: string): number => {\n if (value.includes('%')) {\n return Number(value.replace('%', '')) / 100;\n } else {\n return Number(value) / 255;\n }\n };\n const numericR = processValue(r);\n const numericG = processValue(g);\n const numericB = processValue(b);\n\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = alpha;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n alpha >= 0 &&\n alpha <= 1;\n } else if (hslaMatch) {\n const [, h, s, l, a] = hslaMatch;\n const values = [h, s, l, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericL, numericA] = values;\n\n result.spaceId = 'hsl';\n result.coords = [numericH, numericS, numericL];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericL >= 0 &&\n numericL <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hsvaMatch) {\n const [, h, s, v, a] = hsvaMatch;\n const values = [h, s, v, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericV, numericA] = values;\n\n result.spaceId = 'hsv';\n result.coords = [numericH, numericS, numericV];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericV >= 0 &&\n numericV <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hexMatch) {\n const [, hex, alphaHex] = hexMatch;\n\n // Function to process 2-digit or repeated 1-digit hex\n const processHex = (hex: string): number => {\n // For 3-digit hex values, repeat each digit\n if (hex.length === 1) {\n hex = hex + hex;\n }\n return parseInt(hex, 16) / 255;\n };\n\n // Handle both 3-digit and 6-digit hex\n let numericR, numericG, numericB;\n if (hex.length === 3) {\n // 3-digit hex (e.g., #3a7 -> #33aa77)\n numericR = processHex(hex.substring(0, 1));\n numericG = processHex(hex.substring(1, 2));\n numericB = processHex(hex.substring(2, 3));\n } else {\n // 6-digit hex (e.g., #33aa77)\n numericR = processHex(hex.substring(0, 2));\n numericG = processHex(hex.substring(2, 4));\n numericB = processHex(hex.substring(4, 6));\n }\n\n // Process hex alpha if provided (convert from 0-255 to 0-1)\n const numericA = alphaHex ? processHex(alphaHex) : 1;\n\n // Validate the color values\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = numericA;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n numericA >= 0 &&\n numericA <= 1;\n }\n\n return result;\n }\n\n /**\n * Represents the color state of the component.\n * Initialized with an HSV color model with hue 0, saturation 100, and value 100, and an alpha value of 1.\n *\n * @private\n * @type {Color}\n */\n private _color: Color = new Color('hsv', [0, 100, 100], 1);\n\n /**\n * Represents the original color value provided by the user.\n *\n * @private\n * @type {ColorTypes}\n */\n private _colorOrigin!: ColorTypes;\n\n /**\n * Gets the original color value provided by the user.\n *\n * @returns {ColorTypes} The original color value.\n */\n get colorOrigin(): ColorTypes {\n return this._colorOrigin;\n }\n\n /**\n * Sets the original color value provided by the user.\n *\n * @param {ColorTypes} colorOrigin - The original color value to set.\n */\n set colorOrigin(colorOrigin: ColorTypes) {\n this._colorOrigin = colorOrigin;\n }\n\n /**\n * An optional string property that specifies how the color should be managed(its value is the name of color space in which color object will be managed).\n * This property can be used to define a specific management strategy or identifier.\n */\n private manageAs?: string;\n\n /**\n * Stores the previous color value.\n * This is used to keep track of the color before any changes are made.\n *\n * @private\n */\n private _previousColor!: Color;\n\n /**\n * Private helper method to convert RGB color to hex format with optional alpha\n *\n * @private\n * @param {boolean} includeHash - Whether to include the # prefix in the returned string\n * @param {boolean} includeAlpha - Whether to include the alpha channel in the returned string\n * @returns {string} The color in hex format\n */\n private _getHexString(includeHash: boolean, includeAlpha: boolean): string {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const a = this._color.alpha;\n\n const rHex = Math.round(r * 255)\n .toString(16)\n .padStart(2, '0');\n const gHex = Math.round(g * 255)\n .toString(16)\n .padStart(2, '0');\n const bHex = Math.round(b * 255)\n .toString(16)\n .padStart(2, '0');\n const aHex = Math.round(a * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `${includeHash ? '#' : ''}${rHex}${gHex}${bHex}${includeAlpha ? aHex : ''}`;\n }\n\n /**\n * Sets the color value for the controller. The color can be provided in various formats:\n * - A string representing a color name, hex code, or other color format.\n * - An instance of the `Color` class.\n * - An object containing color properties such as `h`, `s`, `l`, `v`, `r`, `g`, `b`, and optionally `a`.\n *\n * The method validates and parses the input color, converting it to a `Color` instance.\n * If the color is invalid, it attempts to parse it as a hex code or returns without setting a new color.\n *\n * @param {ColorTypes} color - The color value to set. It can be a string, an instance of `Color`, or an object with color properties.\n */\n set color(color: ColorTypes) {\n this._colorOrigin = color;\n let newColor!: Color;\n if (typeof color === 'string') {\n const colorValidationResult = this.validateColorString(\n color as string\n );\n if (colorValidationResult.isValid) {\n const [coord1, coord2, coord3] = colorValidationResult.coords;\n newColor = new Color(\n `${colorValidationResult.spaceId}`,\n [coord1, coord2, coord3],\n colorValidationResult.alpha\n );\n } else {\n try {\n Color.parse(color);\n } catch (error) {\n try {\n newColor = new Color(`#${color}`);\n } catch (error) {\n return;\n }\n }\n }\n } else if (color instanceof Color) {\n newColor = color;\n } else if (!Array.isArray(color)) {\n const { h, s, l, v, r, g, b, a } = color as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n a?: string;\n };\n if (typeof h !== 'undefined' && typeof s !== 'undefined') {\n const lv = l ?? v;\n newColor = new Color(\n typeof l !== 'undefined' ? 'hsl' : 'hsv',\n [\n parseFloat(h),\n typeof s !== 'string' ? s * 100 : parseFloat(s),\n typeof lv !== 'string' ? lv * 100 : parseFloat(lv),\n ],\n parseFloat(a || '1')\n );\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n newColor = new Color(\n 'srgb',\n [\n parseFloat(r) / 255,\n parseFloat(g) / 255,\n parseFloat(b) / 255,\n ],\n parseFloat(a || '1')\n );\n }\n }\n\n if (!newColor) {\n newColor = new Color(color as DefaultColorTypes);\n }\n\n if (this.manageAs) {\n this._color = newColor.to(this.manageAs) as Color;\n } else {\n this._color = newColor;\n }\n this.host.requestUpdate();\n }\n\n /**\n * Gets the color value in various formats based on the original color input.\n *\n * The method determines the color space of the original color input and converts\n * the color to the appropriate format. The supported color spaces are:\n * - HSV (Hue, Saturation, Value)\n * - HSL (Hue, Saturation, Lightness)\n * - Hexadecimal (with or without alpha)\n * - RGB (Red, Green, Blue) with optional alpha\n *\n * @returns {ColorTypes} The color value in the appropriate format.\n *\n * The method handles the following cases:\n * - If the original color input is a string, it checks the prefix to determine the color space.\n * - If the original color input is an object, it checks the properties to determine the color space.\n * - If the original color input is not provided, it defaults to the current color space of the color object.\n *\n * The returned color value can be in one of the following formats:\n * - `hsv(h, s%, v%)` or `hsva(h, s%, v%, a)`\n * - `hsl(h, s%, l%)` or `hsla(h, s%, l%, a)`\n * - `#rrggbb` or `#rrggbbaa`\n * - `rgb(r, g, b)` or `rgba(r, g, b, a)`\n * - `{ h, s, v, a }` for HSV object\n * - `{ h, s, l, a }` for HSL object\n * - `{ r, g, b, a }` for RGB object\n */\n get colorValue(): ColorTypes {\n if (typeof this._colorOrigin === 'string') {\n let spaceId = '';\n if (this._colorOrigin.startsWith('#')) {\n spaceId = 'hex string';\n } else if (this._colorOrigin.startsWith('rgb')) {\n spaceId = 'rgb';\n } else if (this._colorOrigin.startsWith('hsl')) {\n spaceId = 'hsl';\n } else if (this._colorOrigin.startsWith('hsv')) {\n spaceId = 'hsv';\n } else {\n spaceId = 'hex';\n }\n switch (spaceId) {\n case 'hsv': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n const a = this._color.alpha;\n return `hsv${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(v)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hsl': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n const a = this._color.alpha;\n return `hsl${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(l)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hex string': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 9 || // #RRGGBBAA format\n this._colorOrigin.length === 5; // #RGBA format\n return this._getHexString(true, hadAlpha);\n }\n case 'hex': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 8 || // RRGGBBAA format (no #)\n this._colorOrigin.length === 4; // RGBA format (no #)\n return this._getHexString(false, hadAlpha);\n }\n //rgb\n default: {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const hadAlpha = this._colorOrigin[3] === 'a';\n const a = this._color.alpha;\n if (this._colorOrigin.search('%') > -1) {\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 100)}%, ${Math.round(\n g * 100\n )}%, ${Math.round(b * 100)}%${hadAlpha ? `,${Math.round(a * 100)}%` : ''})`;\n }\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 255)}, ${Math.round(\n g * 255\n )}, ${Math.round(b * 255)}${hadAlpha ? `, ${a}` : ''})`;\n }\n }\n }\n let spaceId;\n if (this._colorOrigin) {\n try {\n ({ spaceId } = new Color(\n this._colorOrigin as DefaultColorTypes\n ));\n } catch (error) {\n const { h, s, l, v, r, g, b } = this._colorOrigin as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n };\n if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof l !== 'undefined'\n ) {\n spaceId = 'hsl';\n } else if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof v !== 'undefined'\n ) {\n spaceId = 'hsv';\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n spaceId = 'srgb';\n }\n }\n } else {\n ({ spaceId } = this.color);\n }\n switch (spaceId) {\n case 'hsv': {\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n return {\n h,\n s: s / 100,\n v: v / 100,\n a: this._color.alpha,\n };\n }\n case 'hsl': {\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n return {\n h,\n s: s / 100,\n l: l / 100,\n a: this._color.alpha,\n };\n }\n case 'srgb': {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n if (\n this._colorOrigin &&\n typeof (this._colorOrigin as { r: string }).r ===\n 'string' &&\n (this._colorOrigin as { r: string }).r.search('%')\n ) {\n return {\n r: `${Math.round(r * 255)}%`,\n g: `${Math.round(g * 255)}%`,\n b: `${Math.round(b * 255)}%`,\n a: this._color.alpha,\n };\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: this._color.alpha,\n };\n }\n }\n return this._color;\n }\n\n protected host: ReactiveElement;\n\n /**\n * Gets the hue value of the current color in HSL format.\n *\n * @returns {number} The hue value as a number.\n */\n get hue(): number {\n return Number((this._color.to('hsl') as Color).hsl.h);\n }\n\n /**\n * Sets the hue value of the color and requests an update from the host.\n *\n * @param hue - The hue value to set, represented as a number.\n */\n set hue(hue: number) {\n this._color.set('h', hue);\n this.host.requestUpdate();\n }\n\n /**\n * Creates an instance of ColorController.\n *\n * @param host - The ReactiveElement that this controller is associated with.\n * @param options - An object containing optional parameters.\n * @param options.manageAs - A string to manage the controller as a specific type.\n */\n constructor(\n host: ReactiveElement,\n {\n manageAs,\n }: {\n manageAs?: string;\n } = {}\n ) {\n this.host = host;\n this.manageAs = manageAs;\n }\n\n /**\n * Converts the current color to the specified format.\n *\n * @param format - The desired color format. It can be a string representing one of the valid formats\n * ('srgb', 'hsva', 'hsv', 'hsl', 'hsla') or a ColorSpace object.\n * @returns The color object in the specified format.\n * @throws Will throw an error if the provided format is not a valid string format.\n */\n getColor(format: string | ColorSpace): ColorObject {\n const validFormats = ['srgb', 'hsva', 'hsv', 'hsl', 'hsla'];\n if (typeof format === 'string' && !validFormats.includes(format)) {\n throw new Error('not a valid format');\n }\n\n return this._color.to(format);\n }\n\n /**\n * Converts the current color to an HSL string representation.\n *\n * @returns {string} The HSL string representation of the current color.\n */\n getHslString(): string {\n return this._color.to('hsl').toString();\n }\n\n /**\n * Saves the current color state by cloning the current color and storing it\n * as the previous color. This allows for the ability to revert to the previous\n * color state if needed.\n *\n * @returns {void}\n */\n savePreviousColor(): void {\n this._previousColor = this._color.clone();\n }\n\n /**\n * Restores the color to the previously saved color value.\n *\n * This method sets the current color (`_color`) to the previously stored color (`_previousColor`).\n */\n restorePreviousColor(): void {\n this._color = this._previousColor;\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["hex", "error", "spaceId"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["ColorController.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveElement } from 'lit';\nimport Color from 'colorjs.io';\nimport type {\n ColorObject,\n ColorTypes as DefaultColorTypes,\n} from 'colorjs.io/types/src/color';\nimport type ColorSpace from 'colorjs.io/types/src/space';\n\n/**\n * Represents various color types that can be used in the application.\n *\n * This type can be one of the following:\n * - `DefaultColorTypes`: A predefined set of color types.\n * - An object representing an RGBA color with properties:\n * - `r`: Red component, can be a number or string.\n * - `g`: Green component, can be a number or string.\n * - `b`: Blue component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSLA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `l`: Lightness component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSVA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `v`: Value component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n */\ntype ColorTypes =\n | DefaultColorTypes\n | {\n r: number | string;\n g: number | string;\n b: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n l: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n v: number | string;\n a?: number | string;\n };\n\nexport type { Color, ColorTypes };\n\ntype ColorValidationResult = {\n spaceId: string | null;\n coords: number[];\n isValid: boolean;\n alpha: number;\n};\n\n/**\n * The `ColorController` class is responsible for managing and validating color values\n * in various color spaces (RGB, HSL, HSV, Hex). It provides methods to set, get, and\n * validate colors, as well as convert between different color formats.\n *\n * @class\n * @property {Color} color - Gets or sets the current color value.\n * @property {ColorTypes} colorValue - Gets the color value in various formats based on the original color input.\n * @property {number} hue - Gets or sets the hue value of the current color.\n *\n * @method validateColorString(color: string): ColorValidationResult - Validates a color string and returns the validation result.\n * @method getColor(format: string | ColorSpace): ColorObject - Converts the current color to the specified format.\n * @method getHslString(): string - Returns the current color in HSL string format.\n * @method savePreviousColor(): void - Saves the current color as the previous color.\n * @method restorePreviousColor(): void - Restores the previous color.\n *\n * @constructor\n * @param {ReactiveElement} host - The host element that uses this controller.\n * @param {Object} [options] - Optional configuration options.\n * @param {string} [options.manageAs] - Specifies the color space to manage the color as.\n */\n\nexport class ColorController {\n get color(): Color {\n return this._color;\n }\n\n /**\n * Validates a color string and returns a result indicating the color space,\n * coordinates, alpha value, and whether the color is valid.\n *\n * @param color - The color string to validate. Supported formats include:\n * - RGB: `rgb(r, g, b)`, `rgba(r, g, b, a)`, `rgb r g b`, `rgba r g b a`\n * - HSL: `hsl(h, s, l)`, `hsla(h, s, l, a)`, `hsl h s l`, `hsla h s l a`\n * - HSV: `hsv(h, s, v)`, `hsva(h, s, v, a)`, `hsv h s v`, `hsva h s v a`\n * - HEX: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`\n *\n * @returns An object containing the following properties:\n * - `spaceId`: The color space identifier (`'srgb'`, `'hsl'`, or `'hsv'`).\n * - `coords`: An array of numeric values representing the color coordinates.\n * - `alpha`: The alpha value of the color (0 to 1).\n * - `isValid`: A boolean indicating whether the color string is valid.\n */\n public validateColorString(color: string): ColorValidationResult {\n const result: ColorValidationResult = {\n spaceId: null,\n coords: [0, 0, 0],\n isValid: false,\n alpha: 1,\n };\n\n // RGB color formats\n const rgbRegExpArray = [\n // With commas\n /rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r, g, b, a)\n /rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)/i, // rgb(r, g, b)\n\n // With spaces\n /^rgba\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(0|0?\\.\\d+|1)\\s*$/i, // rgba r g b a\n /^rgb\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$/i, // rgb r g b\n\n // Spaces inside parentheses\n /^rgba\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // rgba(r g b a)\n /^rgb\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*\\)$/i, // rgb(r g b)\n\n // Percentage values\n /rgb\\(\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*\\)/i, // rgb(r%, g%, b%)\n /rgba\\(\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r%, g%, b%, a)\n ];\n\n // HSL color formats\n const hslRegExpArray = [\n // With commas\n /hsla\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsla(h, s, l, a)\n /hsl\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsl(h, s, l)\n\n // With spaces\n /^hsla\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsla h s l a\n /^hsl\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsl h s l\n\n // Spaces inside parentheses\n /^hsla\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsla(h s l a)\n /^hsl\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsl(h s l)\n ];\n\n // HSV color formats\n const hsvRegExpArray = [\n // With commas\n /hsva\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsva(h, s, v, a)\n /hsv\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsv(h, s, v)\n\n // With spaces\n /^hsva\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsva h s v a\n /^hsv\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsv h s v\n\n // Spaces inside parentheses\n /^hsva\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsva(h s v a)\n /^hsv\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsv(h s v)\n ];\n\n // HEX color formats\n const hexRegExpArray = [\n /^#([A-Fa-f0-9]{6})([A-Fa-f0-9]{2})?$/, // 6-digit hex with optional hex alpha\n /^#([A-Fa-f0-9]{3})([A-Fa-f0-9]{1})?$/, // 3-digit hex with optional hex alpha\n ];\n\n const rgbaMatch = rgbRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hslaMatch = hslRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hsvaMatch = hsvRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hexMatch = hexRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch.filter(\n (element) => typeof element === 'string'\n );\n const alpha = a === undefined ? 1 : Number(a);\n const processValue = (value: string): number => {\n if (value.includes('%')) {\n return Number(value.replace('%', '')) / 100;\n } else {\n return Number(value) / 255;\n }\n };\n const numericR = processValue(r);\n const numericG = processValue(g);\n const numericB = processValue(b);\n\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = alpha;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n alpha >= 0 &&\n alpha <= 1;\n } else if (hslaMatch) {\n const [, h, s, l, a] = hslaMatch;\n const values = [h, s, l, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericL, numericA] = values;\n\n result.spaceId = 'hsl';\n result.coords = [numericH, numericS, numericL];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericL >= 0 &&\n numericL <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hsvaMatch) {\n const [, h, s, v, a] = hsvaMatch;\n const values = [h, s, v, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericV, numericA] = values;\n\n result.spaceId = 'hsv';\n result.coords = [numericH, numericS, numericV];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericV >= 0 &&\n numericV <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hexMatch) {\n const [, hex, alphaHex] = hexMatch;\n\n // Function to process 2-digit or repeated 1-digit hex\n const processHex = (hex: string): number => {\n // For 3-digit hex values, repeat each digit\n if (hex.length === 1) {\n hex = hex + hex;\n }\n return parseInt(hex, 16) / 255;\n };\n\n // Handle both 3-digit and 6-digit hex\n let numericR, numericG, numericB;\n if (hex.length === 3) {\n // 3-digit hex (e.g., #3a7 -> #33aa77)\n numericR = processHex(hex.substring(0, 1));\n numericG = processHex(hex.substring(1, 2));\n numericB = processHex(hex.substring(2, 3));\n } else {\n // 6-digit hex (e.g., #33aa77)\n numericR = processHex(hex.substring(0, 2));\n numericG = processHex(hex.substring(2, 4));\n numericB = processHex(hex.substring(4, 6));\n }\n\n // Process hex alpha if provided (convert from 0-255 to 0-1)\n const numericA = alphaHex ? processHex(alphaHex) : 1;\n\n // Validate the color values\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = numericA;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n numericA >= 0 &&\n numericA <= 1;\n }\n\n return result;\n }\n\n /**\n * Represents the color state of the component.\n * Initialized with an HSV color model with hue 0, saturation 100, and value 100, and an alpha value of 1.\n *\n * @private\n * @type {Color}\n */\n private _color: Color = new Color('hsv', [0, 100, 100], 1);\n\n /**\n * Represents the original color value provided by the user.\n *\n * @private\n * @type {ColorTypes}\n */\n private _colorOrigin!: ColorTypes;\n\n /**\n * Gets the original color value provided by the user.\n *\n * @returns {ColorTypes} The original color value.\n */\n get colorOrigin(): ColorTypes {\n return this._colorOrigin;\n }\n\n /**\n * Sets the original color value provided by the user.\n *\n * @param {ColorTypes} colorOrigin - The original color value to set.\n */\n set colorOrigin(colorOrigin: ColorTypes) {\n this._colorOrigin = colorOrigin;\n }\n\n /**\n * An optional string property that specifies how the color should be managed(its value is the name of color space in which color object will be managed).\n * This property can be used to define a specific management strategy or identifier.\n */\n private manageAs?: string;\n\n /**\n * Stores the previous color value.\n * This is used to keep track of the color before any changes are made.\n *\n * @private\n */\n private _previousColor!: Color;\n\n /**\n * Private helper method to convert RGB color to hex format with optional alpha\n *\n * @private\n * @param {boolean} includeHash - Whether to include the # prefix in the returned string\n * @param {boolean} includeAlpha - Whether to include the alpha channel in the returned string\n * @returns {string} The color in hex format\n */\n private _getHexString(includeHash: boolean, includeAlpha: boolean): string {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const a = this._color.alpha;\n\n const rHex = Math.round(r * 255)\n .toString(16)\n .padStart(2, '0');\n const gHex = Math.round(g * 255)\n .toString(16)\n .padStart(2, '0');\n const bHex = Math.round(b * 255)\n .toString(16)\n .padStart(2, '0');\n const aHex = Math.round(a * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `${includeHash ? '#' : ''}${rHex}${gHex}${bHex}${includeAlpha ? aHex : ''}`;\n }\n\n /**\n * Sets the color value for the controller. The color can be provided in various formats:\n * - A string representing a color name, hex code, or other color format.\n * - An instance of the `Color` class.\n * - An object containing color properties such as `h`, `s`, `l`, `v`, `r`, `g`, `b`, and optionally `a`.\n *\n * The method validates and parses the input color, converting it to a `Color` instance.\n * If the color is invalid, it attempts to parse it as a hex code or returns without setting a new color.\n *\n * @param {ColorTypes} color - The color value to set. It can be a string, an instance of `Color`, or an object with color properties.\n */\n set color(color: ColorTypes) {\n this._colorOrigin = color;\n let newColor!: Color;\n if (typeof color === 'string') {\n const colorValidationResult = this.validateColorString(\n color as string\n );\n if (colorValidationResult.isValid) {\n const [coord1, coord2, coord3] = colorValidationResult.coords;\n newColor = new Color(\n `${colorValidationResult.spaceId}`,\n [coord1, coord2, coord3],\n colorValidationResult.alpha\n );\n } else {\n try {\n Color.parse(color);\n } catch (error) {\n try {\n newColor = new Color(`#${color}`);\n } catch (error) {\n return;\n }\n }\n }\n } else if (color instanceof Color) {\n newColor = color;\n } else if (!Array.isArray(color)) {\n const { h, s, l, v, r, g, b, a } = color as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n a?: string;\n };\n if (typeof h !== 'undefined' && typeof s !== 'undefined') {\n const lv = l ?? v;\n newColor = new Color(\n typeof l !== 'undefined' ? 'hsl' : 'hsv',\n [\n parseFloat(h),\n typeof s !== 'string' ? s * 100 : parseFloat(s),\n typeof lv !== 'string' ? lv * 100 : parseFloat(lv),\n ],\n parseFloat(a || '1')\n );\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n newColor = new Color(\n 'srgb',\n [\n parseFloat(r) / 255,\n parseFloat(g) / 255,\n parseFloat(b) / 255,\n ],\n parseFloat(a || '1')\n );\n }\n }\n\n if (!newColor) {\n newColor = new Color(color as DefaultColorTypes);\n }\n\n if (this.manageAs) {\n this._color = newColor.to(this.manageAs) as Color;\n } else {\n this._color = newColor;\n }\n this.host.requestUpdate();\n }\n\n /**\n * Gets the color value in various formats based on the original color input.\n *\n * The method determines the color space of the original color input and converts\n * the color to the appropriate format. The supported color spaces are:\n * - HSV (Hue, Saturation, Value)\n * - HSL (Hue, Saturation, Lightness)\n * - Hexadecimal (with or without alpha)\n * - RGB (Red, Green, Blue) with optional alpha\n *\n * @returns {ColorTypes} The color value in the appropriate format.\n *\n * The method handles the following cases:\n * - If the original color input is a string, it checks the prefix to determine the color space.\n * - If the original color input is an object, it checks the properties to determine the color space.\n * - If the original color input is not provided, it defaults to the current color space of the color object.\n *\n * The returned color value can be in one of the following formats:\n * - `hsv(h, s%, v%)` or `hsva(h, s%, v%, a)`\n * - `hsl(h, s%, l%)` or `hsla(h, s%, l%, a)`\n * - `#rrggbb` or `#rrggbbaa`\n * - `rgb(r, g, b)` or `rgba(r, g, b, a)`\n * - `{ h, s, v, a }` for HSV object\n * - `{ h, s, l, a }` for HSL object\n * - `{ r, g, b, a }` for RGB object\n */\n get colorValue(): ColorTypes {\n if (typeof this._colorOrigin === 'string') {\n let spaceId = '';\n if (this._colorOrigin.startsWith('#')) {\n spaceId = 'hex string';\n } else if (this._colorOrigin.startsWith('rgb')) {\n spaceId = 'rgb';\n } else if (this._colorOrigin.startsWith('hsl')) {\n spaceId = 'hsl';\n } else if (this._colorOrigin.startsWith('hsv')) {\n spaceId = 'hsv';\n } else {\n spaceId = 'hex';\n }\n switch (spaceId) {\n case 'hsv': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n const a = this._color.alpha;\n return `hsv${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(v)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hsl': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n const a = this._color.alpha;\n return `hsl${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(l)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hex string': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 9 || // #RRGGBBAA format\n this._colorOrigin.length === 5; // #RGBA format\n return this._getHexString(true, hadAlpha);\n }\n case 'hex': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 8 || // RRGGBBAA format (no #)\n this._colorOrigin.length === 4; // RGBA format (no #)\n return this._getHexString(false, hadAlpha);\n }\n //rgb\n default: {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const hadAlpha = this._colorOrigin[3] === 'a';\n const a = this._color.alpha;\n if (this._colorOrigin.search('%') > -1) {\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 100)}%, ${Math.round(\n g * 100\n )}%, ${Math.round(b * 100)}%${hadAlpha ? `,${Math.round(a * 100)}%` : ''})`;\n }\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 255)}, ${Math.round(\n g * 255\n )}, ${Math.round(b * 255)}${hadAlpha ? `, ${a}` : ''})`;\n }\n }\n }\n let spaceId;\n if (this._colorOrigin) {\n try {\n ({ spaceId } = new Color(\n this._colorOrigin as DefaultColorTypes\n ));\n } catch (error) {\n const { h, s, l, v, r, g, b } = this._colorOrigin as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n };\n if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof l !== 'undefined'\n ) {\n spaceId = 'hsl';\n } else if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof v !== 'undefined'\n ) {\n spaceId = 'hsv';\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n spaceId = 'srgb';\n }\n }\n } else {\n ({ spaceId } = this.color);\n }\n switch (spaceId) {\n case 'hsv': {\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n return {\n h,\n s: s / 100,\n v: v / 100,\n a: this._color.alpha,\n };\n }\n case 'hsl': {\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n return {\n h,\n s: s / 100,\n l: l / 100,\n a: this._color.alpha,\n };\n }\n case 'srgb': {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n if (\n this._colorOrigin &&\n typeof (this._colorOrigin as { r: string }).r ===\n 'string' &&\n (this._colorOrigin as { r: string }).r.search('%')\n ) {\n return {\n r: `${Math.round(r * 255)}%`,\n g: `${Math.round(g * 255)}%`,\n b: `${Math.round(b * 255)}%`,\n a: this._color.alpha,\n };\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: this._color.alpha,\n };\n }\n }\n return this._color;\n }\n\n protected host: ReactiveElement;\n\n /**\n * Gets the hue value of the current color in HSL format.\n *\n * @returns {number} The hue value as a number.\n */\n get hue(): number {\n return Number((this._color.to('hsl') as Color).hsl.h);\n }\n\n /**\n * Sets the hue value of the color and requests an update from the host.\n *\n * @param hue - The hue value to set, represented as a number.\n */\n set hue(hue: number) {\n this._color.set('h', hue);\n this.host.requestUpdate();\n }\n\n /**\n * Creates an instance of ColorController.\n *\n * @param host - The ReactiveElement that this controller is associated with.\n * @param options - An object containing optional parameters.\n * @param options.manageAs - A string to manage the controller as a specific type.\n */\n constructor(\n host: ReactiveElement,\n {\n manageAs,\n }: {\n manageAs?: string;\n } = {}\n ) {\n this.host = host;\n this.manageAs = manageAs;\n }\n\n /**\n * Converts the current color to the specified format.\n *\n * @param format - The desired color format. It can be a string representing one of the valid formats\n * ('srgb', 'hsva', 'hsv', 'hsl', 'hsla') or a ColorSpace object.\n * @returns The color object in the specified format.\n * @throws Will throw an error if the provided format is not a valid string format.\n */\n getColor(format: string | ColorSpace): ColorObject {\n const validFormats = ['srgb', 'hsva', 'hsv', 'hsl', 'hsla'];\n if (typeof format === 'string' && !validFormats.includes(format)) {\n throw new Error('not a valid format');\n }\n\n return this._color.to(format);\n }\n\n /**\n * Converts the current color to an HSL string representation.\n *\n * @returns {string} The HSL string representation of the current color.\n */\n getHslString(): string {\n return this._color.to('hsl').toString();\n }\n\n /**\n * Saves the current color state by cloning the current color and storing it\n * as the previous color. This allows for the ability to revert to the previous\n * color state if needed.\n *\n * @returns {void}\n */\n savePreviousColor(): void {\n this._previousColor = this._color.clone();\n }\n\n /**\n * Restores the color to the previously saved color value.\n *\n * This method sets the current color (`_color`) to the previously stored color (`_previousColor`).\n */\n restorePreviousColor(): void {\n this._color = this._previousColor;\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveElement } from 'lit';\nimport Color from 'colorjs.io';\nimport type {\n ColorObject,\n ColorTypes as DefaultColorTypes,\n} from 'colorjs.io/types/src/color';\nimport type ColorSpace from 'colorjs.io/types/src/space';\n\n/**\n * Represents various color types that can be used in the application.\n *\n * This type can be one of the following:\n * - `DefaultColorTypes`: A predefined set of color types.\n * - An object representing an RGBA color with properties:\n * - `r`: Red component, can be a number or string.\n * - `g`: Green component, can be a number or string.\n * - `b`: Blue component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSLA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `l`: Lightness component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n * - An object representing an HSVA color with properties:\n * - `h`: Hue component, can be a number or string.\n * - `s`: Saturation component, can be a number or string.\n * - `v`: Value component, can be a number or string.\n * - `a` (optional): Alpha component, can be a number or string.\n */\ntype ColorTypes =\n | DefaultColorTypes\n | {\n r: number | string;\n g: number | string;\n b: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n l: number | string;\n a?: number | string;\n }\n | {\n h: number | string;\n s: number | string;\n v: number | string;\n a?: number | string;\n };\n\nexport type { Color, ColorTypes };\n\ntype ColorValidationResult = {\n spaceId: string | null;\n coords: number[];\n isValid: boolean;\n alpha: number;\n};\n\n/**\n * The `ColorController` class is responsible for managing and validating color values\n * in various color spaces (RGB, HSL, HSV, Hex). It provides methods to set, get, and\n * validate colors, as well as convert between different color formats.\n *\n * @class\n * @property {Color} color - Gets or sets the current color value.\n * @property {ColorTypes} colorValue - Gets the color value in various formats based on the original color input.\n * @property {number} hue - Gets or sets the hue value of the current color.\n *\n * @method validateColorString(color: string): ColorValidationResult - Validates a color string and returns the validation result.\n * @method getColor(format: string | ColorSpace): ColorObject - Converts the current color to the specified format.\n * @method getHslString(): string - Returns the current color in HSL string format.\n * @method savePreviousColor(): void - Saves the current color as the previous color.\n * @method restorePreviousColor(): void - Restores the previous color.\n *\n * @constructor\n * @param {ReactiveElement} host - The host element that uses this controller.\n * @param {Object} [options] - Optional configuration options.\n * @param {string} [options.manageAs] - Specifies the color space to manage the color as.\n */\n\nexport class ColorController {\n get color(): Color {\n return this._color;\n }\n\n /**\n * Validates a color string and returns a result indicating the color space,\n * coordinates, alpha value, and whether the color is valid.\n *\n * @param color - The color string to validate. Supported formats include:\n * - RGB: `rgb(r, g, b)`, `rgba(r, g, b, a)`, `rgb r g b`, `rgba r g b a`\n * - HSL: `hsl(h, s, l)`, `hsla(h, s, l, a)`, `hsl h s l`, `hsla h s l a`\n * - HSV: `hsv(h, s, v)`, `hsva(h, s, v, a)`, `hsv h s v`, `hsva h s v a`\n * - HEX: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`\n *\n * @returns An object containing the following properties:\n * - `spaceId`: The color space identifier (`'srgb'`, `'hsl'`, or `'hsv'`).\n * - `coords`: An array of numeric values representing the color coordinates.\n * - `alpha`: The alpha value of the color (0 to 1).\n * - `isValid`: A boolean indicating whether the color string is valid.\n */\n public validateColorString(color: string): ColorValidationResult {\n const result: ColorValidationResult = {\n spaceId: null,\n coords: [0, 0, 0],\n isValid: false,\n alpha: 1,\n };\n\n // RGB color formats\n const rgbRegExpArray = [\n // With commas\n /rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r, g, b, a)\n /rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)/i, // rgb(r, g, b)\n\n // With spaces\n /^rgba\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(0|0?\\.\\d+|1)\\s*$/i, // rgba r g b a\n /^rgb\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*$/i, // rgb r g b\n\n // Spaces inside parentheses\n /^rgba\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // rgba(r g b a)\n /^rgb\\(\\s*(\\d{1,3})\\s+(\\d{1,3})\\s+(\\d{1,3})\\s*\\)$/i, // rgb(r g b)\n\n // Percentage values\n /rgb\\(\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*,\\s*(100|[0-9]{1,2}%)\\s*\\)/i, // rgb(r%, g%, b%)\n /rgba\\(\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(100|[0-9]{1,2})%\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // rgba(r%, g%, b%, a)\n ];\n\n // HSL color formats\n const hslRegExpArray = [\n // With commas\n /hsla\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsla(h, s, l, a)\n /hsl\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsl(h, s, l)\n\n // With spaces\n /^hsla\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsla h s l a\n /^hsl\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsl h s l\n\n // Spaces inside parentheses\n /^hsla\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsla(h s l a)\n /^hsl\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsl(h s l)\n ];\n\n // HSV color formats\n const hsvRegExpArray = [\n // With commas\n /hsva\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d*\\.?\\d+)\\s*\\)/i, // hsva(h, s, v, a)\n /hsv\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}%?)\\s*,\\s*(\\d{1,3}%?)\\s*\\)/i, // hsv(h, s, v)\n\n // With spaces\n /^hsva\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*$/i, // hsva h s v a\n /^hsv\\s+(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*$/i, // hsv h s v\n\n // Spaces inside parentheses\n /^hsva\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s+(\\d*\\.?\\d+)\\s*\\)$/i, // hsva(h s v a)\n /^hsv\\(\\s*(\\d{1,3})\\s+(\\d{1,3}%?)\\s+(\\d{1,3}%?)\\s*\\)$/i, // hsv(h s v)\n ];\n\n // HEX color formats\n const hexRegExpArray = [\n /^#([A-Fa-f0-9]{6})([A-Fa-f0-9]{2})?$/, // 6-digit hex with optional hex alpha\n /^#([A-Fa-f0-9]{3})([A-Fa-f0-9]{1})?$/, // 3-digit hex with optional hex alpha\n ];\n\n const rgbaMatch = rgbRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hslaMatch = hslRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hsvaMatch = hsvRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n const hexMatch = hexRegExpArray\n .find((regex) => regex.test(color))\n ?.exec(color);\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch.filter(\n (element) => typeof element === 'string'\n );\n const alpha = a === undefined ? 1 : Number(a);\n const processValue = (value: string): number => {\n if (value.includes('%')) {\n return Number(value.replace('%', '')) / 100;\n } else {\n return Number(value) / 255;\n }\n };\n const numericR = processValue(r);\n const numericG = processValue(g);\n const numericB = processValue(b);\n\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = alpha;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n alpha >= 0 &&\n alpha <= 1;\n } else if (hslaMatch) {\n const [, h, s, l, a] = hslaMatch;\n const values = [h, s, l, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericL, numericA] = values;\n\n result.spaceId = 'hsl';\n result.coords = [numericH, numericS, numericL];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericL >= 0 &&\n numericL <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hsvaMatch) {\n const [, h, s, v, a] = hsvaMatch;\n const values = [h, s, v, a === undefined ? '1' : a].map((value) =>\n Number(value.replace(/[^\\d.]/g, ''))\n );\n const [numericH, numericS, numericV, numericA] = values;\n\n result.spaceId = 'hsv';\n result.coords = [numericH, numericS, numericV];\n result.alpha = numericA;\n result.isValid =\n numericH >= 0 &&\n numericH <= 360 &&\n numericS >= 0 &&\n numericS <= 100 &&\n numericV >= 0 &&\n numericV <= 100 &&\n numericA >= 0 &&\n numericA <= 1;\n } else if (hexMatch) {\n const [, hex, alphaHex] = hexMatch;\n\n // Function to process 2-digit or repeated 1-digit hex\n const processHex = (hex: string): number => {\n // For 3-digit hex values, repeat each digit\n if (hex.length === 1) {\n hex = hex + hex;\n }\n return parseInt(hex, 16) / 255;\n };\n\n // Handle both 3-digit and 6-digit hex\n let numericR, numericG, numericB;\n if (hex.length === 3) {\n // 3-digit hex (e.g., #3a7 -> #33aa77)\n numericR = processHex(hex.substring(0, 1));\n numericG = processHex(hex.substring(1, 2));\n numericB = processHex(hex.substring(2, 3));\n } else {\n // 6-digit hex (e.g., #33aa77)\n numericR = processHex(hex.substring(0, 2));\n numericG = processHex(hex.substring(2, 4));\n numericB = processHex(hex.substring(4, 6));\n }\n\n // Process hex alpha if provided (convert from 0-255 to 0-1)\n const numericA = alphaHex ? processHex(alphaHex) : 1;\n\n // Validate the color values\n result.spaceId = 'srgb';\n result.coords = [numericR, numericG, numericB];\n result.alpha = numericA;\n result.isValid =\n numericR >= 0 &&\n numericR <= 1 &&\n numericG >= 0 &&\n numericG <= 1 &&\n numericB >= 0 &&\n numericB <= 1 &&\n numericA >= 0 &&\n numericA <= 1;\n }\n\n return result;\n }\n\n /**\n * Represents the color state of the component.\n * Initialized with an HSV color model with hue 0, saturation 100, and value 100, and an alpha value of 1.\n *\n * @private\n * @type {Color}\n */\n private _color: Color = new Color('hsv', [0, 100, 100], 1);\n\n /**\n * Represents the original color value provided by the user.\n *\n * @private\n * @type {ColorTypes}\n */\n private _colorOrigin!: ColorTypes;\n\n /**\n * Gets the original color value provided by the user.\n *\n * @returns {ColorTypes} The original color value.\n */\n get colorOrigin(): ColorTypes {\n return this._colorOrigin;\n }\n\n /**\n * Sets the original color value provided by the user.\n *\n * @param {ColorTypes} colorOrigin - The original color value to set.\n */\n set colorOrigin(colorOrigin: ColorTypes) {\n this._colorOrigin = colorOrigin;\n }\n\n /**\n * An optional string property that specifies how the color should be managed(its value is the name of color space in which color object will be managed).\n * This property can be used to define a specific management strategy or identifier.\n */\n private manageAs?: string;\n\n /**\n * Stores the previous color value.\n * This is used to keep track of the color before any changes are made.\n *\n * @private\n */\n private _previousColor!: Color;\n\n /**\n * Private helper method to convert RGB color to hex format with optional alpha\n *\n * @private\n * @param {boolean} includeHash - Whether to include the # prefix in the returned string\n * @param {boolean} includeAlpha - Whether to include the alpha channel in the returned string\n * @returns {string} The color in hex format\n */\n private _getHexString(includeHash: boolean, includeAlpha: boolean): string {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const a = this._color.alpha;\n\n const rHex = Math.round(r * 255)\n .toString(16)\n .padStart(2, '0');\n const gHex = Math.round(g * 255)\n .toString(16)\n .padStart(2, '0');\n const bHex = Math.round(b * 255)\n .toString(16)\n .padStart(2, '0');\n const aHex = Math.round(a * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `${includeHash ? '#' : ''}${rHex}${gHex}${bHex}${includeAlpha ? aHex : ''}`;\n }\n\n /**\n * Sets the color value for the controller. The color can be provided in various formats:\n * - A string representing a color name, hex code, or other color format.\n * - An instance of the `Color` class.\n * - An object containing color properties such as `h`, `s`, `l`, `v`, `r`, `g`, `b`, and optionally `a`.\n *\n * The method validates and parses the input color, converting it to a `Color` instance.\n * If the color is invalid, it attempts to parse it as a hex code or returns without setting a new color.\n *\n * @param {ColorTypes} color - The color value to set. It can be a string, an instance of `Color`, or an object with color properties.\n */\n set color(color: ColorTypes) {\n this._colorOrigin = color;\n let newColor!: Color;\n if (typeof color === 'string') {\n const colorValidationResult = this.validateColorString(\n color as string\n );\n if (colorValidationResult.isValid) {\n const [coord1, coord2, coord3] = colorValidationResult.coords;\n newColor = new Color(\n `${colorValidationResult.spaceId}`,\n [coord1, coord2, coord3],\n colorValidationResult.alpha\n );\n } else {\n try {\n Color.parse(color);\n } catch (error) {\n try {\n newColor = new Color(`#${color}`);\n } catch (error) {\n return;\n }\n }\n }\n } else if (color instanceof Color) {\n newColor = color;\n } else if (!Array.isArray(color)) {\n const { h, s, l, v, r, g, b, a } = color as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n a?: string;\n };\n if (typeof h !== 'undefined' && typeof s !== 'undefined') {\n const lv = l ?? v;\n newColor = new Color(\n typeof l !== 'undefined' ? 'hsl' : 'hsv',\n [\n parseFloat(h),\n typeof s !== 'string' ? s * 100 : parseFloat(s),\n typeof lv !== 'string' ? lv * 100 : parseFloat(lv),\n ],\n parseFloat(a || '1')\n );\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n newColor = new Color(\n 'srgb',\n [\n parseFloat(r) / 255,\n parseFloat(g) / 255,\n parseFloat(b) / 255,\n ],\n parseFloat(a || '1')\n );\n }\n }\n\n if (!newColor) {\n newColor = new Color(color as DefaultColorTypes);\n }\n\n if (this.manageAs) {\n this._color = newColor.to(this.manageAs) as Color;\n } else {\n this._color = newColor;\n }\n this.host.requestUpdate();\n }\n\n /**\n * Gets the color value in various formats based on the original color input.\n *\n * The method determines the color space of the original color input and converts\n * the color to the appropriate format. The supported color spaces are:\n * - HSV (Hue, Saturation, Value)\n * - HSL (Hue, Saturation, Lightness)\n * - Hexadecimal (with or without alpha)\n * - RGB (Red, Green, Blue) with optional alpha\n *\n * @returns {ColorTypes} The color value in the appropriate format.\n *\n * The method handles the following cases:\n * - If the original color input is a string, it checks the prefix to determine the color space.\n * - If the original color input is an object, it checks the properties to determine the color space.\n * - If the original color input is not provided, it defaults to the current color space of the color object.\n *\n * The returned color value can be in one of the following formats:\n * - `hsv(h, s%, v%)` or `hsva(h, s%, v%, a)`\n * - `hsl(h, s%, l%)` or `hsla(h, s%, l%, a)`\n * - `#rrggbb` or `#rrggbbaa`\n * - `rgb(r, g, b)` or `rgba(r, g, b, a)`\n * - `{ h, s, v, a }` for HSV object\n * - `{ h, s, l, a }` for HSL object\n * - `{ r, g, b, a }` for RGB object\n */\n get colorValue(): ColorTypes {\n if (typeof this._colorOrigin === 'string') {\n let spaceId = '';\n if (this._colorOrigin.startsWith('#')) {\n spaceId = 'hex string';\n } else if (this._colorOrigin.startsWith('rgb')) {\n spaceId = 'rgb';\n } else if (this._colorOrigin.startsWith('hsl')) {\n spaceId = 'hsl';\n } else if (this._colorOrigin.startsWith('hsv')) {\n spaceId = 'hsv';\n } else {\n spaceId = 'hex';\n }\n switch (spaceId) {\n case 'hsv': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n const a = this._color.alpha;\n return `hsv${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(v)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hsl': {\n const hadAlpha = this._colorOrigin[3] === 'a';\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n const a = this._color.alpha;\n return `hsl${hadAlpha ? `a` : ''}(${Math.round(\n h\n )}, ${Math.round(s)}%, ${Math.round(l)}%${\n hadAlpha ? `, ${a}` : ''\n })`;\n }\n case 'hex string': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 9 || // #RRGGBBAA format\n this._colorOrigin.length === 5; // #RGBA format\n return this._getHexString(true, hadAlpha);\n }\n case 'hex': {\n // Check if the original input included alpha\n const hadAlpha =\n this._colorOrigin.length === 8 || // RRGGBBAA format (no #)\n this._colorOrigin.length === 4; // RGBA format (no #)\n return this._getHexString(false, hadAlpha);\n }\n //rgb\n default: {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n const hadAlpha = this._colorOrigin[3] === 'a';\n const a = this._color.alpha;\n if (this._colorOrigin.search('%') > -1) {\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 100)}%, ${Math.round(\n g * 100\n )}%, ${Math.round(b * 100)}%${hadAlpha ? `,${Math.round(a * 100)}%` : ''})`;\n }\n return `rgb${hadAlpha ? `a` : ''}(${Math.round(r * 255)}, ${Math.round(\n g * 255\n )}, ${Math.round(b * 255)}${hadAlpha ? `, ${a}` : ''})`;\n }\n }\n }\n let spaceId;\n if (this._colorOrigin) {\n try {\n ({ spaceId } = new Color(\n this._colorOrigin as DefaultColorTypes\n ));\n } catch (error) {\n const { h, s, l, v, r, g, b } = this._colorOrigin as {\n h: string;\n s: string;\n l: string;\n v: string;\n r: string;\n g: string;\n b: string;\n };\n if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof l !== 'undefined'\n ) {\n spaceId = 'hsl';\n } else if (\n typeof h !== 'undefined' &&\n typeof s !== 'undefined' &&\n typeof v !== 'undefined'\n ) {\n spaceId = 'hsv';\n } else if (\n typeof r !== 'undefined' &&\n typeof g !== 'undefined' &&\n typeof b !== 'undefined'\n ) {\n spaceId = 'srgb';\n }\n }\n } else {\n ({ spaceId } = this.color);\n }\n switch (spaceId) {\n case 'hsv': {\n const { h, s, v } = (this._color.to('hsv') as Color).hsv;\n return {\n h,\n s: s / 100,\n v: v / 100,\n a: this._color.alpha,\n };\n }\n case 'hsl': {\n const { h, s, l } = (this._color.to('hsl') as Color).hsl;\n return {\n h,\n s: s / 100,\n l: l / 100,\n a: this._color.alpha,\n };\n }\n case 'srgb': {\n const { r, g, b } = (this._color.to('srgb') as Color).srgb;\n if (\n this._colorOrigin &&\n typeof (this._colorOrigin as { r: string }).r ===\n 'string' &&\n (this._colorOrigin as { r: string }).r.search('%')\n ) {\n return {\n r: `${Math.round(r * 255)}%`,\n g: `${Math.round(g * 255)}%`,\n b: `${Math.round(b * 255)}%`,\n a: this._color.alpha,\n };\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: this._color.alpha,\n };\n }\n }\n return this._color;\n }\n\n protected host: ReactiveElement;\n\n /**\n * Gets the hue value of the current color in HSL format.\n *\n * @returns {number} The hue value as a number.\n */\n get hue(): number {\n return Number((this._color.to('hsl') as Color).hsl.h);\n }\n\n /**\n * Sets the hue value of the color and requests an update from the host.\n *\n * @param hue - The hue value to set, represented as a number.\n */\n set hue(hue: number) {\n this._color.set('h', hue);\n this.host.requestUpdate();\n }\n\n /**\n * Creates an instance of ColorController.\n *\n * @param host - The ReactiveElement that this controller is associated with.\n * @param options - An object containing optional parameters.\n * @param options.manageAs - A string to manage the controller as a specific type.\n */\n constructor(\n host: ReactiveElement,\n {\n manageAs,\n }: {\n manageAs?: string;\n } = {}\n ) {\n this.host = host;\n this.manageAs = manageAs;\n }\n\n /**\n * Converts the current color to the specified format.\n *\n * @param format - The desired color format. It can be a string representing one of the valid formats\n * ('srgb', 'hsva', 'hsv', 'hsl', 'hsla') or a ColorSpace object.\n * @returns The color object in the specified format.\n * @throws Will throw an error if the provided format is not a valid string format.\n */\n getColor(format: string | ColorSpace): ColorObject {\n const validFormats = ['srgb', 'hsva', 'hsv', 'hsl', 'hsla'];\n if (typeof format === 'string' && !validFormats.includes(format)) {\n throw new Error('not a valid format');\n }\n\n return this._color.to(format);\n }\n\n /**\n * Converts the current color to an HSL string representation.\n *\n * @returns {string} The HSL string representation of the current color.\n */\n getHslString(): string {\n return this._color.to('hsl').toString();\n }\n\n /**\n * Saves the current color state by cloning the current color and storing it\n * as the previous color. This allows for the ability to revert to the previous\n * color state if needed.\n *\n * @returns {void}\n */\n savePreviousColor(): void {\n this._previousColor = this._color.clone();\n }\n\n /**\n * Restores the color to the previously saved color value.\n *\n * This method sets the current color (`_color`) to the previously stored color (`_previousColor`).\n */\n restorePreviousColor(): void {\n this._color = this._previousColor;\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["Color", "host", "manageAs", "color", "_a", "_b", "_c", "_d", "result", "rgbRegExpArray", "hslRegExpArray", "hsvRegExpArray", "hexRegExpArray", "rgbaMatch", "regex", "hslaMatch", "hsvaMatch", "hexMatch", "r", "g", "b", "a", "element", "alpha", "processValue", "value", "numericR", "numericG", "numericB", "h", "s", "l", "values", "numericH", "numericS", "numericL", "numericA", "v", "numericV", "hex", "alphaHex", "processHex", "colorOrigin", "includeHash", "includeAlpha", "rHex", "gHex", "bHex", "aHex", "newColor", "colorValidationResult", "coord1", "coord2", "coord3", "error", "lv", "spaceId", "hadAlpha", "hue", "format"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveElement } from 'lit';
2
13
  export declare const dependencyManagerLoadedSymbol: unique symbol;
3
14
  /**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["DependencyManger.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveElement } from 'lit';\nexport const dependencyManagerLoadedSymbol = Symbol(\n 'dependency manager loaded'\n);\n\n/**\n * Manage the availability of custom element dependencies of a host element\n * to gate render and functional behavior before and after their presence\n */\nexport class DependencyManagerController {\n private dependencies: Record<string, boolean> = {};\n\n private host!: ReactiveElement;\n\n /**\n * Whether all of the provided dependencies have been registered.\n * This will be `false` when no dependencies have been listed for management.\n * Changes to this value will trigger `requestUpdate()` on the host.\n */\n public get loaded(): boolean {\n return this._loaded;\n }\n\n private set loaded(loaded: boolean) {\n if (loaded === this.loaded) return;\n this._loaded = loaded;\n this.host.requestUpdate(dependencyManagerLoadedSymbol, !this.loaded);\n }\n\n private _loaded = false;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n }\n\n /**\n * Submit a custom element tag name to be managed as a dependency.\n *\n * @param dependency {string} - the custom element tag to manage\n * @param alreadyLoaded {boolean} - force the managemented custom element to be listed as loaded\n */\n public add(dependency: string, alreadyLoaded?: boolean): void {\n const loaded =\n !!alreadyLoaded ||\n !!customElements.get(dependency) ||\n this.dependencies[dependency];\n if (!loaded) {\n customElements.whenDefined(dependency).then(() => {\n this.add(dependency, true);\n });\n }\n this.dependencies = {\n ...this.dependencies,\n [dependency]: loaded,\n };\n // Update the loaded property based on the new loaded state of all dependencies\n this.loaded = Object.values(this.dependencies).every(\n (loaded) => loaded\n );\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveElement } from 'lit';\nexport const dependencyManagerLoadedSymbol = Symbol(\n 'dependency manager loaded'\n);\n\n/**\n * Manage the availability of custom element dependencies of a host element\n * to gate render and functional behavior before and after their presence\n */\nexport class DependencyManagerController {\n private dependencies: Record<string, boolean> = {};\n\n private host!: ReactiveElement;\n\n /**\n * Whether all of the provided dependencies have been registered.\n * This will be `false` when no dependencies have been listed for management.\n * Changes to this value will trigger `requestUpdate()` on the host.\n */\n public get loaded(): boolean {\n return this._loaded;\n }\n\n private set loaded(loaded: boolean) {\n if (loaded === this.loaded) return;\n this._loaded = loaded;\n this.host.requestUpdate(dependencyManagerLoadedSymbol, !this.loaded);\n }\n\n private _loaded = false;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n }\n\n /**\n * Submit a custom element tag name to be managed as a dependency.\n *\n * @param dependency {string} - the custom element tag to manage\n * @param alreadyLoaded {boolean} - force the managemented custom element to be listed as loaded\n */\n public add(dependency: string, alreadyLoaded?: boolean): void {\n const loaded =\n !!alreadyLoaded ||\n !!customElements.get(dependency) ||\n this.dependencies[dependency];\n if (!loaded) {\n customElements.whenDefined(dependency).then(() => {\n this.add(dependency, true);\n });\n }\n this.dependencies = {\n ...this.dependencies,\n [dependency]: loaded,\n };\n // Update the loaded property based on the new loaded state of all dependencies\n this.loaded = Object.values(this.dependencies).every(\n (loaded) => loaded\n );\n }\n}\n"],
5
5
  "mappings": ";AAaO,aAAM,gCAAgC;AAAA,EACzC;AACJ;AAMO,aAAM,4BAA4B;AAAA,EAsBrC,YAAY,MAAuB;AArBnC,SAAQ,eAAwC,CAAC;AAmBjD,SAAQ,UAAU;AAGd,SAAK,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAdA,IAAW,SAAkB;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAY,OAAO,QAAiB;AAChC,QAAI,WAAW,KAAK,OAAQ;AAC5B,SAAK,UAAU;AACf,SAAK,KAAK,cAAc,+BAA+B,CAAC,KAAK,MAAM;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,IAAI,YAAoB,eAA+B;AAC1D,UAAM,SACF,CAAC,CAAC,iBACF,CAAC,CAAC,eAAe,IAAI,UAAU,KAC/B,KAAK,aAAa,UAAU;AAChC,QAAI,CAAC,QAAQ;AACT,qBAAe,YAAY,UAAU,EAAE,KAAK,MAAM;AAC9C,aAAK,IAAI,YAAY,IAAI;AAAA,MAC7B,CAAC;AAAA,IACL;AACA,SAAK,eAAe;AAAA,MAChB,GAAG,KAAK;AAAA,MACR,CAAC,UAAU,GAAG;AAAA,IAClB;AAEA,SAAK,SAAS,OAAO,OAAO,KAAK,YAAY,EAAE;AAAA,MAC3C,CAACA,YAAWA;AAAA,IAChB;AAAA,EACJ;AACJ;",
6
6
  "names": ["loaded"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["DependencyManger.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveElement } from 'lit';\nexport const dependencyManagerLoadedSymbol = Symbol(\n 'dependency manager loaded'\n);\n\n/**\n * Manage the availability of custom element dependencies of a host element\n * to gate render and functional behavior before and after their presence\n */\nexport class DependencyManagerController {\n private dependencies: Record<string, boolean> = {};\n\n private host!: ReactiveElement;\n\n /**\n * Whether all of the provided dependencies have been registered.\n * This will be `false` when no dependencies have been listed for management.\n * Changes to this value will trigger `requestUpdate()` on the host.\n */\n public get loaded(): boolean {\n return this._loaded;\n }\n\n private set loaded(loaded: boolean) {\n if (loaded === this.loaded) return;\n this._loaded = loaded;\n this.host.requestUpdate(dependencyManagerLoadedSymbol, !this.loaded);\n }\n\n private _loaded = false;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n }\n\n /**\n * Submit a custom element tag name to be managed as a dependency.\n *\n * @param dependency {string} - the custom element tag to manage\n * @param alreadyLoaded {boolean} - force the managemented custom element to be listed as loaded\n */\n public add(dependency: string, alreadyLoaded?: boolean): void {\n const loaded =\n !!alreadyLoaded ||\n !!customElements.get(dependency) ||\n this.dependencies[dependency];\n if (!loaded) {\n customElements.whenDefined(dependency).then(() => {\n this.add(dependency, true);\n });\n }\n this.dependencies = {\n ...this.dependencies,\n [dependency]: loaded,\n };\n // Update the loaded property based on the new loaded state of all dependencies\n this.loaded = Object.values(this.dependencies).every(\n (loaded) => loaded\n );\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveElement } from 'lit';\nexport const dependencyManagerLoadedSymbol = Symbol(\n 'dependency manager loaded'\n);\n\n/**\n * Manage the availability of custom element dependencies of a host element\n * to gate render and functional behavior before and after their presence\n */\nexport class DependencyManagerController {\n private dependencies: Record<string, boolean> = {};\n\n private host!: ReactiveElement;\n\n /**\n * Whether all of the provided dependencies have been registered.\n * This will be `false` when no dependencies have been listed for management.\n * Changes to this value will trigger `requestUpdate()` on the host.\n */\n public get loaded(): boolean {\n return this._loaded;\n }\n\n private set loaded(loaded: boolean) {\n if (loaded === this.loaded) return;\n this._loaded = loaded;\n this.host.requestUpdate(dependencyManagerLoadedSymbol, !this.loaded);\n }\n\n private _loaded = false;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n }\n\n /**\n * Submit a custom element tag name to be managed as a dependency.\n *\n * @param dependency {string} - the custom element tag to manage\n * @param alreadyLoaded {boolean} - force the managemented custom element to be listed as loaded\n */\n public add(dependency: string, alreadyLoaded?: boolean): void {\n const loaded =\n !!alreadyLoaded ||\n !!customElements.get(dependency) ||\n this.dependencies[dependency];\n if (!loaded) {\n customElements.whenDefined(dependency).then(() => {\n this.add(dependency, true);\n });\n }\n this.dependencies = {\n ...this.dependencies,\n [dependency]: loaded,\n };\n // Update the loaded property based on the new loaded state of all dependencies\n this.loaded = Object.values(this.dependencies).every(\n (loaded) => loaded\n );\n }\n}\n"],
5
5
  "mappings": "aAaO,aAAM,8BAAgC,OACzC,2BACJ,EAMO,aAAM,2BAA4B,CAsBrC,YAAYA,EAAuB,CArBnC,KAAQ,aAAwC,CAAC,EAmBjD,KAAQ,QAAU,GAGd,KAAK,KAAOA,CAChB,CAdA,IAAW,QAAkB,CACzB,OAAO,KAAK,OAChB,CAEA,IAAY,OAAOC,EAAiB,CAC5BA,IAAW,KAAK,SACpB,KAAK,QAAUA,EACf,KAAK,KAAK,cAAc,8BAA+B,CAAC,KAAK,MAAM,EACvE,CAcO,IAAIC,EAAoBC,EAA+B,CAC1D,MAAMF,EACF,CAAC,CAACE,GACF,CAAC,CAAC,eAAe,IAAID,CAAU,GAC/B,KAAK,aAAaA,CAAU,EAC3BD,GACD,eAAe,YAAYC,CAAU,EAAE,KAAK,IAAM,CAC9C,KAAK,IAAIA,EAAY,EAAI,CAC7B,CAAC,EAEL,KAAK,aAAe,CAChB,GAAG,KAAK,aACR,CAACA,CAAU,EAAGD,CAClB,EAEA,KAAK,OAAS,OAAO,OAAO,KAAK,YAAY,EAAE,MAC1CA,GAAWA,CAChB,CACJ,CACJ",
6
6
  "names": ["host", "loaded", "dependency", "alreadyLoaded"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveController, ReactiveElement } from 'lit';
2
13
  export declare const elementResolverUpdatedSymbol: unique symbol;
3
14
  export declare class ElementResolutionController implements ReactiveController {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["ElementResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nexport const elementResolverUpdatedSymbol = Symbol('element resolver updated');\n\nexport class ElementResolutionController implements ReactiveController {\n get element(): HTMLElement | null {\n return this._element;\n }\n\n set element(element: HTMLElement | null) {\n if (element === this.element) return;\n const previous = this.element;\n this._element = element;\n // requestUpdate leveraging the exported Symbol() so that the\n // changes can be easily tracked in the host element.\n this.host.requestUpdate(elementResolverUpdatedSymbol, previous);\n }\n\n private _element: HTMLElement | null = null;\n\n private host!: ReactiveElement;\n\n private observer!: MutationObserver;\n\n get selector(): string {\n return this._selector;\n }\n\n set selector(selector: string) {\n if (selector === this.selector) return;\n this.releaseElement();\n this._selector = selector;\n this.resolveElement();\n }\n\n private _selector = '';\n\n get selectorAsId(): string {\n return this.selector.slice(1);\n }\n\n get selectorIsId(): boolean {\n return !!this.selector && this.selector.startsWith('#');\n }\n\n constructor(\n host: ReactiveElement,\n { selector }: { selector: string } = { selector: '' }\n ) {\n this.host = host;\n this.selector = selector;\n this.observer = new MutationObserver(this.mutationCallback);\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n protected mutationCallback: MutationCallback = (mutationList) => {\n let needsResolution = false;\n mutationList.forEach((mutation) => {\n if (needsResolution) return;\n if (mutation.type === 'childList') {\n const currentElementRemoved =\n this.element &&\n [...mutation.removedNodes].includes(this.element);\n const matchingElementAdded =\n !!this.selector &&\n ([...mutation.addedNodes] as HTMLElement[]).some(\n this.elementIsSelected\n );\n needsResolution =\n needsResolution ||\n currentElementRemoved ||\n matchingElementAdded;\n }\n if (mutation.type === 'attributes') {\n const attributeChangedOnCurrentElement =\n mutation.target === this.element;\n const attributeChangedOnMatchingElement =\n !!this.selector &&\n this.elementIsSelected(mutation.target as HTMLElement);\n needsResolution =\n needsResolution ||\n attributeChangedOnCurrentElement ||\n attributeChangedOnMatchingElement;\n }\n });\n if (needsResolution) {\n this.resolveElement();\n }\n };\n\n public hostConnected(): void {\n this.resolveElement();\n this.observer.observe(this.host.getRootNode(), {\n subtree: true,\n childList: true,\n attributes: true,\n });\n }\n\n public hostDisconnected(): void {\n this.releaseElement();\n this.observer.disconnect();\n }\n\n private resolveElement(): void {\n if (!this.selector) {\n this.releaseElement();\n return;\n }\n\n const parent = this.host.getRootNode() as ShadowRoot;\n this.element = this.selectorIsId\n ? (parent.getElementById(this.selectorAsId) as HTMLElement)\n : (parent.querySelector(this.selector) as HTMLElement);\n }\n\n private releaseElement(): void {\n this.element = null;\n }\n\n private elementIsSelected = (el: HTMLElement): boolean => {\n return this.selectorIsId\n ? el?.id === this.selectorAsId\n : el?.matches?.(this.selector);\n };\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nexport const elementResolverUpdatedSymbol = Symbol('element resolver updated');\n\nexport class ElementResolutionController implements ReactiveController {\n get element(): HTMLElement | null {\n return this._element;\n }\n\n set element(element: HTMLElement | null) {\n if (element === this.element) return;\n const previous = this.element;\n this._element = element;\n // requestUpdate leveraging the exported Symbol() so that the\n // changes can be easily tracked in the host element.\n this.host.requestUpdate(elementResolverUpdatedSymbol, previous);\n }\n\n private _element: HTMLElement | null = null;\n\n private host!: ReactiveElement;\n\n private observer!: MutationObserver;\n\n get selector(): string {\n return this._selector;\n }\n\n set selector(selector: string) {\n if (selector === this.selector) return;\n this.releaseElement();\n this._selector = selector;\n this.resolveElement();\n }\n\n private _selector = '';\n\n get selectorAsId(): string {\n return this.selector.slice(1);\n }\n\n get selectorIsId(): boolean {\n return !!this.selector && this.selector.startsWith('#');\n }\n\n constructor(\n host: ReactiveElement,\n { selector }: { selector: string } = { selector: '' }\n ) {\n this.host = host;\n this.selector = selector;\n this.observer = new MutationObserver(this.mutationCallback);\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n protected mutationCallback: MutationCallback = (mutationList) => {\n let needsResolution = false;\n mutationList.forEach((mutation) => {\n if (needsResolution) return;\n if (mutation.type === 'childList') {\n const currentElementRemoved =\n this.element &&\n [...mutation.removedNodes].includes(this.element);\n const matchingElementAdded =\n !!this.selector &&\n ([...mutation.addedNodes] as HTMLElement[]).some(\n this.elementIsSelected\n );\n needsResolution =\n needsResolution ||\n currentElementRemoved ||\n matchingElementAdded;\n }\n if (mutation.type === 'attributes') {\n const attributeChangedOnCurrentElement =\n mutation.target === this.element;\n const attributeChangedOnMatchingElement =\n !!this.selector &&\n this.elementIsSelected(mutation.target as HTMLElement);\n needsResolution =\n needsResolution ||\n attributeChangedOnCurrentElement ||\n attributeChangedOnMatchingElement;\n }\n });\n if (needsResolution) {\n this.resolveElement();\n }\n };\n\n public hostConnected(): void {\n this.resolveElement();\n this.observer.observe(this.host.getRootNode(), {\n subtree: true,\n childList: true,\n attributes: true,\n });\n }\n\n public hostDisconnected(): void {\n this.releaseElement();\n this.observer.disconnect();\n }\n\n private resolveElement(): void {\n if (!this.selector) {\n this.releaseElement();\n return;\n }\n\n const parent = this.host.getRootNode() as ShadowRoot;\n this.element = this.selectorIsId\n ? (parent.getElementById(this.selectorAsId) as HTMLElement)\n : (parent.querySelector(this.selector) as HTMLElement);\n }\n\n private releaseElement(): void {\n this.element = null;\n }\n\n private elementIsSelected = (el: HTMLElement): boolean => {\n return this.selectorIsId\n ? el?.id === this.selectorAsId\n : el?.matches?.(this.selector);\n };\n}\n"],
5
5
  "mappings": ";AAaO,aAAM,+BAA+B,OAAO,0BAA0B;AAEtE,aAAM,4BAA0D;AAAA,EAyCnE,YACI,MACA,EAAE,SAAS,IAA0B,EAAE,UAAU,GAAG,GACtD;AA9BF,SAAQ,WAA+B;AAiBvC,SAAQ,YAAY;AAsBpB,SAAU,mBAAqC,CAAC,iBAAiB;AAC7D,UAAI,kBAAkB;AACtB,mBAAa,QAAQ,CAAC,aAAa;AAC/B,YAAI,gBAAiB;AACrB,YAAI,SAAS,SAAS,aAAa;AAC/B,gBAAM,wBACF,KAAK,WACL,CAAC,GAAG,SAAS,YAAY,EAAE,SAAS,KAAK,OAAO;AACpD,gBAAM,uBACF,CAAC,CAAC,KAAK,YACN,CAAC,GAAG,SAAS,UAAU,EAAoB;AAAA,YACxC,KAAK;AAAA,UACT;AACJ,4BACI,mBACA,yBACA;AAAA,QACR;AACA,YAAI,SAAS,SAAS,cAAc;AAChC,gBAAM,mCACF,SAAS,WAAW,KAAK;AAC7B,gBAAM,oCACF,CAAC,CAAC,KAAK,YACP,KAAK,kBAAkB,SAAS,MAAqB;AACzD,4BACI,mBACA,oCACA;AAAA,QACR;AAAA,MACJ,CAAC;AACD,UAAI,iBAAiB;AACjB,aAAK,eAAe;AAAA,MACxB;AAAA,IACJ;AAgCA,SAAQ,oBAAoB,CAAC,OAA6B;AArI9D;AAsIQ,aAAO,KAAK,gBACN,yBAAI,QAAO,KAAK,gBAChB,8BAAI,YAAJ,4BAAc,KAAK;AAAA,IAC7B;AA7EI,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,WAAW,IAAI,iBAAiB,KAAK,gBAAgB;AAG1D,SAAK,KAAK,cAAc,IAAI;AAAA,EAChC;AAAA,EAlDA,IAAI,UAA8B;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,QAAQ,SAA6B;AACrC,QAAI,YAAY,KAAK,QAAS;AAC9B,UAAM,WAAW,KAAK;AACtB,SAAK,WAAW;AAGhB,SAAK,KAAK,cAAc,8BAA8B,QAAQ;AAAA,EAClE;AAAA,EAQA,IAAI,WAAmB;AACnB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,SAAS,UAAkB;AAC3B,QAAI,aAAa,KAAK,SAAU;AAChC,SAAK,eAAe;AACpB,SAAK,YAAY;AACjB,SAAK,eAAe;AAAA,EACxB;AAAA,EAIA,IAAI,eAAuB;AACvB,WAAO,KAAK,SAAS,MAAM,CAAC;AAAA,EAChC;AAAA,EAEA,IAAI,eAAwB;AACxB,WAAO,CAAC,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,GAAG;AAAA,EAC1D;AAAA,EAiDO,gBAAsB;AACzB,SAAK,eAAe;AACpB,SAAK,SAAS,QAAQ,KAAK,KAAK,YAAY,GAAG;AAAA,MAC3C,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEO,mBAAyB;AAC5B,SAAK,eAAe;AACpB,SAAK,SAAS,WAAW;AAAA,EAC7B;AAAA,EAEQ,iBAAuB;AAC3B,QAAI,CAAC,KAAK,UAAU;AAChB,WAAK,eAAe;AACpB;AAAA,IACJ;AAEA,UAAM,SAAS,KAAK,KAAK,YAAY;AACrC,SAAK,UAAU,KAAK,eACb,OAAO,eAAe,KAAK,YAAY,IACvC,OAAO,cAAc,KAAK,QAAQ;AAAA,EAC7C;AAAA,EAEQ,iBAAuB;AAC3B,SAAK,UAAU;AAAA,EACnB;AAOJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["ElementResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nexport const elementResolverUpdatedSymbol = Symbol('element resolver updated');\n\nexport class ElementResolutionController implements ReactiveController {\n get element(): HTMLElement | null {\n return this._element;\n }\n\n set element(element: HTMLElement | null) {\n if (element === this.element) return;\n const previous = this.element;\n this._element = element;\n // requestUpdate leveraging the exported Symbol() so that the\n // changes can be easily tracked in the host element.\n this.host.requestUpdate(elementResolverUpdatedSymbol, previous);\n }\n\n private _element: HTMLElement | null = null;\n\n private host!: ReactiveElement;\n\n private observer!: MutationObserver;\n\n get selector(): string {\n return this._selector;\n }\n\n set selector(selector: string) {\n if (selector === this.selector) return;\n this.releaseElement();\n this._selector = selector;\n this.resolveElement();\n }\n\n private _selector = '';\n\n get selectorAsId(): string {\n return this.selector.slice(1);\n }\n\n get selectorIsId(): boolean {\n return !!this.selector && this.selector.startsWith('#');\n }\n\n constructor(\n host: ReactiveElement,\n { selector }: { selector: string } = { selector: '' }\n ) {\n this.host = host;\n this.selector = selector;\n this.observer = new MutationObserver(this.mutationCallback);\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n protected mutationCallback: MutationCallback = (mutationList) => {\n let needsResolution = false;\n mutationList.forEach((mutation) => {\n if (needsResolution) return;\n if (mutation.type === 'childList') {\n const currentElementRemoved =\n this.element &&\n [...mutation.removedNodes].includes(this.element);\n const matchingElementAdded =\n !!this.selector &&\n ([...mutation.addedNodes] as HTMLElement[]).some(\n this.elementIsSelected\n );\n needsResolution =\n needsResolution ||\n currentElementRemoved ||\n matchingElementAdded;\n }\n if (mutation.type === 'attributes') {\n const attributeChangedOnCurrentElement =\n mutation.target === this.element;\n const attributeChangedOnMatchingElement =\n !!this.selector &&\n this.elementIsSelected(mutation.target as HTMLElement);\n needsResolution =\n needsResolution ||\n attributeChangedOnCurrentElement ||\n attributeChangedOnMatchingElement;\n }\n });\n if (needsResolution) {\n this.resolveElement();\n }\n };\n\n public hostConnected(): void {\n this.resolveElement();\n this.observer.observe(this.host.getRootNode(), {\n subtree: true,\n childList: true,\n attributes: true,\n });\n }\n\n public hostDisconnected(): void {\n this.releaseElement();\n this.observer.disconnect();\n }\n\n private resolveElement(): void {\n if (!this.selector) {\n this.releaseElement();\n return;\n }\n\n const parent = this.host.getRootNode() as ShadowRoot;\n this.element = this.selectorIsId\n ? (parent.getElementById(this.selectorAsId) as HTMLElement)\n : (parent.querySelector(this.selector) as HTMLElement);\n }\n\n private releaseElement(): void {\n this.element = null;\n }\n\n private elementIsSelected = (el: HTMLElement): boolean => {\n return this.selectorIsId\n ? el?.id === this.selectorAsId\n : el?.matches?.(this.selector);\n };\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nexport const elementResolverUpdatedSymbol = Symbol('element resolver updated');\n\nexport class ElementResolutionController implements ReactiveController {\n get element(): HTMLElement | null {\n return this._element;\n }\n\n set element(element: HTMLElement | null) {\n if (element === this.element) return;\n const previous = this.element;\n this._element = element;\n // requestUpdate leveraging the exported Symbol() so that the\n // changes can be easily tracked in the host element.\n this.host.requestUpdate(elementResolverUpdatedSymbol, previous);\n }\n\n private _element: HTMLElement | null = null;\n\n private host!: ReactiveElement;\n\n private observer!: MutationObserver;\n\n get selector(): string {\n return this._selector;\n }\n\n set selector(selector: string) {\n if (selector === this.selector) return;\n this.releaseElement();\n this._selector = selector;\n this.resolveElement();\n }\n\n private _selector = '';\n\n get selectorAsId(): string {\n return this.selector.slice(1);\n }\n\n get selectorIsId(): boolean {\n return !!this.selector && this.selector.startsWith('#');\n }\n\n constructor(\n host: ReactiveElement,\n { selector }: { selector: string } = { selector: '' }\n ) {\n this.host = host;\n this.selector = selector;\n this.observer = new MutationObserver(this.mutationCallback);\n // Add the controller after the MutationObserver has been created in preparation\n // for the `hostConnected`/`hostDisconnected` callbacks to be run.\n this.host.addController(this);\n }\n\n protected mutationCallback: MutationCallback = (mutationList) => {\n let needsResolution = false;\n mutationList.forEach((mutation) => {\n if (needsResolution) return;\n if (mutation.type === 'childList') {\n const currentElementRemoved =\n this.element &&\n [...mutation.removedNodes].includes(this.element);\n const matchingElementAdded =\n !!this.selector &&\n ([...mutation.addedNodes] as HTMLElement[]).some(\n this.elementIsSelected\n );\n needsResolution =\n needsResolution ||\n currentElementRemoved ||\n matchingElementAdded;\n }\n if (mutation.type === 'attributes') {\n const attributeChangedOnCurrentElement =\n mutation.target === this.element;\n const attributeChangedOnMatchingElement =\n !!this.selector &&\n this.elementIsSelected(mutation.target as HTMLElement);\n needsResolution =\n needsResolution ||\n attributeChangedOnCurrentElement ||\n attributeChangedOnMatchingElement;\n }\n });\n if (needsResolution) {\n this.resolveElement();\n }\n };\n\n public hostConnected(): void {\n this.resolveElement();\n this.observer.observe(this.host.getRootNode(), {\n subtree: true,\n childList: true,\n attributes: true,\n });\n }\n\n public hostDisconnected(): void {\n this.releaseElement();\n this.observer.disconnect();\n }\n\n private resolveElement(): void {\n if (!this.selector) {\n this.releaseElement();\n return;\n }\n\n const parent = this.host.getRootNode() as ShadowRoot;\n this.element = this.selectorIsId\n ? (parent.getElementById(this.selectorAsId) as HTMLElement)\n : (parent.querySelector(this.selector) as HTMLElement);\n }\n\n private releaseElement(): void {\n this.element = null;\n }\n\n private elementIsSelected = (el: HTMLElement): boolean => {\n return this.selectorIsId\n ? el?.id === this.selectorAsId\n : el?.matches?.(this.selector);\n };\n}\n"],
5
5
  "mappings": "aAaO,aAAM,6BAA+B,OAAO,0BAA0B,EAEtE,aAAM,2BAA0D,CAyCnE,YACIA,EACA,CAAE,SAAAC,CAAS,EAA0B,CAAE,SAAU,EAAG,EACtD,CA9BF,KAAQ,SAA+B,KAiBvC,KAAQ,UAAY,GAsBpB,KAAU,iBAAsCC,GAAiB,CAC7D,IAAIC,EAAkB,GACtBD,EAAa,QAASE,GAAa,CAC/B,GAAI,CAAAD,EACJ,IAAIC,EAAS,OAAS,YAAa,CAC/B,MAAMC,EACF,KAAK,SACL,CAAC,GAAGD,EAAS,YAAY,EAAE,SAAS,KAAK,OAAO,EAC9CE,EACF,CAAC,CAAC,KAAK,UACN,CAAC,GAAGF,EAAS,UAAU,EAAoB,KACxC,KAAK,iBACT,EACJD,EACIA,GACAE,GACAC,CACR,CACA,GAAIF,EAAS,OAAS,aAAc,CAChC,MAAMG,EACFH,EAAS,SAAW,KAAK,QACvBI,EACF,CAAC,CAAC,KAAK,UACP,KAAK,kBAAkBJ,EAAS,MAAqB,EACzDD,EACIA,GACAI,GACAC,CACR,EACJ,CAAC,EACGL,GACA,KAAK,eAAe,CAE5B,EAgCA,KAAQ,kBAAqBM,GAA6B,CArI9D,IAAAC,EAsIQ,OAAO,KAAK,cACND,GAAA,YAAAA,EAAI,MAAO,KAAK,cAChBC,EAAAD,GAAA,YAAAA,EAAI,UAAJ,YAAAC,EAAA,KAAAD,EAAc,KAAK,SAC7B,EA7EI,KAAK,KAAOT,EACZ,KAAK,SAAWC,EAChB,KAAK,SAAW,IAAI,iBAAiB,KAAK,gBAAgB,EAG1D,KAAK,KAAK,cAAc,IAAI,CAChC,CAlDA,IAAI,SAA8B,CAC9B,OAAO,KAAK,QAChB,CAEA,IAAI,QAAQU,EAA6B,CACrC,GAAIA,IAAY,KAAK,QAAS,OAC9B,MAAMC,EAAW,KAAK,QACtB,KAAK,SAAWD,EAGhB,KAAK,KAAK,cAAc,6BAA8BC,CAAQ,CAClE,CAQA,IAAI,UAAmB,CACnB,OAAO,KAAK,SAChB,CAEA,IAAI,SAASX,EAAkB,CACvBA,IAAa,KAAK,WACtB,KAAK,eAAe,EACpB,KAAK,UAAYA,EACjB,KAAK,eAAe,EACxB,CAIA,IAAI,cAAuB,CACvB,OAAO,KAAK,SAAS,MAAM,CAAC,CAChC,CAEA,IAAI,cAAwB,CACxB,MAAO,CAAC,CAAC,KAAK,UAAY,KAAK,SAAS,WAAW,GAAG,CAC1D,CAiDO,eAAsB,CACzB,KAAK,eAAe,EACpB,KAAK,SAAS,QAAQ,KAAK,KAAK,YAAY,EAAG,CAC3C,QAAS,GACT,UAAW,GACX,WAAY,EAChB,CAAC,CACL,CAEO,kBAAyB,CAC5B,KAAK,eAAe,EACpB,KAAK,SAAS,WAAW,CAC7B,CAEQ,gBAAuB,CAC3B,GAAI,CAAC,KAAK,SAAU,CAChB,KAAK,eAAe,EACpB,MACJ,CAEA,MAAMY,EAAS,KAAK,KAAK,YAAY,EACrC,KAAK,QAAU,KAAK,aACbA,EAAO,eAAe,KAAK,YAAY,EACvCA,EAAO,cAAc,KAAK,QAAQ,CAC7C,CAEQ,gBAAuB,CAC3B,KAAK,QAAU,IACnB,CAOJ",
6
6
  "names": ["host", "selector", "mutationList", "needsResolution", "mutation", "currentElementRemoved", "matchingElementAdded", "attributeChangedOnCurrentElement", "attributeChangedOnMatchingElement", "el", "_a", "element", "previous", "parent"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveController, ReactiveElement } from 'lit';
2
13
  type DirectionTypes = 'horizontal' | 'vertical' | 'both' | 'grid';
3
14
  export type FocusGroupConfig<T> = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["FocusGroup.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\ntype DirectionTypes = 'horizontal' | 'vertical' | 'both' | 'grid';\nexport type FocusGroupConfig<T> = {\n hostDelegatesFocus?: boolean;\n focusInIndex?: (_elements: T[]) => number;\n direction?: DirectionTypes | (() => DirectionTypes);\n elementEnterAction?: (el: T) => void;\n elements: () => T[];\n isFocusableElement?: (el: T) => boolean;\n listenerScope?: HTMLElement | (() => HTMLElement);\n};\n\nfunction ensureMethod<T, RT>(\n value: T | RT | undefined,\n type: string,\n fallback: T\n): T {\n if (typeof value === type) {\n return (() => value) as T;\n } else if (typeof value === 'function') {\n return value as T;\n }\n return fallback;\n}\n\nexport class FocusGroupController<T extends HTMLElement>\n implements ReactiveController\n{\n protected cachedElements?: T[];\n private mutationObserver: MutationObserver;\n\n get currentIndex(): number {\n if (this._currentIndex === -1) {\n this._currentIndex = this.focusInIndex;\n }\n return this._currentIndex - this.offset;\n }\n\n set currentIndex(currentIndex) {\n this._currentIndex = currentIndex + this.offset;\n }\n\n private _currentIndex = -1;\n\n private prevIndex = -1;\n\n get direction(): DirectionTypes {\n return this._direction();\n }\n\n _direction = (): DirectionTypes => 'both';\n\n public directionLength = 5;\n\n public hostDelegatesFocus = false;\n\n elementEnterAction = (_el: T): void => {\n return;\n };\n\n get elements(): T[] {\n if (!this.cachedElements) {\n this.cachedElements = this._elements();\n }\n return this.cachedElements;\n }\n\n private _elements!: () => T[];\n\n protected set focused(focused: boolean) {\n /* c8 ignore next 1 */\n if (focused === this.focused) return;\n this._focused = focused;\n }\n\n protected get focused(): boolean {\n return this._focused;\n }\n\n private _focused = false;\n\n get focusInElement(): T {\n return this.elements[this.focusInIndex];\n }\n\n get focusInIndex(): number {\n return this._focusInIndex(this.elements);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _focusInIndex = (_elements: T[]): number => 0;\n\n host: ReactiveElement;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isFocusableElement = (_el: T): boolean => true;\n\n isEventWithinListenerScope(event: Event): boolean {\n if (this._listenerScope() === this.host) return true;\n return event.composedPath().includes(this._listenerScope());\n }\n\n _listenerScope = (): HTMLElement => this.host;\n\n // When elements are virtualized, the delta between the first element\n // and the first rendered element.\n offset = 0;\n\n recentlyConnected = false;\n\n constructor(\n host: ReactiveElement,\n {\n hostDelegatesFocus,\n direction,\n elementEnterAction,\n elements,\n focusInIndex,\n isFocusableElement,\n listenerScope,\n }: FocusGroupConfig<T> = { elements: () => [] }\n ) {\n this.mutationObserver = new MutationObserver(() => {\n this.handleItemMutation();\n });\n this.hostDelegatesFocus = hostDelegatesFocus || false;\n this.host = host;\n this.host.addController(this);\n this._elements = elements;\n this.isFocusableElement = isFocusableElement || this.isFocusableElement;\n this._direction = ensureMethod<() => DirectionTypes, DirectionTypes>(\n direction,\n 'string',\n this._direction\n );\n this.elementEnterAction = elementEnterAction || this.elementEnterAction;\n this._focusInIndex = ensureMethod<(_elements: T[]) => number, number>(\n focusInIndex,\n 'number',\n this._focusInIndex\n );\n this._listenerScope = ensureMethod<() => HTMLElement, HTMLElement>(\n listenerScope,\n 'object',\n this._listenerScope\n );\n }\n /* In handleItemMutation() method the first if condition is checking if the element is not focused or if the element's children's length is not decreasing then it means no element has been deleted and we must return.\n Then we are checking if the deleted element was the focused one before the deletion if so then we need to proceed else we casn return;\n */\n handleItemMutation(): void {\n if (\n this._currentIndex == -1 ||\n this.elements.length <= this._elements().length\n )\n return;\n const focusedElement = this.elements[this.currentIndex];\n this.clearElementCache();\n if (this.elements.includes(focusedElement)) return;\n const moveToNextElement = this.currentIndex !== this.elements.length;\n const diff = moveToNextElement ? 1 : -1;\n if (moveToNextElement) {\n this.setCurrentIndexCircularly(-1);\n }\n this.setCurrentIndexCircularly(diff);\n this.focus();\n }\n\n update({ elements }: FocusGroupConfig<T> = { elements: () => [] }): void {\n this.unmanage();\n this._elements = elements;\n this.clearElementCache();\n this.manage();\n }\n\n /**\n * resets the focusedItem to initial item\n */\n reset(): void {\n const elements = this.elements;\n if (!elements.length) return;\n this.setCurrentIndexCircularly(this.focusInIndex - this.currentIndex);\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n }\n\n focusOnItem(item?: T, options?: FocusOptions): void {\n const elements = this.elements || [];\n const newIndex: number =\n !item || !this.isFocusableElement(item)\n ? -1\n : elements.indexOf(item);\n if (newIndex > -1) {\n this.currentIndex = newIndex;\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n this.focus(options);\n }\n\n focus(options?: FocusOptions): void {\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n if (\n !this.hostDelegatesFocus ||\n elements[this.prevIndex] !== focusElement\n ) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n focusElement.tabIndex = 0;\n focusElement.focus(options);\n if (this.hostDelegatesFocus && !this.focused) {\n this.hostContainsFocus();\n }\n }\n }\n\n clearElementCache(offset = 0): void {\n this.mutationObserver.disconnect();\n delete this.cachedElements;\n this.offset = offset;\n requestAnimationFrame(() => {\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n });\n }\n\n setCurrentIndexCircularly(diff: number): void {\n const { length } = this.elements;\n let steps = length;\n this.prevIndex = this.currentIndex;\n // start at a possibly not 0 index\n let nextIndex = (length + this.currentIndex + diff) % length;\n while (\n // don't cycle the elements more than once\n steps &&\n this.elements[nextIndex] &&\n !this.isFocusableElement(this.elements[nextIndex])\n ) {\n nextIndex = (length + nextIndex + diff) % length;\n steps -= 1;\n }\n this.currentIndex = nextIndex;\n }\n\n hostContainsFocus(): void {\n this.host.addEventListener('focusout', this.handleFocusout);\n this.host.addEventListener('keydown', this.handleKeydown);\n this.focused = true;\n }\n\n hostNoLongerContainsFocus(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.focused = false;\n }\n\n isRelatedTargetOrContainAnElement(event: FocusEvent): boolean {\n const relatedTarget = event.relatedTarget as null | Element;\n\n const isRelatedTargetAnElement = this.elements.includes(\n relatedTarget as T\n );\n const isRelatedTargetContainedWithinElements = this.elements.some(\n (el) => el.contains(relatedTarget)\n );\n return !(\n isRelatedTargetAnElement || isRelatedTargetContainedWithinElements\n );\n }\n\n handleFocusin = (event: FocusEvent): void => {\n if (!this.isEventWithinListenerScope(event)) return;\n\n const path = event.composedPath() as T[];\n let targetIndex = -1;\n path.find((el) => {\n targetIndex = this.elements.indexOf(el);\n return targetIndex !== -1;\n });\n this.prevIndex = this.currentIndex;\n this.currentIndex = targetIndex > -1 ? targetIndex : this.currentIndex;\n\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostContainsFocus();\n }\n };\n\n /**\n * handleClick - Finds the element that was clicked and sets the tabindex to 0\n * @returns void\n */\n handleClick = (): void => {\n // Manually set the tabindex to 0 for the current element on receiving focus (from keyboard or mouse)\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n };\n\n handleFocusout = (event: FocusEvent): void => {\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostNoLongerContainsFocus();\n }\n };\n\n acceptsEventKey(key: string): boolean {\n if (key === 'End' || key === 'Home') {\n return true;\n }\n switch (this.direction) {\n case 'horizontal':\n return key === 'ArrowLeft' || key === 'ArrowRight';\n case 'vertical':\n return key === 'ArrowUp' || key === 'ArrowDown';\n case 'both':\n case 'grid':\n return key.startsWith('Arrow');\n }\n }\n\n handleKeydown = (event: KeyboardEvent): void => {\n if (!this.acceptsEventKey(event.key) || event.defaultPrevented) {\n return;\n }\n let diff = 0;\n this.prevIndex = this.currentIndex;\n switch (event.key) {\n case 'ArrowRight':\n diff += 1;\n break;\n case 'ArrowDown':\n diff += this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'ArrowLeft':\n diff -= 1;\n break;\n case 'ArrowUp':\n diff -= this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'End':\n this.currentIndex = 0;\n diff -= 1;\n break;\n case 'Home':\n this.currentIndex = this.elements.length - 1;\n diff += 1;\n break;\n }\n event.preventDefault();\n if (this.direction === 'grid' && this.currentIndex + diff < 0) {\n this.currentIndex = 0;\n } else if (\n this.direction === 'grid' &&\n this.currentIndex + diff > this.elements.length - 1\n ) {\n this.currentIndex = this.elements.length - 1;\n } else {\n this.setCurrentIndexCircularly(diff);\n }\n // To allow the `focusInIndex` to be calculated with the \"after\" state of the keyboard interaction\n // do `elementEnterAction` _before_ focusing the next element.\n this.elementEnterAction(this.elements[this.currentIndex]);\n this.focus();\n };\n\n manage(): void {\n this.addEventListeners();\n }\n\n unmanage(): void {\n this.removeEventListeners();\n }\n\n addEventListeners(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.addEventListener('click', this.handleClick);\n }\n\n removeEventListeners(): void {\n this.host.removeEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.host.removeEventListener('click', this.handleClick);\n }\n\n hostConnected(): void {\n this.recentlyConnected = true;\n this.addEventListeners();\n }\n\n hostDisconnected(): void {\n this.mutationObserver.disconnect();\n this.removeEventListeners();\n }\n\n hostUpdated(): void {\n if (this.recentlyConnected) {\n this.recentlyConnected = false;\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n }\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\ntype DirectionTypes = 'horizontal' | 'vertical' | 'both' | 'grid';\nexport type FocusGroupConfig<T> = {\n hostDelegatesFocus?: boolean;\n focusInIndex?: (_elements: T[]) => number;\n direction?: DirectionTypes | (() => DirectionTypes);\n elementEnterAction?: (el: T) => void;\n elements: () => T[];\n isFocusableElement?: (el: T) => boolean;\n listenerScope?: HTMLElement | (() => HTMLElement);\n};\n\nfunction ensureMethod<T, RT>(\n value: T | RT | undefined,\n type: string,\n fallback: T\n): T {\n if (typeof value === type) {\n return (() => value) as T;\n } else if (typeof value === 'function') {\n return value as T;\n }\n return fallback;\n}\n\nexport class FocusGroupController<T extends HTMLElement>\n implements ReactiveController\n{\n protected cachedElements?: T[];\n private mutationObserver: MutationObserver;\n\n get currentIndex(): number {\n if (this._currentIndex === -1) {\n this._currentIndex = this.focusInIndex;\n }\n return this._currentIndex - this.offset;\n }\n\n set currentIndex(currentIndex) {\n this._currentIndex = currentIndex + this.offset;\n }\n\n private _currentIndex = -1;\n\n private prevIndex = -1;\n\n get direction(): DirectionTypes {\n return this._direction();\n }\n\n _direction = (): DirectionTypes => 'both';\n\n public directionLength = 5;\n\n public hostDelegatesFocus = false;\n\n elementEnterAction = (_el: T): void => {\n return;\n };\n\n get elements(): T[] {\n if (!this.cachedElements) {\n this.cachedElements = this._elements();\n }\n return this.cachedElements;\n }\n\n private _elements!: () => T[];\n\n protected set focused(focused: boolean) {\n /* c8 ignore next 1 */\n if (focused === this.focused) return;\n this._focused = focused;\n }\n\n protected get focused(): boolean {\n return this._focused;\n }\n\n private _focused = false;\n\n get focusInElement(): T {\n return this.elements[this.focusInIndex];\n }\n\n get focusInIndex(): number {\n return this._focusInIndex(this.elements);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _focusInIndex = (_elements: T[]): number => 0;\n\n host: ReactiveElement;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isFocusableElement = (_el: T): boolean => true;\n\n isEventWithinListenerScope(event: Event): boolean {\n if (this._listenerScope() === this.host) return true;\n return event.composedPath().includes(this._listenerScope());\n }\n\n _listenerScope = (): HTMLElement => this.host;\n\n // When elements are virtualized, the delta between the first element\n // and the first rendered element.\n offset = 0;\n\n recentlyConnected = false;\n\n constructor(\n host: ReactiveElement,\n {\n hostDelegatesFocus,\n direction,\n elementEnterAction,\n elements,\n focusInIndex,\n isFocusableElement,\n listenerScope,\n }: FocusGroupConfig<T> = { elements: () => [] }\n ) {\n this.mutationObserver = new MutationObserver(() => {\n this.handleItemMutation();\n });\n this.hostDelegatesFocus = hostDelegatesFocus || false;\n this.host = host;\n this.host.addController(this);\n this._elements = elements;\n this.isFocusableElement = isFocusableElement || this.isFocusableElement;\n this._direction = ensureMethod<() => DirectionTypes, DirectionTypes>(\n direction,\n 'string',\n this._direction\n );\n this.elementEnterAction = elementEnterAction || this.elementEnterAction;\n this._focusInIndex = ensureMethod<(_elements: T[]) => number, number>(\n focusInIndex,\n 'number',\n this._focusInIndex\n );\n this._listenerScope = ensureMethod<() => HTMLElement, HTMLElement>(\n listenerScope,\n 'object',\n this._listenerScope\n );\n }\n /* In handleItemMutation() method the first if condition is checking if the element is not focused or if the element's children's length is not decreasing then it means no element has been deleted and we must return.\n Then we are checking if the deleted element was the focused one before the deletion if so then we need to proceed else we casn return;\n */\n handleItemMutation(): void {\n if (\n this._currentIndex == -1 ||\n this.elements.length <= this._elements().length\n )\n return;\n const focusedElement = this.elements[this.currentIndex];\n this.clearElementCache();\n if (this.elements.includes(focusedElement)) return;\n const moveToNextElement = this.currentIndex !== this.elements.length;\n const diff = moveToNextElement ? 1 : -1;\n if (moveToNextElement) {\n this.setCurrentIndexCircularly(-1);\n }\n this.setCurrentIndexCircularly(diff);\n this.focus();\n }\n\n update({ elements }: FocusGroupConfig<T> = { elements: () => [] }): void {\n this.unmanage();\n this._elements = elements;\n this.clearElementCache();\n this.manage();\n }\n\n /**\n * resets the focusedItem to initial item\n */\n reset(): void {\n const elements = this.elements;\n if (!elements.length) return;\n this.setCurrentIndexCircularly(this.focusInIndex - this.currentIndex);\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n }\n\n focusOnItem(item?: T, options?: FocusOptions): void {\n const elements = this.elements || [];\n const newIndex: number =\n !item || !this.isFocusableElement(item)\n ? -1\n : elements.indexOf(item);\n if (newIndex > -1) {\n this.currentIndex = newIndex;\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n this.focus(options);\n }\n\n focus(options?: FocusOptions): void {\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n if (\n !this.hostDelegatesFocus ||\n elements[this.prevIndex] !== focusElement\n ) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n focusElement.tabIndex = 0;\n focusElement.focus(options);\n if (this.hostDelegatesFocus && !this.focused) {\n this.hostContainsFocus();\n }\n }\n }\n\n clearElementCache(offset = 0): void {\n this.mutationObserver.disconnect();\n delete this.cachedElements;\n this.offset = offset;\n requestAnimationFrame(() => {\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n });\n }\n\n setCurrentIndexCircularly(diff: number): void {\n const { length } = this.elements;\n let steps = length;\n this.prevIndex = this.currentIndex;\n // start at a possibly not 0 index\n let nextIndex = (length + this.currentIndex + diff) % length;\n while (\n // don't cycle the elements more than once\n steps &&\n this.elements[nextIndex] &&\n !this.isFocusableElement(this.elements[nextIndex])\n ) {\n nextIndex = (length + nextIndex + diff) % length;\n steps -= 1;\n }\n this.currentIndex = nextIndex;\n }\n\n hostContainsFocus(): void {\n this.host.addEventListener('focusout', this.handleFocusout);\n this.host.addEventListener('keydown', this.handleKeydown);\n this.focused = true;\n }\n\n hostNoLongerContainsFocus(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.focused = false;\n }\n\n isRelatedTargetOrContainAnElement(event: FocusEvent): boolean {\n const relatedTarget = event.relatedTarget as null | Element;\n\n const isRelatedTargetAnElement = this.elements.includes(\n relatedTarget as T\n );\n const isRelatedTargetContainedWithinElements = this.elements.some(\n (el) => el.contains(relatedTarget)\n );\n return !(\n isRelatedTargetAnElement || isRelatedTargetContainedWithinElements\n );\n }\n\n handleFocusin = (event: FocusEvent): void => {\n if (!this.isEventWithinListenerScope(event)) return;\n\n const path = event.composedPath() as T[];\n let targetIndex = -1;\n path.find((el) => {\n targetIndex = this.elements.indexOf(el);\n return targetIndex !== -1;\n });\n this.prevIndex = this.currentIndex;\n this.currentIndex = targetIndex > -1 ? targetIndex : this.currentIndex;\n\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostContainsFocus();\n }\n };\n\n /**\n * handleClick - Finds the element that was clicked and sets the tabindex to 0\n * @returns void\n */\n handleClick = (): void => {\n // Manually set the tabindex to 0 for the current element on receiving focus (from keyboard or mouse)\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n };\n\n handleFocusout = (event: FocusEvent): void => {\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostNoLongerContainsFocus();\n }\n };\n\n acceptsEventKey(key: string): boolean {\n if (key === 'End' || key === 'Home') {\n return true;\n }\n switch (this.direction) {\n case 'horizontal':\n return key === 'ArrowLeft' || key === 'ArrowRight';\n case 'vertical':\n return key === 'ArrowUp' || key === 'ArrowDown';\n case 'both':\n case 'grid':\n return key.startsWith('Arrow');\n }\n }\n\n handleKeydown = (event: KeyboardEvent): void => {\n if (!this.acceptsEventKey(event.key) || event.defaultPrevented) {\n return;\n }\n let diff = 0;\n this.prevIndex = this.currentIndex;\n switch (event.key) {\n case 'ArrowRight':\n diff += 1;\n break;\n case 'ArrowDown':\n diff += this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'ArrowLeft':\n diff -= 1;\n break;\n case 'ArrowUp':\n diff -= this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'End':\n this.currentIndex = 0;\n diff -= 1;\n break;\n case 'Home':\n this.currentIndex = this.elements.length - 1;\n diff += 1;\n break;\n }\n event.preventDefault();\n if (this.direction === 'grid' && this.currentIndex + diff < 0) {\n this.currentIndex = 0;\n } else if (\n this.direction === 'grid' &&\n this.currentIndex + diff > this.elements.length - 1\n ) {\n this.currentIndex = this.elements.length - 1;\n } else {\n this.setCurrentIndexCircularly(diff);\n }\n // To allow the `focusInIndex` to be calculated with the \"after\" state of the keyboard interaction\n // do `elementEnterAction` _before_ focusing the next element.\n this.elementEnterAction(this.elements[this.currentIndex]);\n this.focus();\n };\n\n manage(): void {\n this.addEventListeners();\n }\n\n unmanage(): void {\n this.removeEventListeners();\n }\n\n addEventListeners(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.addEventListener('click', this.handleClick);\n }\n\n removeEventListeners(): void {\n this.host.removeEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.host.removeEventListener('click', this.handleClick);\n }\n\n hostConnected(): void {\n this.recentlyConnected = true;\n this.addEventListeners();\n }\n\n hostDisconnected(): void {\n this.mutationObserver.disconnect();\n this.removeEventListeners();\n }\n\n hostUpdated(): void {\n if (this.recentlyConnected) {\n this.recentlyConnected = false;\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n }\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["FocusGroup.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\ntype DirectionTypes = 'horizontal' | 'vertical' | 'both' | 'grid';\nexport type FocusGroupConfig<T> = {\n hostDelegatesFocus?: boolean;\n focusInIndex?: (_elements: T[]) => number;\n direction?: DirectionTypes | (() => DirectionTypes);\n elementEnterAction?: (el: T) => void;\n elements: () => T[];\n isFocusableElement?: (el: T) => boolean;\n listenerScope?: HTMLElement | (() => HTMLElement);\n};\n\nfunction ensureMethod<T, RT>(\n value: T | RT | undefined,\n type: string,\n fallback: T\n): T {\n if (typeof value === type) {\n return (() => value) as T;\n } else if (typeof value === 'function') {\n return value as T;\n }\n return fallback;\n}\n\nexport class FocusGroupController<T extends HTMLElement>\n implements ReactiveController\n{\n protected cachedElements?: T[];\n private mutationObserver: MutationObserver;\n\n get currentIndex(): number {\n if (this._currentIndex === -1) {\n this._currentIndex = this.focusInIndex;\n }\n return this._currentIndex - this.offset;\n }\n\n set currentIndex(currentIndex) {\n this._currentIndex = currentIndex + this.offset;\n }\n\n private _currentIndex = -1;\n\n private prevIndex = -1;\n\n get direction(): DirectionTypes {\n return this._direction();\n }\n\n _direction = (): DirectionTypes => 'both';\n\n public directionLength = 5;\n\n public hostDelegatesFocus = false;\n\n elementEnterAction = (_el: T): void => {\n return;\n };\n\n get elements(): T[] {\n if (!this.cachedElements) {\n this.cachedElements = this._elements();\n }\n return this.cachedElements;\n }\n\n private _elements!: () => T[];\n\n protected set focused(focused: boolean) {\n /* c8 ignore next 1 */\n if (focused === this.focused) return;\n this._focused = focused;\n }\n\n protected get focused(): boolean {\n return this._focused;\n }\n\n private _focused = false;\n\n get focusInElement(): T {\n return this.elements[this.focusInIndex];\n }\n\n get focusInIndex(): number {\n return this._focusInIndex(this.elements);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _focusInIndex = (_elements: T[]): number => 0;\n\n host: ReactiveElement;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isFocusableElement = (_el: T): boolean => true;\n\n isEventWithinListenerScope(event: Event): boolean {\n if (this._listenerScope() === this.host) return true;\n return event.composedPath().includes(this._listenerScope());\n }\n\n _listenerScope = (): HTMLElement => this.host;\n\n // When elements are virtualized, the delta between the first element\n // and the first rendered element.\n offset = 0;\n\n recentlyConnected = false;\n\n constructor(\n host: ReactiveElement,\n {\n hostDelegatesFocus,\n direction,\n elementEnterAction,\n elements,\n focusInIndex,\n isFocusableElement,\n listenerScope,\n }: FocusGroupConfig<T> = { elements: () => [] }\n ) {\n this.mutationObserver = new MutationObserver(() => {\n this.handleItemMutation();\n });\n this.hostDelegatesFocus = hostDelegatesFocus || false;\n this.host = host;\n this.host.addController(this);\n this._elements = elements;\n this.isFocusableElement = isFocusableElement || this.isFocusableElement;\n this._direction = ensureMethod<() => DirectionTypes, DirectionTypes>(\n direction,\n 'string',\n this._direction\n );\n this.elementEnterAction = elementEnterAction || this.elementEnterAction;\n this._focusInIndex = ensureMethod<(_elements: T[]) => number, number>(\n focusInIndex,\n 'number',\n this._focusInIndex\n );\n this._listenerScope = ensureMethod<() => HTMLElement, HTMLElement>(\n listenerScope,\n 'object',\n this._listenerScope\n );\n }\n /* In handleItemMutation() method the first if condition is checking if the element is not focused or if the element's children's length is not decreasing then it means no element has been deleted and we must return.\n Then we are checking if the deleted element was the focused one before the deletion if so then we need to proceed else we casn return;\n */\n handleItemMutation(): void {\n if (\n this._currentIndex == -1 ||\n this.elements.length <= this._elements().length\n )\n return;\n const focusedElement = this.elements[this.currentIndex];\n this.clearElementCache();\n if (this.elements.includes(focusedElement)) return;\n const moveToNextElement = this.currentIndex !== this.elements.length;\n const diff = moveToNextElement ? 1 : -1;\n if (moveToNextElement) {\n this.setCurrentIndexCircularly(-1);\n }\n this.setCurrentIndexCircularly(diff);\n this.focus();\n }\n\n update({ elements }: FocusGroupConfig<T> = { elements: () => [] }): void {\n this.unmanage();\n this._elements = elements;\n this.clearElementCache();\n this.manage();\n }\n\n /**\n * resets the focusedItem to initial item\n */\n reset(): void {\n const elements = this.elements;\n if (!elements.length) return;\n this.setCurrentIndexCircularly(this.focusInIndex - this.currentIndex);\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n }\n\n focusOnItem(item?: T, options?: FocusOptions): void {\n const elements = this.elements || [];\n const newIndex: number =\n !item || !this.isFocusableElement(item)\n ? -1\n : elements.indexOf(item);\n if (newIndex > -1) {\n this.currentIndex = newIndex;\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n this.focus(options);\n }\n\n focus(options?: FocusOptions): void {\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n if (\n !this.hostDelegatesFocus ||\n elements[this.prevIndex] !== focusElement\n ) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n focusElement.tabIndex = 0;\n focusElement.focus(options);\n if (this.hostDelegatesFocus && !this.focused) {\n this.hostContainsFocus();\n }\n }\n }\n\n clearElementCache(offset = 0): void {\n this.mutationObserver.disconnect();\n delete this.cachedElements;\n this.offset = offset;\n requestAnimationFrame(() => {\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n });\n }\n\n setCurrentIndexCircularly(diff: number): void {\n const { length } = this.elements;\n let steps = length;\n this.prevIndex = this.currentIndex;\n // start at a possibly not 0 index\n let nextIndex = (length + this.currentIndex + diff) % length;\n while (\n // don't cycle the elements more than once\n steps &&\n this.elements[nextIndex] &&\n !this.isFocusableElement(this.elements[nextIndex])\n ) {\n nextIndex = (length + nextIndex + diff) % length;\n steps -= 1;\n }\n this.currentIndex = nextIndex;\n }\n\n hostContainsFocus(): void {\n this.host.addEventListener('focusout', this.handleFocusout);\n this.host.addEventListener('keydown', this.handleKeydown);\n this.focused = true;\n }\n\n hostNoLongerContainsFocus(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.focused = false;\n }\n\n isRelatedTargetOrContainAnElement(event: FocusEvent): boolean {\n const relatedTarget = event.relatedTarget as null | Element;\n\n const isRelatedTargetAnElement = this.elements.includes(\n relatedTarget as T\n );\n const isRelatedTargetContainedWithinElements = this.elements.some(\n (el) => el.contains(relatedTarget)\n );\n return !(\n isRelatedTargetAnElement || isRelatedTargetContainedWithinElements\n );\n }\n\n handleFocusin = (event: FocusEvent): void => {\n if (!this.isEventWithinListenerScope(event)) return;\n\n const path = event.composedPath() as T[];\n let targetIndex = -1;\n path.find((el) => {\n targetIndex = this.elements.indexOf(el);\n return targetIndex !== -1;\n });\n this.prevIndex = this.currentIndex;\n this.currentIndex = targetIndex > -1 ? targetIndex : this.currentIndex;\n\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostContainsFocus();\n }\n };\n\n /**\n * handleClick - Finds the element that was clicked and sets the tabindex to 0\n * @returns void\n */\n handleClick = (): void => {\n // Manually set the tabindex to 0 for the current element on receiving focus (from keyboard or mouse)\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n };\n\n handleFocusout = (event: FocusEvent): void => {\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostNoLongerContainsFocus();\n }\n };\n\n acceptsEventKey(key: string): boolean {\n if (key === 'End' || key === 'Home') {\n return true;\n }\n switch (this.direction) {\n case 'horizontal':\n return key === 'ArrowLeft' || key === 'ArrowRight';\n case 'vertical':\n return key === 'ArrowUp' || key === 'ArrowDown';\n case 'both':\n case 'grid':\n return key.startsWith('Arrow');\n }\n }\n\n handleKeydown = (event: KeyboardEvent): void => {\n if (!this.acceptsEventKey(event.key) || event.defaultPrevented) {\n return;\n }\n let diff = 0;\n this.prevIndex = this.currentIndex;\n switch (event.key) {\n case 'ArrowRight':\n diff += 1;\n break;\n case 'ArrowDown':\n diff += this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'ArrowLeft':\n diff -= 1;\n break;\n case 'ArrowUp':\n diff -= this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'End':\n this.currentIndex = 0;\n diff -= 1;\n break;\n case 'Home':\n this.currentIndex = this.elements.length - 1;\n diff += 1;\n break;\n }\n event.preventDefault();\n if (this.direction === 'grid' && this.currentIndex + diff < 0) {\n this.currentIndex = 0;\n } else if (\n this.direction === 'grid' &&\n this.currentIndex + diff > this.elements.length - 1\n ) {\n this.currentIndex = this.elements.length - 1;\n } else {\n this.setCurrentIndexCircularly(diff);\n }\n // To allow the `focusInIndex` to be calculated with the \"after\" state of the keyboard interaction\n // do `elementEnterAction` _before_ focusing the next element.\n this.elementEnterAction(this.elements[this.currentIndex]);\n this.focus();\n };\n\n manage(): void {\n this.addEventListeners();\n }\n\n unmanage(): void {\n this.removeEventListeners();\n }\n\n addEventListeners(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.addEventListener('click', this.handleClick);\n }\n\n removeEventListeners(): void {\n this.host.removeEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.host.removeEventListener('click', this.handleClick);\n }\n\n hostConnected(): void {\n this.recentlyConnected = true;\n this.addEventListeners();\n }\n\n hostDisconnected(): void {\n this.mutationObserver.disconnect();\n this.removeEventListeners();\n }\n\n hostUpdated(): void {\n if (this.recentlyConnected) {\n this.recentlyConnected = false;\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n }\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\ntype DirectionTypes = 'horizontal' | 'vertical' | 'both' | 'grid';\nexport type FocusGroupConfig<T> = {\n hostDelegatesFocus?: boolean;\n focusInIndex?: (_elements: T[]) => number;\n direction?: DirectionTypes | (() => DirectionTypes);\n elementEnterAction?: (el: T) => void;\n elements: () => T[];\n isFocusableElement?: (el: T) => boolean;\n listenerScope?: HTMLElement | (() => HTMLElement);\n};\n\nfunction ensureMethod<T, RT>(\n value: T | RT | undefined,\n type: string,\n fallback: T\n): T {\n if (typeof value === type) {\n return (() => value) as T;\n } else if (typeof value === 'function') {\n return value as T;\n }\n return fallback;\n}\n\nexport class FocusGroupController<T extends HTMLElement>\n implements ReactiveController\n{\n protected cachedElements?: T[];\n private mutationObserver: MutationObserver;\n\n get currentIndex(): number {\n if (this._currentIndex === -1) {\n this._currentIndex = this.focusInIndex;\n }\n return this._currentIndex - this.offset;\n }\n\n set currentIndex(currentIndex) {\n this._currentIndex = currentIndex + this.offset;\n }\n\n private _currentIndex = -1;\n\n private prevIndex = -1;\n\n get direction(): DirectionTypes {\n return this._direction();\n }\n\n _direction = (): DirectionTypes => 'both';\n\n public directionLength = 5;\n\n public hostDelegatesFocus = false;\n\n elementEnterAction = (_el: T): void => {\n return;\n };\n\n get elements(): T[] {\n if (!this.cachedElements) {\n this.cachedElements = this._elements();\n }\n return this.cachedElements;\n }\n\n private _elements!: () => T[];\n\n protected set focused(focused: boolean) {\n /* c8 ignore next 1 */\n if (focused === this.focused) return;\n this._focused = focused;\n }\n\n protected get focused(): boolean {\n return this._focused;\n }\n\n private _focused = false;\n\n get focusInElement(): T {\n return this.elements[this.focusInIndex];\n }\n\n get focusInIndex(): number {\n return this._focusInIndex(this.elements);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _focusInIndex = (_elements: T[]): number => 0;\n\n host: ReactiveElement;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isFocusableElement = (_el: T): boolean => true;\n\n isEventWithinListenerScope(event: Event): boolean {\n if (this._listenerScope() === this.host) return true;\n return event.composedPath().includes(this._listenerScope());\n }\n\n _listenerScope = (): HTMLElement => this.host;\n\n // When elements are virtualized, the delta between the first element\n // and the first rendered element.\n offset = 0;\n\n recentlyConnected = false;\n\n constructor(\n host: ReactiveElement,\n {\n hostDelegatesFocus,\n direction,\n elementEnterAction,\n elements,\n focusInIndex,\n isFocusableElement,\n listenerScope,\n }: FocusGroupConfig<T> = { elements: () => [] }\n ) {\n this.mutationObserver = new MutationObserver(() => {\n this.handleItemMutation();\n });\n this.hostDelegatesFocus = hostDelegatesFocus || false;\n this.host = host;\n this.host.addController(this);\n this._elements = elements;\n this.isFocusableElement = isFocusableElement || this.isFocusableElement;\n this._direction = ensureMethod<() => DirectionTypes, DirectionTypes>(\n direction,\n 'string',\n this._direction\n );\n this.elementEnterAction = elementEnterAction || this.elementEnterAction;\n this._focusInIndex = ensureMethod<(_elements: T[]) => number, number>(\n focusInIndex,\n 'number',\n this._focusInIndex\n );\n this._listenerScope = ensureMethod<() => HTMLElement, HTMLElement>(\n listenerScope,\n 'object',\n this._listenerScope\n );\n }\n /* In handleItemMutation() method the first if condition is checking if the element is not focused or if the element's children's length is not decreasing then it means no element has been deleted and we must return.\n Then we are checking if the deleted element was the focused one before the deletion if so then we need to proceed else we casn return;\n */\n handleItemMutation(): void {\n if (\n this._currentIndex == -1 ||\n this.elements.length <= this._elements().length\n )\n return;\n const focusedElement = this.elements[this.currentIndex];\n this.clearElementCache();\n if (this.elements.includes(focusedElement)) return;\n const moveToNextElement = this.currentIndex !== this.elements.length;\n const diff = moveToNextElement ? 1 : -1;\n if (moveToNextElement) {\n this.setCurrentIndexCircularly(-1);\n }\n this.setCurrentIndexCircularly(diff);\n this.focus();\n }\n\n update({ elements }: FocusGroupConfig<T> = { elements: () => [] }): void {\n this.unmanage();\n this._elements = elements;\n this.clearElementCache();\n this.manage();\n }\n\n /**\n * resets the focusedItem to initial item\n */\n reset(): void {\n const elements = this.elements;\n if (!elements.length) return;\n this.setCurrentIndexCircularly(this.focusInIndex - this.currentIndex);\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n }\n\n focusOnItem(item?: T, options?: FocusOptions): void {\n const elements = this.elements || [];\n const newIndex: number =\n !item || !this.isFocusableElement(item)\n ? -1\n : elements.indexOf(item);\n if (newIndex > -1) {\n this.currentIndex = newIndex;\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n this.focus(options);\n }\n\n focus(options?: FocusOptions): void {\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n if (\n !this.hostDelegatesFocus ||\n elements[this.prevIndex] !== focusElement\n ) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n }\n focusElement.tabIndex = 0;\n focusElement.focus(options);\n if (this.hostDelegatesFocus && !this.focused) {\n this.hostContainsFocus();\n }\n }\n }\n\n clearElementCache(offset = 0): void {\n this.mutationObserver.disconnect();\n delete this.cachedElements;\n this.offset = offset;\n requestAnimationFrame(() => {\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n });\n }\n\n setCurrentIndexCircularly(diff: number): void {\n const { length } = this.elements;\n let steps = length;\n this.prevIndex = this.currentIndex;\n // start at a possibly not 0 index\n let nextIndex = (length + this.currentIndex + diff) % length;\n while (\n // don't cycle the elements more than once\n steps &&\n this.elements[nextIndex] &&\n !this.isFocusableElement(this.elements[nextIndex])\n ) {\n nextIndex = (length + nextIndex + diff) % length;\n steps -= 1;\n }\n this.currentIndex = nextIndex;\n }\n\n hostContainsFocus(): void {\n this.host.addEventListener('focusout', this.handleFocusout);\n this.host.addEventListener('keydown', this.handleKeydown);\n this.focused = true;\n }\n\n hostNoLongerContainsFocus(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.focused = false;\n }\n\n isRelatedTargetOrContainAnElement(event: FocusEvent): boolean {\n const relatedTarget = event.relatedTarget as null | Element;\n\n const isRelatedTargetAnElement = this.elements.includes(\n relatedTarget as T\n );\n const isRelatedTargetContainedWithinElements = this.elements.some(\n (el) => el.contains(relatedTarget)\n );\n return !(\n isRelatedTargetAnElement || isRelatedTargetContainedWithinElements\n );\n }\n\n handleFocusin = (event: FocusEvent): void => {\n if (!this.isEventWithinListenerScope(event)) return;\n\n const path = event.composedPath() as T[];\n let targetIndex = -1;\n path.find((el) => {\n targetIndex = this.elements.indexOf(el);\n return targetIndex !== -1;\n });\n this.prevIndex = this.currentIndex;\n this.currentIndex = targetIndex > -1 ? targetIndex : this.currentIndex;\n\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostContainsFocus();\n }\n };\n\n /**\n * handleClick - Finds the element that was clicked and sets the tabindex to 0\n * @returns void\n */\n handleClick = (): void => {\n // Manually set the tabindex to 0 for the current element on receiving focus (from keyboard or mouse)\n const elements = this.elements;\n if (!elements.length) return;\n let focusElement = elements[this.currentIndex];\n if (this.currentIndex < 0) {\n return;\n }\n if (!focusElement || !this.isFocusableElement(focusElement)) {\n this.setCurrentIndexCircularly(1);\n focusElement = elements[this.currentIndex];\n }\n if (focusElement && this.isFocusableElement(focusElement)) {\n elements[this.prevIndex]?.setAttribute('tabindex', '-1');\n focusElement.setAttribute('tabindex', '0');\n }\n };\n\n handleFocusout = (event: FocusEvent): void => {\n if (this.isRelatedTargetOrContainAnElement(event)) {\n this.hostNoLongerContainsFocus();\n }\n };\n\n acceptsEventKey(key: string): boolean {\n if (key === 'End' || key === 'Home') {\n return true;\n }\n switch (this.direction) {\n case 'horizontal':\n return key === 'ArrowLeft' || key === 'ArrowRight';\n case 'vertical':\n return key === 'ArrowUp' || key === 'ArrowDown';\n case 'both':\n case 'grid':\n return key.startsWith('Arrow');\n }\n }\n\n handleKeydown = (event: KeyboardEvent): void => {\n if (!this.acceptsEventKey(event.key) || event.defaultPrevented) {\n return;\n }\n let diff = 0;\n this.prevIndex = this.currentIndex;\n switch (event.key) {\n case 'ArrowRight':\n diff += 1;\n break;\n case 'ArrowDown':\n diff += this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'ArrowLeft':\n diff -= 1;\n break;\n case 'ArrowUp':\n diff -= this.direction === 'grid' ? this.directionLength : 1;\n break;\n case 'End':\n this.currentIndex = 0;\n diff -= 1;\n break;\n case 'Home':\n this.currentIndex = this.elements.length - 1;\n diff += 1;\n break;\n }\n event.preventDefault();\n if (this.direction === 'grid' && this.currentIndex + diff < 0) {\n this.currentIndex = 0;\n } else if (\n this.direction === 'grid' &&\n this.currentIndex + diff > this.elements.length - 1\n ) {\n this.currentIndex = this.elements.length - 1;\n } else {\n this.setCurrentIndexCircularly(diff);\n }\n // To allow the `focusInIndex` to be calculated with the \"after\" state of the keyboard interaction\n // do `elementEnterAction` _before_ focusing the next element.\n this.elementEnterAction(this.elements[this.currentIndex]);\n this.focus();\n };\n\n manage(): void {\n this.addEventListeners();\n }\n\n unmanage(): void {\n this.removeEventListeners();\n }\n\n addEventListeners(): void {\n this.host.addEventListener('focusin', this.handleFocusin);\n this.host.addEventListener('click', this.handleClick);\n }\n\n removeEventListeners(): void {\n this.host.removeEventListener('focusin', this.handleFocusin);\n this.host.removeEventListener('focusout', this.handleFocusout);\n this.host.removeEventListener('keydown', this.handleKeydown);\n this.host.removeEventListener('click', this.handleClick);\n }\n\n hostConnected(): void {\n this.recentlyConnected = true;\n this.addEventListeners();\n }\n\n hostDisconnected(): void {\n this.mutationObserver.disconnect();\n this.removeEventListeners();\n }\n\n hostUpdated(): void {\n if (this.recentlyConnected) {\n this.recentlyConnected = false;\n this.elements.forEach((element) => {\n this.mutationObserver.observe(element, {\n attributes: true,\n });\n });\n }\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["ensureMethod", "value", "type", "fallback", "host", "hostDelegatesFocus", "direction", "elementEnterAction", "elements", "focusInIndex", "isFocusableElement", "listenerScope", "_el", "_elements", "event", "path", "targetIndex", "el", "_a", "focusElement", "diff", "currentIndex", "focused", "focusedElement", "moveToNextElement", "item", "options", "newIndex", "offset", "element", "length", "steps", "nextIndex", "relatedTarget", "isRelatedTargetAnElement", "isRelatedTargetContainedWithinElements", "key"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveController, ReactiveElement } from 'lit';
2
13
  export declare const languageResolverUpdatedSymbol: unique symbol;
3
14
  export declare class LanguageResolutionController implements ReactiveController {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["LanguageResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport { ProvideLang } from '@spectrum-web-components/theme';\n\nexport const languageResolverUpdatedSymbol = Symbol(\n 'language resolver updated'\n);\n\nexport class LanguageResolutionController implements ReactiveController {\n private host: ReactiveElement;\n language = document.documentElement.lang || navigator.language;\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveLanguage();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveLanguage(): void {\n const queryThemeEvent = new CustomEvent<ProvideLang>(\n 'sp-language-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (lang: string, unsubscribe: () => void) => {\n const previous = this.language;\n this.language = lang;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n languageResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(queryThemeEvent);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport { ProvideLang } from '@spectrum-web-components/theme';\n\nexport const languageResolverUpdatedSymbol = Symbol(\n 'language resolver updated'\n);\n\nexport class LanguageResolutionController implements ReactiveController {\n private host: ReactiveElement;\n language = document.documentElement.lang || navigator.language;\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveLanguage();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveLanguage(): void {\n const queryThemeEvent = new CustomEvent<ProvideLang>(\n 'sp-language-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (lang: string, unsubscribe: () => void) => {\n const previous = this.language;\n this.language = lang;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n languageResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(queryThemeEvent);\n }\n}\n"],
5
5
  "mappings": ";AAeO,aAAM,gCAAgC;AAAA,EACzC;AACJ;AAEO,aAAM,6BAA2D;AAAA,EAKpE,YAAY,MAAuB;AAHnC,oBAAW,SAAS,gBAAgB,QAAQ,UAAU;AAIlD,SAAK,OAAO;AACZ,SAAK,KAAK,cAAc,IAAI;AAAA,EAChC;AAAA,EAEO,gBAAsB;AACzB,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEO,mBAAyB;AAjCpC;AAkCQ,eAAK,gBAAL;AAAA,EACJ;AAAA,EAEQ,kBAAwB;AAC5B,UAAM,kBAAkB,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,QACI,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,UACJ,UAAU,CAAC,MAAc,gBAA4B;AACjD,kBAAM,WAAW,KAAK;AACtB,iBAAK,WAAW;AAChB,iBAAK,cAAc;AACnB,iBAAK,KAAK;AAAA,cACN;AAAA,cACA;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,QACA,YAAY;AAAA,MAChB;AAAA,IACJ;AACA,SAAK,KAAK,cAAc,eAAe;AAAA,EAC3C;AACJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["LanguageResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport { ProvideLang } from '@spectrum-web-components/theme';\n\nexport const languageResolverUpdatedSymbol = Symbol(\n 'language resolver updated'\n);\n\nexport class LanguageResolutionController implements ReactiveController {\n private host: ReactiveElement;\n language = document.documentElement.lang || navigator.language;\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveLanguage();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveLanguage(): void {\n const queryThemeEvent = new CustomEvent<ProvideLang>(\n 'sp-language-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (lang: string, unsubscribe: () => void) => {\n const previous = this.language;\n this.language = lang;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n languageResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(queryThemeEvent);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport { ProvideLang } from '@spectrum-web-components/theme';\n\nexport const languageResolverUpdatedSymbol = Symbol(\n 'language resolver updated'\n);\n\nexport class LanguageResolutionController implements ReactiveController {\n private host: ReactiveElement;\n language = document.documentElement.lang || navigator.language;\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveLanguage();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveLanguage(): void {\n const queryThemeEvent = new CustomEvent<ProvideLang>(\n 'sp-language-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (lang: string, unsubscribe: () => void) => {\n const previous = this.language;\n this.language = lang;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n languageResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(queryThemeEvent);\n }\n}\n"],
5
5
  "mappings": "aAeO,aAAM,8BAAgC,OACzC,2BACJ,EAEO,aAAM,4BAA2D,CAKpE,YAAYA,EAAuB,CAHnC,cAAW,SAAS,gBAAgB,MAAQ,UAAU,SAIlD,KAAK,KAAOA,EACZ,KAAK,KAAK,cAAc,IAAI,CAChC,CAEO,eAAsB,CACzB,KAAK,gBAAgB,CACzB,CAEO,kBAAyB,CAjCpC,IAAAC,GAkCQA,EAAA,KAAK,cAAL,MAAAA,EAAA,UACJ,CAEQ,iBAAwB,CAC5B,MAAMC,EAAkB,IAAI,YACxB,sBACA,CACI,QAAS,GACT,SAAU,GACV,OAAQ,CACJ,SAAU,CAACC,EAAcC,IAA4B,CACjD,MAAMC,EAAW,KAAK,SACtB,KAAK,SAAWF,EAChB,KAAK,YAAcC,EACnB,KAAK,KAAK,cACN,8BACAC,CACJ,CACJ,CACJ,EACA,WAAY,EAChB,CACJ,EACA,KAAK,KAAK,cAAcH,CAAe,CAC3C,CACJ",
6
6
  "names": ["host", "_a", "queryThemeEvent", "lang", "unsubscribe", "previous"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveController, ReactiveElement } from 'lit';
2
13
  export declare const DARK_MODE = "(prefers-color-scheme: dark)";
3
14
  export declare const IS_MOBILE = "(max-width: 743px) and (hover: none) and (pointer: coarse)";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["MatchMedia.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\nexport const DARK_MODE = '(prefers-color-scheme: dark)';\nexport const IS_MOBILE =\n '(max-width: 743px) and (hover: none) and (pointer: coarse)';\n\nexport class MatchMediaController implements ReactiveController {\n key = Symbol('match-media-key');\n\n matches = false;\n\n protected host: ReactiveElement;\n\n protected media: MediaQueryList;\n\n constructor(host: ReactiveElement, query: string) {\n this.host = host;\n this.host.addController(this);\n this.media = window.matchMedia(query);\n this.matches = this.media.matches;\n this.onChange = this.onChange.bind(this);\n host.addController(this);\n }\n\n public hostConnected(): void {\n this.media?.addEventListener('change', this.onChange);\n }\n\n public hostDisconnected(): void {\n this.media?.removeEventListener('change', this.onChange);\n }\n\n protected onChange(event: MediaQueryListEvent): void {\n if (this.matches === event.matches) return;\n this.matches = event.matches;\n this.host.requestUpdate(this.key, !this.matches);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\nexport const DARK_MODE = '(prefers-color-scheme: dark)';\nexport const IS_MOBILE =\n '(max-width: 743px) and (hover: none) and (pointer: coarse)';\n\nexport class MatchMediaController implements ReactiveController {\n key = Symbol('match-media-key');\n\n matches = false;\n\n protected host: ReactiveElement;\n\n protected media: MediaQueryList;\n\n constructor(host: ReactiveElement, query: string) {\n this.host = host;\n this.host.addController(this);\n this.media = window.matchMedia(query);\n this.matches = this.media.matches;\n this.onChange = this.onChange.bind(this);\n host.addController(this);\n }\n\n public hostConnected(): void {\n this.media?.addEventListener('change', this.onChange);\n }\n\n public hostDisconnected(): void {\n this.media?.removeEventListener('change', this.onChange);\n }\n\n protected onChange(event: MediaQueryListEvent): void {\n if (this.matches === event.matches) return;\n this.matches = event.matches;\n this.host.requestUpdate(this.key, !this.matches);\n }\n}\n"],
5
5
  "mappings": ";AAaO,aAAM,YAAY;AAClB,aAAM,YACT;AAEG,aAAM,qBAAmD;AAAA,EAS5D,YAAY,MAAuB,OAAe;AARlD,eAAM,OAAO,iBAAiB;AAE9B,mBAAU;AAON,SAAK,OAAO;AACZ,SAAK,KAAK,cAAc,IAAI;AAC5B,SAAK,QAAQ,OAAO,WAAW,KAAK;AACpC,SAAK,UAAU,KAAK,MAAM;AAC1B,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AACvC,SAAK,cAAc,IAAI;AAAA,EAC3B;AAAA,EAEO,gBAAsB;AAnCjC;AAoCQ,eAAK,UAAL,mBAAY,iBAAiB,UAAU,KAAK;AAAA,EAChD;AAAA,EAEO,mBAAyB;AAvCpC;AAwCQ,eAAK,UAAL,mBAAY,oBAAoB,UAAU,KAAK;AAAA,EACnD;AAAA,EAEU,SAAS,OAAkC;AACjD,QAAI,KAAK,YAAY,MAAM,QAAS;AACpC,SAAK,UAAU,MAAM;AACrB,SAAK,KAAK,cAAc,KAAK,KAAK,CAAC,KAAK,OAAO;AAAA,EACnD;AACJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["MatchMedia.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\nexport const DARK_MODE = '(prefers-color-scheme: dark)';\nexport const IS_MOBILE =\n '(max-width: 743px) and (hover: none) and (pointer: coarse)';\n\nexport class MatchMediaController implements ReactiveController {\n key = Symbol('match-media-key');\n\n matches = false;\n\n protected host: ReactiveElement;\n\n protected media: MediaQueryList;\n\n constructor(host: ReactiveElement, query: string) {\n this.host = host;\n this.host.addController(this);\n this.media = window.matchMedia(query);\n this.matches = this.media.matches;\n this.onChange = this.onChange.bind(this);\n host.addController(this);\n }\n\n public hostConnected(): void {\n this.media?.addEventListener('change', this.onChange);\n }\n\n public hostDisconnected(): void {\n this.media?.removeEventListener('change', this.onChange);\n }\n\n protected onChange(event: MediaQueryListEvent): void {\n if (this.matches === event.matches) return;\n this.matches = event.matches;\n this.host.requestUpdate(this.key, !this.matches);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\nexport const DARK_MODE = '(prefers-color-scheme: dark)';\nexport const IS_MOBILE =\n '(max-width: 743px) and (hover: none) and (pointer: coarse)';\n\nexport class MatchMediaController implements ReactiveController {\n key = Symbol('match-media-key');\n\n matches = false;\n\n protected host: ReactiveElement;\n\n protected media: MediaQueryList;\n\n constructor(host: ReactiveElement, query: string) {\n this.host = host;\n this.host.addController(this);\n this.media = window.matchMedia(query);\n this.matches = this.media.matches;\n this.onChange = this.onChange.bind(this);\n host.addController(this);\n }\n\n public hostConnected(): void {\n this.media?.addEventListener('change', this.onChange);\n }\n\n public hostDisconnected(): void {\n this.media?.removeEventListener('change', this.onChange);\n }\n\n protected onChange(event: MediaQueryListEvent): void {\n if (this.matches === event.matches) return;\n this.matches = event.matches;\n this.host.requestUpdate(this.key, !this.matches);\n }\n}\n"],
5
5
  "mappings": "aAaO,aAAM,UAAY,+BACZ,UACT,6DAEG,aAAM,oBAAmD,CAS5D,YAAYA,EAAuBC,EAAe,CARlD,SAAM,OAAO,iBAAiB,EAE9B,aAAU,GAON,KAAK,KAAOD,EACZ,KAAK,KAAK,cAAc,IAAI,EAC5B,KAAK,MAAQ,OAAO,WAAWC,CAAK,EACpC,KAAK,QAAU,KAAK,MAAM,QAC1B,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EACvCD,EAAK,cAAc,IAAI,CAC3B,CAEO,eAAsB,CAnCjC,IAAAE,GAoCQA,EAAA,KAAK,QAAL,MAAAA,EAAY,iBAAiB,SAAU,KAAK,SAChD,CAEO,kBAAyB,CAvCpC,IAAAA,GAwCQA,EAAA,KAAK,QAAL,MAAAA,EAAY,oBAAoB,SAAU,KAAK,SACnD,CAEU,SAASC,EAAkC,CAC7C,KAAK,UAAYA,EAAM,UAC3B,KAAK,QAAUA,EAAM,QACrB,KAAK,KAAK,cAAc,KAAK,IAAK,CAAC,KAAK,OAAO,EACnD,CACJ",
6
6
  "names": ["host", "query", "_a", "event"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import { LitElement, ReactiveController, TemplateResult } from 'lit';
2
13
  import '@spectrum-web-components/progress-circle/sp-progress-circle.js';
3
14
  /**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["PendingState.ts"],
4
- "sourcesContent": ["/*\nCopyright 2024 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { html, LitElement, ReactiveController, TemplateResult } from 'lit';\nimport '@spectrum-web-components/progress-circle/sp-progress-circle.js';\n\n/**\n * Represents a host element with pending state.\n */\nexport interface HostWithPendingState extends LitElement {\n pendingLabel?: string;\n pending: boolean;\n disabled: boolean;\n pendingStateController: PendingStateController<HostWithPendingState>;\n}\n\n/**\n * Represents a controller for managing the pending state of a reactive element.\n *\n * @template T - The type of the reactive element.\n */\nexport class PendingStateController<T extends HostWithPendingState>\n implements ReactiveController\n{\n /**\n * The host element that this controller is attached to.\n */\n public host: T;\n\n /**\n * Creates an instance of PendingStateController.\n * @param host - The host element that this controller is attached to.\n */\n constructor(host: T) {\n this.host = host;\n this.host.addController(this);\n }\n\n public cachedAriaLabel: string | null = null;\n /**\n * Renders the pending state UI.\n * @returns A TemplateResult representing the pending state UI.\n */\n public renderPendingState(): TemplateResult {\n const pendingLabel = this.host.pendingLabel || 'Pending';\n return this.host.pending\n ? html`\n <sp-progress-circle\n id=\"loader\"\n size=\"s\"\n indeterminate\n aria-valuetext=${pendingLabel}\n class=\"progress-circle\"\n ></sp-progress-circle>\n `\n : html``;\n }\n\n /**\n * Updates the ARIA label of the host element based on the pending state.\n * Manages Cached Aria Label\n */\n private updateAriaLabel(): void {\n const { pending, disabled, pendingLabel } = this.host;\n const currentAriaLabel = this.host.getAttribute('aria-label');\n\n if (pending && !disabled && currentAriaLabel !== pendingLabel) {\n // Cache the current `aria-label` to be restored when no longer `pending`\n this.cachedAriaLabel = currentAriaLabel;\n // Since it is pending, we set the aria-label to `pendingLabel` or \"Pending\"\n this.host.setAttribute('aria-label', pendingLabel || 'Pending');\n } else if (!pending || disabled) {\n // Restore the cached `aria-label` if it exists\n if (this.cachedAriaLabel) {\n this.host.setAttribute('aria-label', this.cachedAriaLabel);\n } else if (!pending) {\n // If no cached `aria-label` and not `pending`, remove the `aria-label`\n this.host.removeAttribute('aria-label');\n }\n }\n }\n\n hostConnected(): void {\n if (!this.cachedAriaLabel)\n this.cachedAriaLabel = this.host.getAttribute('aria-label');\n this.updateAriaLabel();\n }\n\n hostUpdated(): void {\n this.updateAriaLabel();\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { html, LitElement, ReactiveController, TemplateResult } from 'lit';\nimport '@spectrum-web-components/progress-circle/sp-progress-circle.js';\n\n/**\n * Represents a host element with pending state.\n */\nexport interface HostWithPendingState extends LitElement {\n pendingLabel?: string;\n pending: boolean;\n disabled: boolean;\n pendingStateController: PendingStateController<HostWithPendingState>;\n}\n\n/**\n * Represents a controller for managing the pending state of a reactive element.\n *\n * @template T - The type of the reactive element.\n */\nexport class PendingStateController<T extends HostWithPendingState>\n implements ReactiveController\n{\n /**\n * The host element that this controller is attached to.\n */\n public host: T;\n\n /**\n * Creates an instance of PendingStateController.\n * @param host - The host element that this controller is attached to.\n */\n constructor(host: T) {\n this.host = host;\n this.host.addController(this);\n }\n\n public cachedAriaLabel: string | null = null;\n /**\n * Renders the pending state UI.\n * @returns A TemplateResult representing the pending state UI.\n */\n public renderPendingState(): TemplateResult {\n const pendingLabel = this.host.pendingLabel || 'Pending';\n return this.host.pending\n ? html`\n <sp-progress-circle\n id=\"loader\"\n size=\"s\"\n indeterminate\n aria-valuetext=${pendingLabel}\n class=\"progress-circle\"\n ></sp-progress-circle>\n `\n : html``;\n }\n\n /**\n * Updates the ARIA label of the host element based on the pending state.\n * Manages Cached Aria Label\n */\n private updateAriaLabel(): void {\n const { pending, disabled, pendingLabel } = this.host;\n const currentAriaLabel = this.host.getAttribute('aria-label');\n\n if (pending && !disabled && currentAriaLabel !== pendingLabel) {\n // Cache the current `aria-label` to be restored when no longer `pending`\n this.cachedAriaLabel = currentAriaLabel;\n // Since it is pending, we set the aria-label to `pendingLabel` or \"Pending\"\n this.host.setAttribute('aria-label', pendingLabel || 'Pending');\n } else if (!pending || disabled) {\n // Restore the cached `aria-label` if it exists\n if (this.cachedAriaLabel) {\n this.host.setAttribute('aria-label', this.cachedAriaLabel);\n } else if (!pending) {\n // If no cached `aria-label` and not `pending`, remove the `aria-label`\n this.host.removeAttribute('aria-label');\n }\n }\n }\n\n hostConnected(): void {\n if (!this.cachedAriaLabel)\n this.cachedAriaLabel = this.host.getAttribute('aria-label');\n this.updateAriaLabel();\n }\n\n hostUpdated(): void {\n this.updateAriaLabel();\n }\n}\n"],
5
5
  "mappings": ";AAYA,SAAS,YAA4D;AACrE,OAAO;AAiBA,aAAM,uBAEb;AAAA;AAAA;AAAA;AAAA;AAAA,EAUI,YAAY,MAAS;AAKrB,SAAO,kBAAiC;AAJpC,SAAK,OAAO;AACZ,SAAK,KAAK,cAAc,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,qBAAqC;AACxC,UAAM,eAAe,KAAK,KAAK,gBAAgB;AAC/C,WAAO,KAAK,KAAK,UACX;AAAA;AAAA;AAAA;AAAA;AAAA,uCAKyB,YAAY;AAAA;AAAA;AAAA,kBAIrC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAwB;AAC5B,UAAM,EAAE,SAAS,UAAU,aAAa,IAAI,KAAK;AACjD,UAAM,mBAAmB,KAAK,KAAK,aAAa,YAAY;AAE5D,QAAI,WAAW,CAAC,YAAY,qBAAqB,cAAc;AAE3D,WAAK,kBAAkB;AAEvB,WAAK,KAAK,aAAa,cAAc,gBAAgB,SAAS;AAAA,IAClE,WAAW,CAAC,WAAW,UAAU;AAE7B,UAAI,KAAK,iBAAiB;AACtB,aAAK,KAAK,aAAa,cAAc,KAAK,eAAe;AAAA,MAC7D,WAAW,CAAC,SAAS;AAEjB,aAAK,KAAK,gBAAgB,YAAY;AAAA,MAC1C;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,gBAAsB;AAClB,QAAI,CAAC,KAAK;AACN,WAAK,kBAAkB,KAAK,KAAK,aAAa,YAAY;AAC9D,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEA,cAAoB;AAChB,SAAK,gBAAgB;AAAA,EACzB;AACJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["PendingState.ts"],
4
- "sourcesContent": ["/*\nCopyright 2024 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { html, LitElement, ReactiveController, TemplateResult } from 'lit';\nimport '@spectrum-web-components/progress-circle/sp-progress-circle.js';\n\n/**\n * Represents a host element with pending state.\n */\nexport interface HostWithPendingState extends LitElement {\n pendingLabel?: string;\n pending: boolean;\n disabled: boolean;\n pendingStateController: PendingStateController<HostWithPendingState>;\n}\n\n/**\n * Represents a controller for managing the pending state of a reactive element.\n *\n * @template T - The type of the reactive element.\n */\nexport class PendingStateController<T extends HostWithPendingState>\n implements ReactiveController\n{\n /**\n * The host element that this controller is attached to.\n */\n public host: T;\n\n /**\n * Creates an instance of PendingStateController.\n * @param host - The host element that this controller is attached to.\n */\n constructor(host: T) {\n this.host = host;\n this.host.addController(this);\n }\n\n public cachedAriaLabel: string | null = null;\n /**\n * Renders the pending state UI.\n * @returns A TemplateResult representing the pending state UI.\n */\n public renderPendingState(): TemplateResult {\n const pendingLabel = this.host.pendingLabel || 'Pending';\n return this.host.pending\n ? html`\n <sp-progress-circle\n id=\"loader\"\n size=\"s\"\n indeterminate\n aria-valuetext=${pendingLabel}\n class=\"progress-circle\"\n ></sp-progress-circle>\n `\n : html``;\n }\n\n /**\n * Updates the ARIA label of the host element based on the pending state.\n * Manages Cached Aria Label\n */\n private updateAriaLabel(): void {\n const { pending, disabled, pendingLabel } = this.host;\n const currentAriaLabel = this.host.getAttribute('aria-label');\n\n if (pending && !disabled && currentAriaLabel !== pendingLabel) {\n // Cache the current `aria-label` to be restored when no longer `pending`\n this.cachedAriaLabel = currentAriaLabel;\n // Since it is pending, we set the aria-label to `pendingLabel` or \"Pending\"\n this.host.setAttribute('aria-label', pendingLabel || 'Pending');\n } else if (!pending || disabled) {\n // Restore the cached `aria-label` if it exists\n if (this.cachedAriaLabel) {\n this.host.setAttribute('aria-label', this.cachedAriaLabel);\n } else if (!pending) {\n // If no cached `aria-label` and not `pending`, remove the `aria-label`\n this.host.removeAttribute('aria-label');\n }\n }\n }\n\n hostConnected(): void {\n if (!this.cachedAriaLabel)\n this.cachedAriaLabel = this.host.getAttribute('aria-label');\n this.updateAriaLabel();\n }\n\n hostUpdated(): void {\n this.updateAriaLabel();\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { html, LitElement, ReactiveController, TemplateResult } from 'lit';\nimport '@spectrum-web-components/progress-circle/sp-progress-circle.js';\n\n/**\n * Represents a host element with pending state.\n */\nexport interface HostWithPendingState extends LitElement {\n pendingLabel?: string;\n pending: boolean;\n disabled: boolean;\n pendingStateController: PendingStateController<HostWithPendingState>;\n}\n\n/**\n * Represents a controller for managing the pending state of a reactive element.\n *\n * @template T - The type of the reactive element.\n */\nexport class PendingStateController<T extends HostWithPendingState>\n implements ReactiveController\n{\n /**\n * The host element that this controller is attached to.\n */\n public host: T;\n\n /**\n * Creates an instance of PendingStateController.\n * @param host - The host element that this controller is attached to.\n */\n constructor(host: T) {\n this.host = host;\n this.host.addController(this);\n }\n\n public cachedAriaLabel: string | null = null;\n /**\n * Renders the pending state UI.\n * @returns A TemplateResult representing the pending state UI.\n */\n public renderPendingState(): TemplateResult {\n const pendingLabel = this.host.pendingLabel || 'Pending';\n return this.host.pending\n ? html`\n <sp-progress-circle\n id=\"loader\"\n size=\"s\"\n indeterminate\n aria-valuetext=${pendingLabel}\n class=\"progress-circle\"\n ></sp-progress-circle>\n `\n : html``;\n }\n\n /**\n * Updates the ARIA label of the host element based on the pending state.\n * Manages Cached Aria Label\n */\n private updateAriaLabel(): void {\n const { pending, disabled, pendingLabel } = this.host;\n const currentAriaLabel = this.host.getAttribute('aria-label');\n\n if (pending && !disabled && currentAriaLabel !== pendingLabel) {\n // Cache the current `aria-label` to be restored when no longer `pending`\n this.cachedAriaLabel = currentAriaLabel;\n // Since it is pending, we set the aria-label to `pendingLabel` or \"Pending\"\n this.host.setAttribute('aria-label', pendingLabel || 'Pending');\n } else if (!pending || disabled) {\n // Restore the cached `aria-label` if it exists\n if (this.cachedAriaLabel) {\n this.host.setAttribute('aria-label', this.cachedAriaLabel);\n } else if (!pending) {\n // If no cached `aria-label` and not `pending`, remove the `aria-label`\n this.host.removeAttribute('aria-label');\n }\n }\n }\n\n hostConnected(): void {\n if (!this.cachedAriaLabel)\n this.cachedAriaLabel = this.host.getAttribute('aria-label');\n this.updateAriaLabel();\n }\n\n hostUpdated(): void {\n this.updateAriaLabel();\n }\n}\n"],
5
5
  "mappings": "aAYA,OAAS,QAAAA,MAA4D,MACrE,MAAO,iEAiBA,aAAM,sBAEb,CAUI,YAAYC,EAAS,CAKrB,KAAO,gBAAiC,KAJpC,KAAK,KAAOA,EACZ,KAAK,KAAK,cAAc,IAAI,CAChC,CAOO,oBAAqC,CACxC,MAAMC,EAAe,KAAK,KAAK,cAAgB,UAC/C,OAAO,KAAK,KAAK,QACXF;AAAA;AAAA;AAAA;AAAA;AAAA,uCAKyBE,CAAY;AAAA;AAAA;AAAA,gBAIrCF,GACV,CAMQ,iBAAwB,CAC5B,KAAM,CAAE,QAAAG,EAAS,SAAAC,EAAU,aAAAF,CAAa,EAAI,KAAK,KAC3CG,EAAmB,KAAK,KAAK,aAAa,YAAY,EAExDF,GAAW,CAACC,GAAYC,IAAqBH,GAE7C,KAAK,gBAAkBG,EAEvB,KAAK,KAAK,aAAa,aAAcH,GAAgB,SAAS,IACvD,CAACC,GAAWC,KAEf,KAAK,gBACL,KAAK,KAAK,aAAa,aAAc,KAAK,eAAe,EACjDD,GAER,KAAK,KAAK,gBAAgB,YAAY,EAGlD,CAEA,eAAsB,CACb,KAAK,kBACN,KAAK,gBAAkB,KAAK,KAAK,aAAa,YAAY,GAC9D,KAAK,gBAAgB,CACzB,CAEA,aAAoB,CAChB,KAAK,gBAAgB,CACzB,CACJ",
6
6
  "names": ["html", "host", "pendingLabel", "pending", "disabled", "currentAriaLabel"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import { FocusGroupConfig, FocusGroupController } from './FocusGroup.js';
2
13
  export type RovingTabindexConfig<T> = FocusGroupConfig<T>;
3
14
  interface UpdateTabIndexes {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["RovingTabindex.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { FocusGroupConfig, FocusGroupController } from './FocusGroup.dev.js'\n\nexport type RovingTabindexConfig<T> = FocusGroupConfig<T>;\ninterface UpdateTabIndexes {\n tabIndex: number;\n removeTabIndex?: boolean;\n}\n\nexport class RovingTabindexController<\n T extends HTMLElement,\n> extends FocusGroupController<T> {\n protected override set focused(focused: boolean) {\n if (focused === this.focused) return;\n super.focused = focused;\n this.manageTabindexes();\n }\n\n protected override get focused(): boolean {\n return super.focused;\n }\n\n private managed = true;\n\n private manageIndexesAnimationFrame = 0;\n\n override clearElementCache(offset = 0): void {\n cancelAnimationFrame(this.manageIndexesAnimationFrame);\n super.clearElementCache(offset);\n if (!this.managed) return;\n\n this.manageIndexesAnimationFrame = requestAnimationFrame(() =>\n this.manageTabindexes()\n );\n }\n\n manageTabindexes(): void {\n if (this.focused && !this.hostDelegatesFocus) {\n this.updateTabindexes(() => ({ tabIndex: -1 }));\n } else {\n this.updateTabindexes((el: HTMLElement): UpdateTabIndexes => {\n return {\n removeTabIndex:\n el.contains(this.focusInElement) &&\n el !== this.focusInElement,\n tabIndex: el === this.focusInElement ? 0 : -1,\n };\n });\n }\n }\n\n updateTabindexes(getTabIndex: (el: HTMLElement) => UpdateTabIndexes): void {\n this.elements.forEach((el) => {\n const { tabIndex, removeTabIndex } = getTabIndex(el);\n if (!removeTabIndex) {\n if (this.focused) {\n if (el !== this.elements[this.currentIndex]) {\n el.tabIndex = tabIndex;\n }\n } else {\n el.tabIndex = tabIndex;\n }\n return;\n }\n const updatable = el as unknown as {\n requestUpdate?: () => void;\n };\n if (updatable.requestUpdate) updatable.requestUpdate();\n });\n }\n\n override manage(): void {\n this.managed = true;\n this.manageTabindexes();\n super.manage();\n }\n\n override unmanage(): void {\n this.managed = false;\n this.updateTabindexes(() => ({ tabIndex: 0 }));\n super.unmanage();\n }\n\n override hostUpdated(): void {\n super.hostUpdated();\n if (!this.host.hasUpdated) {\n this.manageTabindexes();\n }\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { FocusGroupConfig, FocusGroupController } from './FocusGroup.dev.js'\n\nexport type RovingTabindexConfig<T> = FocusGroupConfig<T>;\ninterface UpdateTabIndexes {\n tabIndex: number;\n removeTabIndex?: boolean;\n}\n\nexport class RovingTabindexController<\n T extends HTMLElement,\n> extends FocusGroupController<T> {\n protected override set focused(focused: boolean) {\n if (focused === this.focused) return;\n super.focused = focused;\n this.manageTabindexes();\n }\n\n protected override get focused(): boolean {\n return super.focused;\n }\n\n private managed = true;\n\n private manageIndexesAnimationFrame = 0;\n\n override clearElementCache(offset = 0): void {\n cancelAnimationFrame(this.manageIndexesAnimationFrame);\n super.clearElementCache(offset);\n if (!this.managed) return;\n\n this.manageIndexesAnimationFrame = requestAnimationFrame(() =>\n this.manageTabindexes()\n );\n }\n\n manageTabindexes(): void {\n if (this.focused && !this.hostDelegatesFocus) {\n this.updateTabindexes(() => ({ tabIndex: -1 }));\n } else {\n this.updateTabindexes((el: HTMLElement): UpdateTabIndexes => {\n return {\n removeTabIndex:\n el.contains(this.focusInElement) &&\n el !== this.focusInElement,\n tabIndex: el === this.focusInElement ? 0 : -1,\n };\n });\n }\n }\n\n updateTabindexes(getTabIndex: (el: HTMLElement) => UpdateTabIndexes): void {\n this.elements.forEach((el) => {\n const { tabIndex, removeTabIndex } = getTabIndex(el);\n if (!removeTabIndex) {\n if (this.focused) {\n if (el !== this.elements[this.currentIndex]) {\n el.tabIndex = tabIndex;\n }\n } else {\n el.tabIndex = tabIndex;\n }\n return;\n }\n const updatable = el as unknown as {\n requestUpdate?: () => void;\n };\n if (updatable.requestUpdate) updatable.requestUpdate();\n });\n }\n\n override manage(): void {\n this.managed = true;\n this.manageTabindexes();\n super.manage();\n }\n\n override unmanage(): void {\n this.managed = false;\n this.updateTabindexes(() => ({ tabIndex: 0 }));\n super.unmanage();\n }\n\n override hostUpdated(): void {\n super.hostUpdated();\n if (!this.host.hasUpdated) {\n this.manageTabindexes();\n }\n }\n}\n"],
5
5
  "mappings": ";AAWA,SAA2B,4BAA4B;AAQhD,aAAM,iCAEH,qBAAwB;AAAA,EAF3B;AAAA;AAaH,SAAQ,UAAU;AAElB,SAAQ,8BAA8B;AAAA;AAAA,EAZtC,IAAuB,QAAQ,SAAkB;AAC7C,QAAI,YAAY,KAAK,QAAS;AAC9B,UAAM,UAAU;AAChB,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,IAAuB,UAAmB;AACtC,WAAO,MAAM;AAAA,EACjB;AAAA,EAMS,kBAAkB,SAAS,GAAS;AACzC,yBAAqB,KAAK,2BAA2B;AACrD,UAAM,kBAAkB,MAAM;AAC9B,QAAI,CAAC,KAAK,QAAS;AAEnB,SAAK,8BAA8B;AAAA,MAAsB,MACrD,KAAK,iBAAiB;AAAA,IAC1B;AAAA,EACJ;AAAA,EAEA,mBAAyB;AACrB,QAAI,KAAK,WAAW,CAAC,KAAK,oBAAoB;AAC1C,WAAK,iBAAiB,OAAO,EAAE,UAAU,GAAG,EAAE;AAAA,IAClD,OAAO;AACH,WAAK,iBAAiB,CAAC,OAAsC;AACzD,eAAO;AAAA,UACH,gBACI,GAAG,SAAS,KAAK,cAAc,KAC/B,OAAO,KAAK;AAAA,UAChB,UAAU,OAAO,KAAK,iBAAiB,IAAI;AAAA,QAC/C;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,iBAAiB,aAA0D;AACvE,SAAK,SAAS,QAAQ,CAAC,OAAO;AAC1B,YAAM,EAAE,UAAU,eAAe,IAAI,YAAY,EAAE;AACnD,UAAI,CAAC,gBAAgB;AACjB,YAAI,KAAK,SAAS;AACd,cAAI,OAAO,KAAK,SAAS,KAAK,YAAY,GAAG;AACzC,eAAG,WAAW;AAAA,UAClB;AAAA,QACJ,OAAO;AACH,aAAG,WAAW;AAAA,QAClB;AACA;AAAA,MACJ;AACA,YAAM,YAAY;AAGlB,UAAI,UAAU,cAAe,WAAU,cAAc;AAAA,IACzD,CAAC;AAAA,EACL;AAAA,EAES,SAAe;AACpB,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,UAAM,OAAO;AAAA,EACjB;AAAA,EAES,WAAiB;AACtB,SAAK,UAAU;AACf,SAAK,iBAAiB,OAAO,EAAE,UAAU,EAAE,EAAE;AAC7C,UAAM,SAAS;AAAA,EACnB;AAAA,EAES,cAAoB;AACzB,UAAM,YAAY;AAClB,QAAI,CAAC,KAAK,KAAK,YAAY;AACvB,WAAK,iBAAiB;AAAA,IAC1B;AAAA,EACJ;AACJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["RovingTabindex.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport { FocusGroupConfig, FocusGroupController } from './FocusGroup.js';\n\nexport type RovingTabindexConfig<T> = FocusGroupConfig<T>;\ninterface UpdateTabIndexes {\n tabIndex: number;\n removeTabIndex?: boolean;\n}\n\nexport class RovingTabindexController<\n T extends HTMLElement,\n> extends FocusGroupController<T> {\n protected override set focused(focused: boolean) {\n if (focused === this.focused) return;\n super.focused = focused;\n this.manageTabindexes();\n }\n\n protected override get focused(): boolean {\n return super.focused;\n }\n\n private managed = true;\n\n private manageIndexesAnimationFrame = 0;\n\n override clearElementCache(offset = 0): void {\n cancelAnimationFrame(this.manageIndexesAnimationFrame);\n super.clearElementCache(offset);\n if (!this.managed) return;\n\n this.manageIndexesAnimationFrame = requestAnimationFrame(() =>\n this.manageTabindexes()\n );\n }\n\n manageTabindexes(): void {\n if (this.focused && !this.hostDelegatesFocus) {\n this.updateTabindexes(() => ({ tabIndex: -1 }));\n } else {\n this.updateTabindexes((el: HTMLElement): UpdateTabIndexes => {\n return {\n removeTabIndex:\n el.contains(this.focusInElement) &&\n el !== this.focusInElement,\n tabIndex: el === this.focusInElement ? 0 : -1,\n };\n });\n }\n }\n\n updateTabindexes(getTabIndex: (el: HTMLElement) => UpdateTabIndexes): void {\n this.elements.forEach((el) => {\n const { tabIndex, removeTabIndex } = getTabIndex(el);\n if (!removeTabIndex) {\n if (this.focused) {\n if (el !== this.elements[this.currentIndex]) {\n el.tabIndex = tabIndex;\n }\n } else {\n el.tabIndex = tabIndex;\n }\n return;\n }\n const updatable = el as unknown as {\n requestUpdate?: () => void;\n };\n if (updatable.requestUpdate) updatable.requestUpdate();\n });\n }\n\n override manage(): void {\n this.managed = true;\n this.manageTabindexes();\n super.manage();\n }\n\n override unmanage(): void {\n this.managed = false;\n this.updateTabindexes(() => ({ tabIndex: 0 }));\n super.unmanage();\n }\n\n override hostUpdated(): void {\n super.hostUpdated();\n if (!this.host.hasUpdated) {\n this.manageTabindexes();\n }\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { FocusGroupConfig, FocusGroupController } from './FocusGroup.js';\n\nexport type RovingTabindexConfig<T> = FocusGroupConfig<T>;\ninterface UpdateTabIndexes {\n tabIndex: number;\n removeTabIndex?: boolean;\n}\n\nexport class RovingTabindexController<\n T extends HTMLElement,\n> extends FocusGroupController<T> {\n protected override set focused(focused: boolean) {\n if (focused === this.focused) return;\n super.focused = focused;\n this.manageTabindexes();\n }\n\n protected override get focused(): boolean {\n return super.focused;\n }\n\n private managed = true;\n\n private manageIndexesAnimationFrame = 0;\n\n override clearElementCache(offset = 0): void {\n cancelAnimationFrame(this.manageIndexesAnimationFrame);\n super.clearElementCache(offset);\n if (!this.managed) return;\n\n this.manageIndexesAnimationFrame = requestAnimationFrame(() =>\n this.manageTabindexes()\n );\n }\n\n manageTabindexes(): void {\n if (this.focused && !this.hostDelegatesFocus) {\n this.updateTabindexes(() => ({ tabIndex: -1 }));\n } else {\n this.updateTabindexes((el: HTMLElement): UpdateTabIndexes => {\n return {\n removeTabIndex:\n el.contains(this.focusInElement) &&\n el !== this.focusInElement,\n tabIndex: el === this.focusInElement ? 0 : -1,\n };\n });\n }\n }\n\n updateTabindexes(getTabIndex: (el: HTMLElement) => UpdateTabIndexes): void {\n this.elements.forEach((el) => {\n const { tabIndex, removeTabIndex } = getTabIndex(el);\n if (!removeTabIndex) {\n if (this.focused) {\n if (el !== this.elements[this.currentIndex]) {\n el.tabIndex = tabIndex;\n }\n } else {\n el.tabIndex = tabIndex;\n }\n return;\n }\n const updatable = el as unknown as {\n requestUpdate?: () => void;\n };\n if (updatable.requestUpdate) updatable.requestUpdate();\n });\n }\n\n override manage(): void {\n this.managed = true;\n this.manageTabindexes();\n super.manage();\n }\n\n override unmanage(): void {\n this.managed = false;\n this.updateTabindexes(() => ({ tabIndex: 0 }));\n super.unmanage();\n }\n\n override hostUpdated(): void {\n super.hostUpdated();\n if (!this.host.hasUpdated) {\n this.manageTabindexes();\n }\n }\n}\n"],
5
5
  "mappings": "aAWA,OAA2B,wBAAAA,MAA4B,kBAQhD,aAAM,iCAEHA,CAAwB,CAF3B,kCAaH,KAAQ,QAAU,GAElB,KAAQ,4BAA8B,EAZtC,IAAuB,QAAQC,EAAkB,CACzCA,IAAY,KAAK,UACrB,MAAM,QAAUA,EAChB,KAAK,iBAAiB,EAC1B,CAEA,IAAuB,SAAmB,CACtC,OAAO,MAAM,OACjB,CAMS,kBAAkBC,EAAS,EAAS,CACzC,qBAAqB,KAAK,2BAA2B,EACrD,MAAM,kBAAkBA,CAAM,EACzB,KAAK,UAEV,KAAK,4BAA8B,sBAAsB,IACrD,KAAK,iBAAiB,CAC1B,EACJ,CAEA,kBAAyB,CACjB,KAAK,SAAW,CAAC,KAAK,mBACtB,KAAK,iBAAiB,KAAO,CAAE,SAAU,EAAG,EAAE,EAE9C,KAAK,iBAAkBC,IACZ,CACH,eACIA,EAAG,SAAS,KAAK,cAAc,GAC/BA,IAAO,KAAK,eAChB,SAAUA,IAAO,KAAK,eAAiB,EAAI,EAC/C,EACH,CAET,CAEA,iBAAiBC,EAA0D,CACvE,KAAK,SAAS,QAASD,GAAO,CAC1B,KAAM,CAAE,SAAAE,EAAU,eAAAC,CAAe,EAAIF,EAAYD,CAAE,EACnD,GAAI,CAACG,EAAgB,CACb,KAAK,QACDH,IAAO,KAAK,SAAS,KAAK,YAAY,IACtCA,EAAG,SAAWE,GAGlBF,EAAG,SAAWE,EAElB,MACJ,CACA,MAAME,EAAYJ,EAGdI,EAAU,eAAeA,EAAU,cAAc,CACzD,CAAC,CACL,CAES,QAAe,CACpB,KAAK,QAAU,GACf,KAAK,iBAAiB,EACtB,MAAM,OAAO,CACjB,CAES,UAAiB,CACtB,KAAK,QAAU,GACf,KAAK,iBAAiB,KAAO,CAAE,SAAU,CAAE,EAAE,EAC7C,MAAM,SAAS,CACnB,CAES,aAAoB,CACzB,MAAM,YAAY,EACb,KAAK,KAAK,YACX,KAAK,iBAAiB,CAE9B,CACJ",
6
6
  "names": ["FocusGroupController", "focused", "offset", "el", "getTabIndex", "tabIndex", "removeTabIndex", "updatable"]
7
7
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  import type { ReactiveController, ReactiveElement } from 'lit';
2
13
  import type { SystemVariant } from '@spectrum-web-components/theme';
3
14
  export declare const systemResolverUpdatedSymbol: unique symbol;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["SystemContextResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2024 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport type { SystemVariant } from '@spectrum-web-components/theme';\n\nexport const systemResolverUpdatedSymbol = Symbol('system resolver updated');\n\nexport type ProvideSystem = {\n callback: (system: SystemVariant, unsubscribe: () => void) => void;\n};\n\nexport class SystemResolutionController implements ReactiveController {\n private host: ReactiveElement;\n public system: SystemVariant = 'spectrum';\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveSystem();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveSystem(): void {\n const querySystemEvent = new CustomEvent<ProvideSystem>(\n 'sp-system-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (\n system: SystemVariant,\n unsubscribe: () => void\n ) => {\n const previous = this.system;\n this.system = system;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n systemResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(querySystemEvent);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport type { SystemVariant } from '@spectrum-web-components/theme';\n\nexport const systemResolverUpdatedSymbol = Symbol('system resolver updated');\n\nexport type ProvideSystem = {\n callback: (system: SystemVariant, unsubscribe: () => void) => void;\n};\n\nexport class SystemResolutionController implements ReactiveController {\n private host: ReactiveElement;\n public system: SystemVariant = 'spectrum';\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveSystem();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveSystem(): void {\n const querySystemEvent = new CustomEvent<ProvideSystem>(\n 'sp-system-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (\n system: SystemVariant,\n unsubscribe: () => void\n ) => {\n const previous = this.system;\n this.system = system;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n systemResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(querySystemEvent);\n }\n}\n"],
5
5
  "mappings": ";AAcO,aAAM,8BAA8B,OAAO,yBAAyB;AAMpE,aAAM,2BAAyD;AAAA,EAKlE,YAAY,MAAuB;AAHnC,SAAO,SAAwB;AAI3B,SAAK,OAAO;AACZ,SAAK,KAAK,cAAc,IAAI;AAAA,EAChC;AAAA,EAEO,gBAAsB;AACzB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEO,mBAAyB;AAlCpC;AAmCQ,eAAK,gBAAL;AAAA,EACJ;AAAA,EAEQ,gBAAsB;AAC1B,UAAM,mBAAmB,IAAI;AAAA,MACzB;AAAA,MACA;AAAA,QACI,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,UACJ,UAAU,CACN,QACA,gBACC;AACD,kBAAM,WAAW,KAAK;AACtB,iBAAK,SAAS;AACd,iBAAK,cAAc;AACnB,iBAAK,KAAK;AAAA,cACN;AAAA,cACA;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,QACA,YAAY;AAAA,MAChB;AAAA,IACJ;AACA,SAAK,KAAK,cAAc,gBAAgB;AAAA,EAC5C;AACJ;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["SystemContextResolution.ts"],
4
- "sourcesContent": ["/*\nCopyright 2024 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport type { SystemVariant } from '@spectrum-web-components/theme';\n\nexport const systemResolverUpdatedSymbol = Symbol('system resolver updated');\n\nexport type ProvideSystem = {\n callback: (system: SystemVariant, unsubscribe: () => void) => void;\n};\n\nexport class SystemResolutionController implements ReactiveController {\n private host: ReactiveElement;\n public system: SystemVariant = 'spectrum';\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveSystem();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveSystem(): void {\n const querySystemEvent = new CustomEvent<ProvideSystem>(\n 'sp-system-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (\n system: SystemVariant,\n unsubscribe: () => void\n ) => {\n const previous = this.system;\n this.system = system;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n systemResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(querySystemEvent);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport type { ReactiveController, ReactiveElement } from 'lit';\nimport type { SystemVariant } from '@spectrum-web-components/theme';\n\nexport const systemResolverUpdatedSymbol = Symbol('system resolver updated');\n\nexport type ProvideSystem = {\n callback: (system: SystemVariant, unsubscribe: () => void) => void;\n};\n\nexport class SystemResolutionController implements ReactiveController {\n private host: ReactiveElement;\n public system: SystemVariant = 'spectrum';\n private unsubscribe?: () => void;\n\n constructor(host: ReactiveElement) {\n this.host = host;\n this.host.addController(this);\n }\n\n public hostConnected(): void {\n this.resolveSystem();\n }\n\n public hostDisconnected(): void {\n this.unsubscribe?.();\n }\n\n private resolveSystem(): void {\n const querySystemEvent = new CustomEvent<ProvideSystem>(\n 'sp-system-context',\n {\n bubbles: true,\n composed: true,\n detail: {\n callback: (\n system: SystemVariant,\n unsubscribe: () => void\n ) => {\n const previous = this.system;\n this.system = system;\n this.unsubscribe = unsubscribe;\n this.host.requestUpdate(\n systemResolverUpdatedSymbol,\n previous\n );\n },\n },\n cancelable: true,\n }\n );\n this.host.dispatchEvent(querySystemEvent);\n }\n}\n"],
5
5
  "mappings": "aAcO,aAAM,4BAA8B,OAAO,yBAAyB,EAMpE,aAAM,0BAAyD,CAKlE,YAAYA,EAAuB,CAHnC,KAAO,OAAwB,WAI3B,KAAK,KAAOA,EACZ,KAAK,KAAK,cAAc,IAAI,CAChC,CAEO,eAAsB,CACzB,KAAK,cAAc,CACvB,CAEO,kBAAyB,CAlCpC,IAAAC,GAmCQA,EAAA,KAAK,cAAL,MAAAA,EAAA,UACJ,CAEQ,eAAsB,CAC1B,MAAMC,EAAmB,IAAI,YACzB,oBACA,CACI,QAAS,GACT,SAAU,GACV,OAAQ,CACJ,SAAU,CACNC,EACAC,IACC,CACD,MAAMC,EAAW,KAAK,OACtB,KAAK,OAASF,EACd,KAAK,YAAcC,EACnB,KAAK,KAAK,cACN,4BACAC,CACJ,CACJ,CACJ,EACA,WAAY,EAChB,CACJ,EACA,KAAK,KAAK,cAAcH,CAAgB,CAC5C,CACJ",
6
6
  "names": ["host", "_a", "querySystemEvent", "system", "unsubscribe", "previous"]
7
7
  }
package/src/index.d.ts CHANGED
@@ -1,2 +1,13 @@
1
+ /**
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
1
12
  export * from './MatchMedia.js';
2
13
  export * from './RovingTabindex.js';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["index.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nexport * from './MatchMedia.dev.js'\nexport * from './RovingTabindex.dev.js'\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport * from './MatchMedia.dev.js'\nexport * from './RovingTabindex.dev.js'\n"],
5
5
  "mappings": ";AAYA,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }
package/src/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["index.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nexport * from './MatchMedia.js';\nexport * from './RovingTabindex.js';\n"],
4
+ "sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport * from './MatchMedia.js';\nexport * from './RovingTabindex.js';\n"],
5
5
  "mappings": "aAYA,WAAc,kBACd,WAAc",
6
6
  "names": []
7
7
  }