@m3e/web 2.5.11 → 2.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/all.js +20532 -16074
  2. package/dist/all.js.map +1 -1
  3. package/dist/all.min.js +174 -62
  4. package/dist/all.min.js.map +1 -1
  5. package/dist/autocomplete.js +23 -5
  6. package/dist/autocomplete.js.map +1 -1
  7. package/dist/autocomplete.min.js +1 -1
  8. package/dist/autocomplete.min.js.map +1 -1
  9. package/dist/breadcrumb.js +1 -1
  10. package/dist/breadcrumb.js.map +1 -1
  11. package/dist/breadcrumb.min.js +1 -1
  12. package/dist/breadcrumb.min.js.map +1 -1
  13. package/dist/calendar.js +45 -9
  14. package/dist/calendar.js.map +1 -1
  15. package/dist/calendar.min.js +5 -5
  16. package/dist/calendar.min.js.map +1 -1
  17. package/dist/core-anchoring.js +19 -16
  18. package/dist/core-anchoring.js.map +1 -1
  19. package/dist/core-anchoring.min.js +1 -1
  20. package/dist/core-anchoring.min.js.map +1 -1
  21. package/dist/core.js +122 -105
  22. package/dist/core.js.map +1 -1
  23. package/dist/core.min.js +1 -1
  24. package/dist/core.min.js.map +1 -1
  25. package/dist/css-custom-data.json +50 -50
  26. package/dist/custom-elements.json +1626 -968
  27. package/dist/datepicker.js +53 -27
  28. package/dist/datepicker.js.map +1 -1
  29. package/dist/datepicker.min.js +1 -1
  30. package/dist/datepicker.min.js.map +1 -1
  31. package/dist/fab-menu.js +115 -113
  32. package/dist/fab-menu.js.map +1 -1
  33. package/dist/fab-menu.min.js +1 -1
  34. package/dist/fab-menu.min.js.map +1 -1
  35. package/dist/fab.js +1 -1
  36. package/dist/fab.js.map +1 -1
  37. package/dist/fab.min.js +1 -1
  38. package/dist/fab.min.js.map +1 -1
  39. package/dist/form-field.js +10 -7
  40. package/dist/form-field.js.map +1 -1
  41. package/dist/form-field.min.js +2 -2
  42. package/dist/form-field.min.js.map +1 -1
  43. package/dist/html-custom-data.json +29 -14
  44. package/dist/icon.js +1 -1
  45. package/dist/icon.js.map +1 -1
  46. package/dist/icon.min.js +1 -1
  47. package/dist/icon.min.js.map +1 -1
  48. package/dist/menu.js +26 -19
  49. package/dist/menu.js.map +1 -1
  50. package/dist/menu.min.js +1 -1
  51. package/dist/menu.min.js.map +1 -1
  52. package/dist/option.js +12 -2
  53. package/dist/option.js.map +1 -1
  54. package/dist/option.min.js +1 -1
  55. package/dist/option.min.js.map +1 -1
  56. package/dist/select.js +18 -2
  57. package/dist/select.js.map +1 -1
  58. package/dist/select.min.js +1 -1
  59. package/dist/select.min.js.map +1 -1
  60. package/dist/src/autocomplete/AutocompleteElement.d.ts.map +1 -1
  61. package/dist/src/calendar/CalendarElement.d.ts +2 -0
  62. package/dist/src/calendar/CalendarElement.d.ts.map +1 -1
  63. package/dist/src/calendar/CalendarViewElementBase.d.ts +2 -0
  64. package/dist/src/calendar/CalendarViewElementBase.d.ts.map +1 -1
  65. package/dist/src/calendar/MonthViewElement.d.ts +1 -0
  66. package/dist/src/calendar/MonthViewElement.d.ts.map +1 -1
  67. package/dist/src/calendar/MultiYearViewElement.d.ts.map +1 -1
  68. package/dist/src/calendar/YearViewElement.d.ts.map +1 -1
  69. package/dist/src/core/anchoring/FloatingPanelElement.d.ts.map +1 -1
  70. package/dist/src/core/shared/controllers/ClickOutsideController.d.ts +24 -0
  71. package/dist/src/core/shared/controllers/ClickOutsideController.d.ts.map +1 -0
  72. package/dist/src/core/shared/controllers/FocusController.d.ts +5 -11
  73. package/dist/src/core/shared/controllers/FocusController.d.ts.map +1 -1
  74. package/dist/src/core/shared/controllers/HoverController.d.ts +2 -8
  75. package/dist/src/core/shared/controllers/HoverController.d.ts.map +1 -1
  76. package/dist/src/core/shared/controllers/IntersectionController.d.ts +2 -8
  77. package/dist/src/core/shared/controllers/IntersectionController.d.ts.map +1 -1
  78. package/dist/src/core/shared/controllers/LongPressController.d.ts +2 -8
  79. package/dist/src/core/shared/controllers/LongPressController.d.ts.map +1 -1
  80. package/dist/src/core/shared/controllers/MonitorControllerBase.d.ts +4 -0
  81. package/dist/src/core/shared/controllers/MonitorControllerBase.d.ts.map +1 -1
  82. package/dist/src/core/shared/controllers/PressedController.d.ts +6 -8
  83. package/dist/src/core/shared/controllers/PressedController.d.ts.map +1 -1
  84. package/dist/src/core/shared/controllers/ResizeController.d.ts +2 -8
  85. package/dist/src/core/shared/controllers/ResizeController.d.ts.map +1 -1
  86. package/dist/src/core/shared/controllers/index.d.ts +1 -0
  87. package/dist/src/core/shared/controllers/index.d.ts.map +1 -1
  88. package/dist/src/core/shared/mixins/LinkButton.d.ts.map +1 -1
  89. package/dist/src/core/shared/tokens/DesignToken.d.ts +3 -0
  90. package/dist/src/core/shared/tokens/DesignToken.d.ts.map +1 -1
  91. package/dist/src/core/shared/tokens/MeasurementToken.d.ts +13 -7
  92. package/dist/src/core/shared/tokens/MeasurementToken.d.ts.map +1 -1
  93. package/dist/src/datepicker/DatepickerElement.d.ts +1 -2
  94. package/dist/src/datepicker/DatepickerElement.d.ts.map +1 -1
  95. package/dist/src/fab-menu/FabMenuElement.d.ts.map +1 -1
  96. package/dist/src/form-field/FormFieldElement.d.ts +1 -0
  97. package/dist/src/form-field/FormFieldElement.d.ts.map +1 -1
  98. package/dist/src/menu/MenuElement.d.ts.map +1 -1
  99. package/dist/src/option/OptionElement.d.ts.map +1 -1
  100. package/dist/src/option/OptionPanelElement.d.ts.map +1 -1
  101. package/dist/src/select/SelectElement.d.ts.map +1 -1
  102. package/dist/src/theme/ThemeElement.d.ts.map +1 -1
  103. package/dist/src/tooltip/RichTooltipElement.d.ts +0 -2
  104. package/dist/src/tooltip/RichTooltipElement.d.ts.map +1 -1
  105. package/dist/theme.js +10 -7
  106. package/dist/theme.js.map +1 -1
  107. package/dist/theme.min.js +6 -6
  108. package/dist/theme.min.js.map +1 -1
  109. package/dist/tooltip.js +24 -25
  110. package/dist/tooltip.js.map +1 -1
  111. package/dist/tooltip.min.js +1 -1
  112. package/dist/tooltip.min.js.map +1 -1
  113. package/package.json +1 -1
package/dist/icon.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","sources":["../../src/icon/IconRegistry.ts","../../src/icon/IconElement.ts","../../src/icon/registerIcon.ts"],"sourcesContent":["import { svg, SVGTemplateResult } from \"lit\";\r\n\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\n/** @private */ const PATH_DATA_PATTERN = /^[MmLlHhVvCcSsQqTtAaZz0-9.,\\s-]+$/;\r\n/** @private */ const VIEW_BOX_PATTERN = /^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$/;\r\n\r\n/** Encapsulates information used to construct an SVG. */\r\nexport type SvgIconInfo = {\r\n /** The viewbox of the SVG. */\r\n viewBox: string;\r\n\r\n /** The path of the SVG. */\r\n path: string;\r\n};\r\n\r\n/** Represents the fill-axis SVG data for a single icon. */\r\nexport type SvgIconFillSet = {\r\n /** The unfilled (FILL=0) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n outlined: SvgIconInfo | string;\r\n\r\n /** The filled (FILL=1) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n filled: SvgIconInfo | string;\r\n};\r\n\r\n/**\r\n * Service to register and display icons used by the `m3e-icon` component.\r\n * @internal\r\n */\r\nexport class IconRegistry {\r\n /** @private */\r\n static readonly #icons = new Map<string, { outlined: SVGTemplateResult; filled: SVGTemplateResult }>();\r\n\r\n /** @private */ static readonly #observers = new Map<string, Array<() => void>>();\r\n\r\n /**\r\n * Adds an icon to the registry for the given variant and weight.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {SvgIconFillSet} fillSet The SVG data for both fill states (outlined and filled) of the icon.\r\n */\r\n static addIcon(name: string, variant: IconVariant, fillSet: SvgIconFillSet): void {\r\n const trustOutlinedViewBox = typeof fillSet.outlined === \"string\";\r\n const trustFilledViewBox = typeof fillSet.filled === \"string\";\r\n\r\n if (typeof fillSet.outlined === \"string\") {\r\n fillSet.outlined = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.outlined,\r\n };\r\n }\r\n if (typeof fillSet.filled === \"string\") {\r\n fillSet.filled = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.filled,\r\n };\r\n }\r\n\r\n this.#validateSvgIconInfo(name, variant, fillSet.outlined, trustOutlinedViewBox);\r\n this.#validateSvgIconInfo(name, variant, fillSet.filled, trustFilledViewBox);\r\n\r\n if (window !== undefined) {\r\n const key = this.#createKey(name, variant);\r\n this.#icons.set(key, {\r\n outlined: svg`<svg viewBox=\"${fillSet.outlined.viewBox}\"><path d=\"${fillSet.outlined.path}\"/></svg>`,\r\n filled: svg`<svg viewBox=\"${fillSet.filled.viewBox}\"><path d=\"${fillSet.filled.path}\"/></svg>`,\r\n });\r\n\r\n this.#observers.get(key)?.forEach((x) => x());\r\n }\r\n }\r\n\r\n /**\r\n * Determines whether an icon is registered for the given variant.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @returns {boolean} Whether `icon` is registered for the given `variant`.\r\n */\r\n static isIconRegistered(name: string, variant: IconVariant): boolean {\r\n return window !== undefined && this.#icons.has(this.#createKey(name, variant));\r\n }\r\n\r\n /**\r\n * Renders an icon from the registry.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {boolean} filled Whether to render a filled variant of the icon.\r\n * @returns {SVGTemplateResult | undefined} A `SVGTemplateResult` used to render the icon.\r\n */\r\n static renderIcon(name: string, variant: IconVariant, filled: boolean): SVGTemplateResult | undefined {\r\n const data = this.#icons.get(this.#createKey(name, variant));\r\n return filled ? data?.filled : data?.outlined;\r\n }\r\n\r\n /**\r\n * Begins observing registration for the specified icon.\r\n * @param {string} name The name of the icon to observe.\r\n * @param {IconVariant} variant The variant of the icon to observe.\r\n * @param {() => void} callback Callback invoked when the specified icon is registered for the given variant.\r\n * @returns {() => void} Function used to stop observing.\r\n */\r\n static observe(name: string, variant: IconVariant, callback: () => void): () => void {\r\n if (window === undefined) return () => {};\r\n\r\n const key = this.#createKey(name, variant);\r\n if (!this.#observers.has(key)) {\r\n this.#observers.set(key, [callback]);\r\n } else {\r\n this.#observers.get(key)?.push(callback);\r\n }\r\n\r\n return () => {\r\n const callbacks = this.#observers.get(key);\r\n if (callbacks) {\r\n const index = callbacks.indexOf(callback);\r\n if (index >= 0) {\r\n callbacks.splice(index, 1);\r\n }\r\n if (callbacks.length == 0) {\r\n this.#observers.delete(key);\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** @private */\r\n static #createKey(name: string, variant: IconVariant): string {\r\n return `${variant}-${name}`;\r\n }\r\n\r\n /** @private */\r\n static #validateSvgIconInfo(name: string, variant: IconVariant, info: SvgIconInfo, trustViewBox = false): void {\r\n if (!trustViewBox && !VIEW_BOX_PATTERN.test(info.viewBox)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid viewbox data.`);\r\n }\r\n if (!PATH_DATA_PATTERN.test(info.path)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid path data.`);\r\n }\r\n }\r\n}\r\n","import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport { customElement, Role } from \"@m3e/web/core\";\r\n\r\nimport { IconRegistry } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\nimport { IconGrade } from \"./IconGrade\";\r\nimport { IconWeight } from \"./IconWeight\";\r\n\r\n/**\r\n * A small symbol used to easily identify an action or category.\r\n *\r\n * @description\r\n * The `m3e-icon` component makes it easier to use Material Symbols in your application. Material Symbols are Google's newest icons supporting\r\n * a range of design variants. For more information, see:\r\n * - {@link https://developers.google.com/fonts/docs/material_symbols|Material Symbol Guide}\r\n * - {@link https://fonts.google.com/icons|Material Symbol Library}\r\n *\r\n * The Material Symbols font is the easiest way to incorporate Material Symbols into your application. Using the\r\n * {@link https://developers.google.com/fonts/docs/css2#forming_api_urls|Fonts CSS API}, you can use variable fonts to optimize icon\r\n * usage within your application. See {@link https://caniuse.com/variable-fonts|Can I Use's Variable Fonts} to determine whether\r\n * your user's browser support variable fonts.\r\n *\r\n * @example\r\n * The following example illustrates showing the `home` icon. The `name` attribute specifies the icon to present.\r\n * ```html\r\n * <m3e-icon name=\"home\"></m3e-icon>\r\n * ```\r\n * @example\r\n * The next example illustrates a link used to download a variable font for outlined icons with fill support.\r\n * ```html\r\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0\" rel=\"stylesheet\"/>\r\n * ```\r\n *\r\n * @tag m3e-icon\r\n *\r\n * @attr filled - Whether the icon is filled.\r\n * @attr grade - The grade of the icon.\r\n * @attr optical-size - A value from 20 to 48 indicating the optical size of the icon.\r\n * @attr name - The name of the icon.\r\n * @attr variant - The appearance variant of the icon.\r\n * @attr weight - A value from 100 to 700 indicating the weight of the icon.\r\n */\r\n@customElement(\"m3e-icon\")\r\nexport class M3eIconElement extends Role(LitElement, \"img\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-block;\r\n user-select: none;\r\n font-size: var(--m3e-icon-size, 1.5rem);\r\n width: 1em;\r\n height: 1em;\r\n vertical-align: middle;\r\n overflow: hidden;\r\n }\r\n .icon {\r\n font-weight: normal;\r\n font-style: normal;\r\n line-height: 1;\r\n letter-spacing: normal;\r\n text-transform: none;\r\n white-space: nowrap;\r\n word-wrap: normal;\r\n direction: ltr;\r\n font-feature-settings: \"liga\";\r\n -webkit-font-smoothing: antialiased;\r\n width: inherit;\r\n height: inherit;\r\n vertical-align: inherit;\r\n font-variation-settings:\r\n \"FILL\" var(--_icon-fill, 0),\r\n \"wght\" var(--_icon-weight, 400),\r\n \"GRAD\" var(--_icon-grade, 0),\r\n \"opsz\" var(--_icon-optical-size, 24);\r\n }\r\n :host([variant=\"outlined\"]) .icon {\r\n font-family: \"Material Symbols Outlined\";\r\n }\r\n :host([variant=\"rounded\"]) .icon {\r\n font-family: \"Material Symbols Rounded\";\r\n }\r\n :host([variant=\"sharp\"]) .icon {\r\n font-family: \"Material Symbols Sharp\";\r\n }\r\n svg {\r\n fill: currentColor;\r\n font-size: inherit;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n `;\r\n\r\n /** @private */ @query(\".icon\") private readonly _icon?: HTMLSpanElement;\r\n /** @private */ #iconRegistryUnobserve?: () => void;\r\n\r\n /** The name of the icon. */\r\n @property() name: string = \"\";\r\n\r\n /**\r\n * The appearance variant of the icon.\r\n * @default \"outlined\"\r\n */\r\n @property({ reflect: true }) variant: IconVariant = \"outlined\";\r\n\r\n /**\r\n * Whether the icon is filled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) filled = false;\r\n\r\n /**\r\n * The grade of the icon.\r\n * @default \"medium\"\r\n */\r\n @property() grade: IconGrade = \"medium\";\r\n\r\n /**\r\n * A value from 100 to 700 indicating the weight of the icon.\r\n * @default 400\r\n */\r\n @property({ type: Number }) weight: IconWeight = 400;\r\n\r\n /**\r\n * A value from 20 to 48 indicating the optical size of the icon.\r\n * @default 24\r\n */\r\n @property({ attribute: \"optical-size\", type: Number }) opticalSize = 24;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n if (\r\n !this.hasAttribute(\"aria-label\") &&\r\n !this.hasAttribute(\"aria-labelledby\") &&\r\n !this.hasAttribute(\"aria-hidden\")\r\n ) {\r\n this.ariaHidden = \"true\";\r\n }\r\n\r\n super.connectedCallback();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.#iconRegistryUnobserve?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override willUpdate(_changedProperties: PropertyValues<this>): void {\r\n super.willUpdate(_changedProperties);\r\n\r\n if (_changedProperties.has(\"name\") && !IconRegistry.isIconRegistered(this.name, this.variant)) {\r\n this.#iconRegistryUnobserve = IconRegistry.observe(this.name, this.variant, () => {\r\n this.requestUpdate();\r\n this.#iconRegistryUnobserve?.();\r\n this.#iconRegistryUnobserve = undefined;\r\n });\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override updated(_changedProperties: PropertyValues<this>): void {\r\n super.updated(_changedProperties);\r\n\r\n if (_changedProperties.has(\"filled\")) {\r\n this._icon?.style.setProperty(\"--_icon-fill\", this.filled ? \"1\" : \"0\");\r\n }\r\n if (_changedProperties.has(\"grade\")) {\r\n this._icon?.style.setProperty(\r\n \"--_icon-grade\",\r\n this.grade === \"low\" ? \"-25\" : this.grade === \"high\" ? \"200\" : \"0\",\r\n );\r\n }\r\n if (_changedProperties.has(\"weight\")) {\r\n this._icon?.style.setProperty(\"--_icon-weight\", `${this.weight}`);\r\n }\r\n if (_changedProperties.has(\"opticalSize\")) {\r\n this._icon?.style.setProperty(\"--_icon-optical-size\", `${this.opticalSize}`);\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return IconRegistry.isIconRegistered(this.name, this.variant)\r\n ? IconRegistry.renderIcon(this.name, this.variant, this.filled)\r\n : html`<div class=\"icon\" aria-hidden=\"true\">${this.name}</div>`;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-icon\": M3eIconElement;\r\n }\r\n}\r\n","import { IconRegistry, SvgIconInfo } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\nexport type { SvgIconInfo } from \"./IconRegistry\";\r\n\r\n/**\r\n * Registers an SVG icon to the internal icon registry used by `m3e-icon`.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param data The outlined and filled SVG information of the icon.\r\n */\r\nexport function registerIcon(\r\n name: string,\r\n variant: IconVariant,\r\n data: { outlined: SvgIconInfo; filled: SvgIconInfo },\r\n): void {\r\n IconRegistry.addIcon(name, variant, data);\r\n}\r\n"],"names":["PATH_DATA_PATTERN","VIEW_BOX_PATTERN","IconRegistry","addIcon","name","variant","fillSet","trustOutlinedViewBox","outlined","trustFilledViewBox","filled","viewBox","path","__classPrivateFieldGet","_a","_IconRegistry_validateSvgIconInfo","call","window","undefined","key","_IconRegistry_createKey","_IconRegistry_icons","set","svg","_IconRegistry_observers","get","forEach","x","isIconRegistered","has","renderIcon","data","observe","callback","push","callbacks","index","indexOf","splice","length","delete","info","trustViewBox","test","Error","value","Map","M3eIconElement","Role","LitElement","constructor","_M3eIconElement_iconRegistryUnobserve","grade","weight","opticalSize","connectedCallback","hasAttribute","ariaHidden","disconnectedCallback","willUpdate","_changedProperties","__classPrivateFieldSet","requestUpdate","updated","_icon","style","setProperty","render","html","styles","css","__decorate","query","prototype","property","reflect","type","Boolean","Number","attribute","customElement","registerIcon"],"mappings":";;;;;;;;;;;AAIA;AAAgB,MAAMA,iBAAiB,GAAG,mCAAmC;AAC7E;AAAgB,MAAMC,gBAAgB,GAAG,iEAAiE;AAoB1G;;;AAGG;MACUC,YAAY,CAAA;AAMvB;;;;;AAKG;AACH,EAAA,OAAOC,OAAOA,CAACC,IAAY,EAAEC,OAAoB,EAAEC,OAAuB,EAAA;AACxE,IAAA,MAAMC,oBAAoB,GAAG,OAAOD,OAAO,CAACE,QAAQ,KAAK,QAAQ;AACjE,IAAA,MAAMC,kBAAkB,GAAG,OAAOH,OAAO,CAACI,MAAM,KAAK,QAAQ;AAE7D,IAAA,IAAI,OAAOJ,OAAO,CAACE,QAAQ,KAAK,QAAQ,EAAE;MACxCF,OAAO,CAACE,QAAQ,GAAG;AACjBG,QAAAA,OAAO,EAAE,gBAAgB;QACzBC,IAAI,EAAEN,OAAO,CAACE;OACf;AACH,IAAA;AACA,IAAA,IAAI,OAAOF,OAAO,CAACI,MAAM,KAAK,QAAQ,EAAE;MACtCJ,OAAO,CAACI,MAAM,GAAG;AACfC,QAAAA,OAAO,EAAE,gBAAgB;QACzBC,IAAI,EAAEN,OAAO,CAACI;OACf;AACH,IAAA;IAEAG,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAC,iCAAA,CAAqB,CAAAC,IAAA,CAAzB,IAAI,EAAsBZ,IAAI,EAAEC,OAAO,EAAEC,OAAO,CAACE,QAAQ,EAAED,oBAAoB,CAAC;IAChFM,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAC,iCAAA,CAAqB,CAAAC,IAAA,CAAzB,IAAI,EAAsBZ,IAAI,EAAEC,OAAO,EAAEC,OAAO,CAACI,MAAM,EAAED,kBAAkB,CAAC;IAE5E,IAAIQ,MAAM,KAAKC,SAAS,EAAE;MACxB,MAAMC,GAAG,GAAGN,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAM,uBAAA,CAAW,CAAAJ,IAAA,CAAf,IAAI,EAAYZ,IAAI,EAAEC,OAAO,CAAC;AAC1CQ,MAAAA,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAO,mBAAA,CAAO,CAACC,GAAG,CAACH,GAAG,EAAE;AACnBX,QAAAA,QAAQ,EAAEe,GAAG,CAAA,cAAA,EAAiBjB,OAAO,CAACE,QAAQ,CAACG,OAAO,CAAA,WAAA,EAAcL,OAAO,CAACE,QAAQ,CAACI,IAAI,CAAA,SAAA,CAAW;AACpGF,QAAAA,MAAM,EAAEa,GAAG,CAAA,cAAA,EAAiBjB,OAAO,CAACI,MAAM,CAACC,OAAO,CAAA,WAAA,EAAcL,OAAO,CAACI,MAAM,CAACE,IAAI,CAAA,SAAA;AACpF,OAAA,CAAC;MAEFC,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACC,GAAG,CAACN,GAAG,CAAC,EAAEO,OAAO,CAAEC,CAAC,IAAKA,CAAC,EAAE,CAAC;AAC/C,IAAA;AACF,EAAA;AAEA;;;;;AAKG;AACH,EAAA,OAAOC,gBAAgBA,CAACxB,IAAY,EAAEC,OAAoB,EAAA;AACxD,IAAA,OAAOY,MAAM,KAAKC,SAAS,IAAIL,uBAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAO,mBAAA,CAAO,CAACQ,GAAG,CAAChB,uBAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAM,uBAAA,CAAW,MAAf,IAAI,EAAYhB,IAAI,EAAEC,OAAO,CAAC,CAAC;AAChF,EAAA;AAEA;;;;;;AAMG;AACH,EAAA,OAAOyB,UAAUA,CAAC1B,IAAY,EAAEC,OAAoB,EAAEK,MAAe,EAAA;AACnE,IAAA,MAAMqB,IAAI,GAAGlB,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAO,mBAAA,CAAO,CAACI,GAAG,CAACZ,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAM,uBAAA,CAAW,CAAAJ,IAAA,CAAf,IAAI,EAAYZ,IAAI,EAAEC,OAAO,CAAC,CAAC;IAC5D,OAAOK,MAAM,GAAGqB,IAAI,EAAErB,MAAM,GAAGqB,IAAI,EAAEvB,QAAQ;AAC/C,EAAA;AAEA;;;;;;AAMG;AACH,EAAA,OAAOwB,OAAOA,CAAC5B,IAAY,EAAEC,OAAoB,EAAE4B,QAAoB,EAAA;AACrE,IAAA,IAAIhB,MAAM,KAAKC,SAAS,EAAE,OAAO,MAAK,CAAE,CAAC;IAEzC,MAAMC,GAAG,GAAGN,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAM,uBAAA,CAAW,CAAAJ,IAAA,CAAf,IAAI,EAAYZ,IAAI,EAAEC,OAAO,CAAC;AAC1C,IAAA,IAAI,CAACQ,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACK,GAAG,CAACV,GAAG,CAAC,EAAE;AAC7BN,MAAAA,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACF,GAAG,CAACH,GAAG,EAAE,CAACc,QAAQ,CAAC,CAAC;AACtC,IAAA,CAAC,MAAM;AACLpB,MAAAA,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACC,GAAG,CAACN,GAAG,CAAC,EAAEe,IAAI,CAACD,QAAQ,CAAC;AAC1C,IAAA;AAEA,IAAA,OAAO,MAAK;AACV,MAAA,MAAME,SAAS,GAAGtB,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACC,GAAG,CAACN,GAAG,CAAC;AAC1C,MAAA,IAAIgB,SAAS,EAAE;AACb,QAAA,MAAMC,KAAK,GAAGD,SAAS,CAACE,OAAO,CAACJ,QAAQ,CAAC;QACzC,IAAIG,KAAK,IAAI,CAAC,EAAE;AACdD,UAAAA,SAAS,CAACG,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC;AAC5B,QAAA;AACA,QAAA,IAAID,SAAS,CAACI,MAAM,IAAI,CAAC,EAAE;AACzB1B,UAAAA,sBAAA,CAAA,IAAI,EAAAC,EAAA,EAAA,GAAA,EAAAU,uBAAA,CAAW,CAACgB,MAAM,CAACrB,GAAG,CAAC;AAC7B,QAAA;AACF,MAAA;IACF,CAAC;AACH,EAAA;;AAGkBL,EAAA,GAAAZ,YAAA,EAAAkB,uBAAA,GAAA,SAAAA,uBAAAA,CAAAhB,IAAY,EAAEC,OAAoB,EAAA;AAClD,EAAA,OAAO,CAAA,EAAGA,OAAO,CAAA,CAAA,EAAID,IAAI,CAAA,CAAE;AAC7B,CAAC,EAAAW,iCAAA,GAAA,SAAAA,iCAAAA,CAG2BX,IAAY,EAAEC,OAAoB,EAAEoC,IAAiB,EAAEC,YAAY,GAAG,KAAK,EAAA;AACrG,EAAA,IAAI,CAACA,YAAY,IAAI,CAACzC,gBAAgB,CAAC0C,IAAI,CAACF,IAAI,CAAC9B,OAAO,CAAC,EAAE;IACzD,MAAM,IAAIiC,KAAK,CAAC,CAAA,yBAAA,EAA4BxC,IAAI,CAAA,eAAA,EAAkBC,OAAO,0BAA0B,CAAC;AACtG,EAAA;EACA,IAAI,CAACL,iBAAiB,CAAC2C,IAAI,CAACF,IAAI,CAAC7B,IAAI,CAAC,EAAE;IACtC,MAAM,IAAIgC,KAAK,CAAC,CAAA,yBAAA,EAA4BxC,IAAI,CAAA,eAAA,EAAkBC,OAAO,uBAAuB,CAAC;AACnG,EAAA;AACF,CAAC;AA5GD;AACgBgB,mBAAA,GAAA;EAAAwB,KAAA,EAAS,IAAIC,GAAG;AAAsE,CAAhF;AAEtB;AAAgCtB,uBAAA,GAAA;EAAAqB,KAAA,EAAa,IAAIC,GAAG;CAAV;;;ACvB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCG;AAEI,IAAMC,cAAc,GAApB,MAAMA,cAAe,SAAQC,IAAI,CAACC,UAAU,EAAE,KAAK,CAAC,CAAA;AAApDC,EAAAA,WAAAA,GAAA;;AAkDL;AAAgBC,IAAAA,qCAAA,CAAA7B,GAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAEhB;IACY,IAAA,CAAAlB,IAAI,GAAW,EAAE;AAE7B;;;AAGG;IAC0B,IAAA,CAAAC,OAAO,GAAgB,UAAU;AAE9D;;;AAGG;IACyC,IAAA,CAAAK,MAAM,GAAG,KAAK;AAE1D;;;AAGG;IACS,IAAA,CAAA0C,KAAK,GAAc,QAAQ;AAEvC;;;AAGG;IACyB,IAAA,CAAAC,MAAM,GAAe,GAAG;AAEpD;;;AAGG;IACoD,IAAA,CAAAC,WAAW,GAAG,EAAE;AA8DzE,EAAA;AA5DE;AACSC,EAAAA,iBAAiBA,GAAA;IACxB,IACE,CAAC,IAAI,CAACC,YAAY,CAAC,YAAY,CAAC,IAChC,CAAC,IAAI,CAACA,YAAY,CAAC,iBAAiB,CAAC,IACrC,CAAC,IAAI,CAACA,YAAY,CAAC,aAAa,CAAC,EACjC;MACA,IAAI,CAACC,UAAU,GAAG,MAAM;AAC1B,IAAA;IAEA,KAAK,CAACF,iBAAiB,EAAE;AAC3B,EAAA;AAEA;AACSG,EAAAA,oBAAoBA,GAAA;IAC3B,KAAK,CAACA,oBAAoB,EAAE;IAE5B7C,sBAAA,CAAA,IAAI,EAAAsC,qCAAA,EAAA,GAAA,CAAuB,EAAEnC,IAAA,CAA7B,IAAI,CAA2B;AACjC,EAAA;AAEA;EACmB2C,UAAUA,CAACC,kBAAwC,EAAA;AACpE,IAAA,KAAK,CAACD,UAAU,CAACC,kBAAkB,CAAC;IAEpC,IAAIA,kBAAkB,CAAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC3B,YAAY,CAAC0B,gBAAgB,CAAC,IAAI,CAACxB,IAAI,EAAE,IAAI,CAACC,OAAO,CAAC,EAAE;AAC7FwD,MAAAA,sBAAA,CAAA,IAAI,EAAAV,qCAAA,EAA0BjD,YAAY,CAAC8B,OAAO,CAAC,IAAI,CAAC5B,IAAI,EAAE,IAAI,CAACC,OAAO,EAAE,MAAK;QAC/E,IAAI,CAACyD,aAAa,EAAE;QACpBjD,sBAAA,CAAA,IAAI,EAAAsC,qCAAA,EAAA,GAAA,CAAuB,EAAEnC,IAAA,CAA7B,IAAI,CAA2B;QAC/B6C,sBAAA,CAAA,IAAI,EAAAV,qCAAA,EAA0BjC,SAAS,EAAA,GAAA,CAAA;MACzC,CAAC,CAAC,MAAA;AACJ,IAAA;AACF,EAAA;AAEA;EACmB6C,OAAOA,CAACH,kBAAwC,EAAA;AACjE,IAAA,KAAK,CAACG,OAAO,CAACH,kBAAkB,CAAC;AAEjC,IAAA,IAAIA,kBAAkB,CAAC/B,GAAG,CAAC,QAAQ,CAAC,EAAE;AACpC,MAAA,IAAI,CAACmC,KAAK,EAAEC,KAAK,CAACC,WAAW,CAAC,cAAc,EAAE,IAAI,CAACxD,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC;AACxE,IAAA;AACA,IAAA,IAAIkD,kBAAkB,CAAC/B,GAAG,CAAC,OAAO,CAAC,EAAE;MACnC,IAAI,CAACmC,KAAK,EAAEC,KAAK,CAACC,WAAW,CAC3B,eAAe,EACf,IAAI,CAACd,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,IAAI,CAACA,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,GAAG,CACnE;AACH,IAAA;AACA,IAAA,IAAIQ,kBAAkB,CAAC/B,GAAG,CAAC,QAAQ,CAAC,EAAE;AACpC,MAAA,IAAI,CAACmC,KAAK,EAAEC,KAAK,CAACC,WAAW,CAAC,gBAAgB,EAAE,CAAA,EAAG,IAAI,CAACb,MAAM,EAAE,CAAC;AACnE,IAAA;AACA,IAAA,IAAIO,kBAAkB,CAAC/B,GAAG,CAAC,aAAa,CAAC,EAAE;AACzC,MAAA,IAAI,CAACmC,KAAK,EAAEC,KAAK,CAACC,WAAW,CAAC,sBAAsB,EAAE,CAAA,EAAG,IAAI,CAACZ,WAAW,EAAE,CAAC;AAC9E,IAAA;AACF,EAAA;AAEA;AACmBa,EAAAA,MAAMA,GAAA;AACvB,IAAA,OAAOjE,YAAY,CAAC0B,gBAAgB,CAAC,IAAI,CAACxB,IAAI,EAAE,IAAI,CAACC,OAAO,CAAC,GACzDH,YAAY,CAAC4B,UAAU,CAAC,IAAI,CAAC1B,IAAI,EAAE,IAAI,CAACC,OAAO,EAAE,IAAI,CAACK,MAAM,CAAC,GAC7D0D,IAAI,CAAA,qCAAA,EAAwC,IAAI,CAAChE,IAAI,CAAA,MAAA,CAAQ;AACnE,EAAA;;;AA/IA;AACgB2C,cAAA,CAAAsB,MAAM,GAAmBC,GAAG,CAAA,k5BAAA,CAAtB;AA+C2BC,UAAA,CAAA,CAAhCC,KAAK,CAAC,OAAO,CAAC,CAA0C,EAAAzB,cAAA,CAAA0B,SAAA,EAAA,OAAA,EAAA,MAAA,CAAA;AAI7DF,UAAA,CAAA,CAAXG,QAAQ,EAAE,CAAmB,EAAA3B,cAAA,CAAA0B,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA;AAMDF,UAAA,CAAA,CAA5BG,QAAQ,CAAC;AAAEC,EAAAA,OAAO,EAAE;CAAM,CAAC,CAAmC,EAAA5B,cAAA,CAAA0B,SAAA,EAAA,SAAA,EAAA,MAAA,CAAA;AAMnBF,UAAA,CAAA,CAA3CG,QAAQ,CAAC;AAAEE,EAAAA,IAAI,EAAEC,OAAO;AAAEF,EAAAA,OAAO,EAAE;AAAI,CAAE,CAAC,CAAgB,EAAA5B,cAAA,CAAA0B,SAAA,EAAA,QAAA,EAAA,MAAA,CAAA;AAM/CF,UAAA,CAAA,CAAXG,QAAQ,EAAE,CAA6B,EAAA3B,cAAA,CAAA0B,SAAA,EAAA,OAAA,EAAA,MAAA,CAAA;AAMZF,UAAA,CAAA,CAA3BG,QAAQ,CAAC;AAAEE,EAAAA,IAAI,EAAEE;CAAQ,CAAC,CAA0B,EAAA/B,cAAA,CAAA0B,SAAA,EAAA,QAAA,EAAA,MAAA,CAAA;AAMEF,UAAA,CAAA,CAAtDG,QAAQ,CAAC;AAAEK,EAAAA,SAAS,EAAE,cAAc;AAAEH,EAAAA,IAAI,EAAEE;AAAM,CAAE,CAAC,CAAkB,EAAA/B,cAAA,CAAA0B,SAAA,EAAA,aAAA,EAAA,MAAA,CAAA;AAnF7D1B,cAAc,GAAAwB,UAAA,CAAA,CAD1BS,aAAa,CAAC,UAAU,CAAC,CACb,EAAAjC,cAAc,CAiJ1B;;ACzLD;;;;;AAKG;SACakC,YAAYA,CAC1B7E,IAAY,EACZC,OAAoB,EACpB0B,IAAoD,EAAA;EAEpD7B,YAAY,CAACC,OAAO,CAACC,IAAI,EAAEC,OAAO,EAAE0B,IAAI,CAAC;AAC3C;;;;"}
1
+ {"version":3,"file":"icon.js","sources":["../../src/icon/IconRegistry.ts","../../src/icon/IconElement.ts","../../src/icon/registerIcon.ts"],"sourcesContent":["import { svg, SVGTemplateResult } from \"lit\";\r\n\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\n/** @private */ const PATH_DATA_PATTERN = /^[MmLlHhVvCcSsQqTtAaZz0-9.,\\s-]+$/;\r\n/** @private */ const VIEW_BOX_PATTERN = /^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$/;\r\n\r\n/** Encapsulates information used to construct an SVG. */\r\nexport type SvgIconInfo = {\r\n /** The viewbox of the SVG. */\r\n viewBox: string;\r\n\r\n /** The path of the SVG. */\r\n path: string;\r\n};\r\n\r\n/** Represents the fill-axis SVG data for a single icon. */\r\nexport type SvgIconFillSet = {\r\n /** The unfilled (FILL=0) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n outlined: SvgIconInfo | string;\r\n\r\n /** The filled (FILL=1) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n filled: SvgIconInfo | string;\r\n};\r\n\r\n/**\r\n * Service to register and display icons used by the `m3e-icon` component.\r\n * @internal\r\n */\r\nexport class IconRegistry {\r\n /** @private */\r\n static readonly #icons = new Map<string, { outlined: SVGTemplateResult; filled: SVGTemplateResult }>();\r\n\r\n /** @private */ static readonly #observers = new Map<string, Array<() => void>>();\r\n\r\n /**\r\n * Adds an icon to the registry for the given variant and weight.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {SvgIconFillSet} fillSet The SVG data for both fill states (outlined and filled) of the icon.\r\n */\r\n static addIcon(name: string, variant: IconVariant, fillSet: SvgIconFillSet): void {\r\n const trustOutlinedViewBox = typeof fillSet.outlined === \"string\";\r\n const trustFilledViewBox = typeof fillSet.filled === \"string\";\r\n\r\n if (typeof fillSet.outlined === \"string\") {\r\n fillSet.outlined = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.outlined,\r\n };\r\n }\r\n if (typeof fillSet.filled === \"string\") {\r\n fillSet.filled = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.filled,\r\n };\r\n }\r\n\r\n this.#validateSvgIconInfo(name, variant, fillSet.outlined, trustOutlinedViewBox);\r\n this.#validateSvgIconInfo(name, variant, fillSet.filled, trustFilledViewBox);\r\n\r\n if (window !== undefined) {\r\n const key = this.#createKey(name, variant);\r\n this.#icons.set(key, {\r\n outlined: svg`<svg viewBox=\"${fillSet.outlined.viewBox}\"><path d=\"${fillSet.outlined.path}\"/></svg>`,\r\n filled: svg`<svg viewBox=\"${fillSet.filled.viewBox}\"><path d=\"${fillSet.filled.path}\"/></svg>`,\r\n });\r\n\r\n this.#observers.get(key)?.forEach((x) => x());\r\n }\r\n }\r\n\r\n /**\r\n * Determines whether an icon is registered for the given variant.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @returns {boolean} Whether `icon` is registered for the given `variant`.\r\n */\r\n static isIconRegistered(name: string, variant: IconVariant): boolean {\r\n return window !== undefined && this.#icons.has(this.#createKey(name, variant));\r\n }\r\n\r\n /**\r\n * Renders an icon from the registry.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {boolean} filled Whether to render a filled variant of the icon.\r\n * @returns {SVGTemplateResult | undefined} A `SVGTemplateResult` used to render the icon.\r\n */\r\n static renderIcon(name: string, variant: IconVariant, filled: boolean): SVGTemplateResult | undefined {\r\n const data = this.#icons.get(this.#createKey(name, variant));\r\n return filled ? data?.filled : data?.outlined;\r\n }\r\n\r\n /**\r\n * Begins observing registration for the specified icon.\r\n * @param {string} name The name of the icon to observe.\r\n * @param {IconVariant} variant The variant of the icon to observe.\r\n * @param {() => void} callback Callback invoked when the specified icon is registered for the given variant.\r\n * @returns {() => void} Function used to stop observing.\r\n */\r\n static observe(name: string, variant: IconVariant, callback: () => void): () => void {\r\n if (window === undefined) return () => {};\r\n\r\n const key = this.#createKey(name, variant);\r\n if (!this.#observers.has(key)) {\r\n this.#observers.set(key, [callback]);\r\n } else {\r\n this.#observers.get(key)?.push(callback);\r\n }\r\n\r\n return () => {\r\n const callbacks = this.#observers.get(key);\r\n if (callbacks) {\r\n const index = callbacks.indexOf(callback);\r\n if (index >= 0) {\r\n callbacks.splice(index, 1);\r\n }\r\n if (callbacks.length == 0) {\r\n this.#observers.delete(key);\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** @private */\r\n static #createKey(name: string, variant: IconVariant): string {\r\n return `${variant}-${name}`;\r\n }\r\n\r\n /** @private */\r\n static #validateSvgIconInfo(name: string, variant: IconVariant, info: SvgIconInfo, trustViewBox = false): void {\r\n if (!trustViewBox && !VIEW_BOX_PATTERN.test(info.viewBox)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid viewbox data.`);\r\n }\r\n if (!PATH_DATA_PATTERN.test(info.path)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid path data.`);\r\n }\r\n }\r\n}\r\n","import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport { customElement, Role } from \"@m3e/web/core\";\r\n\r\nimport { IconRegistry } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\nimport { IconGrade } from \"./IconGrade\";\r\nimport { IconWeight } from \"./IconWeight\";\r\n\r\n/**\r\n * A small symbol used to easily identify an action or category.\r\n *\r\n * @description\r\n * The `m3e-icon` component makes it easier to use Material Symbols in your application. Material Symbols are Google's newest icons supporting\r\n * a range of design variants. For more information, see:\r\n * - {@link https://developers.google.com/fonts/docs/material_symbols|Material Symbol Guide}\r\n * - {@link https://fonts.google.com/icons|Material Symbol Library}\r\n *\r\n * The Material Symbols font is the easiest way to incorporate Material Symbols into your application. Using the\r\n * {@link https://developers.google.com/fonts/docs/css2#forming_api_urls|Fonts CSS API}, you can use variable fonts to optimize icon\r\n * usage within your application. See {@link https://caniuse.com/variable-fonts|Can I Use's Variable Fonts} to determine whether\r\n * your user's browser support variable fonts.\r\n *\r\n * @example\r\n * The following example illustrates showing the `home` icon. The `name` attribute specifies the icon to present.\r\n * ```html\r\n * <m3e-icon name=\"home\"></m3e-icon>\r\n * ```\r\n * @example\r\n * The next example illustrates a link used to download a variable font for outlined icons with fill support.\r\n * ```html\r\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0\" rel=\"stylesheet\"/>\r\n * ```\r\n *\r\n * @tag m3e-icon\r\n *\r\n * @attr filled - Whether the icon is filled.\r\n * @attr grade - The grade of the icon.\r\n * @attr optical-size - A value from 20 to 48 indicating the optical size of the icon.\r\n * @attr name - The name of the icon.\r\n * @attr variant - The appearance variant of the icon.\r\n * @attr weight - A value from 100 to 700 indicating the weight of the icon.\r\n */\r\n@customElement(\"m3e-icon\")\r\nexport class M3eIconElement extends Role(LitElement, \"img\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-block;\r\n user-select: none;\r\n font-size: var(--m3e-icon-size, 1.5rem);\r\n width: 1em;\r\n height: 1em;\r\n vertical-align: middle;\r\n overflow: hidden;\r\n }\r\n .icon {\r\n font-weight: normal;\r\n font-style: normal;\r\n line-height: 1;\r\n letter-spacing: normal;\r\n text-transform: none;\r\n white-space: nowrap;\r\n word-wrap: normal;\r\n direction: ltr;\r\n font-feature-settings: \"liga\";\r\n -webkit-font-smoothing: antialiased;\r\n width: inherit;\r\n height: inherit;\r\n vertical-align: inherit;\r\n font-variation-settings:\r\n \"FILL\" var(--_icon-fill, 0),\r\n \"wght\" var(--_icon-weight, 400),\r\n \"GRAD\" var(--_icon-grade, 0),\r\n \"opsz\" var(--_icon-optical-size, 24);\r\n }\r\n :host([variant=\"outlined\"]) .icon {\r\n font-family: \"Material Symbols Outlined\";\r\n }\r\n :host([variant=\"rounded\"]) .icon {\r\n font-family: \"Material Symbols Rounded\";\r\n }\r\n :host([variant=\"sharp\"]) .icon {\r\n font-family: \"Material Symbols Sharp\";\r\n }\r\n svg {\r\n fill: currentColor;\r\n font-size: inherit;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n `;\r\n\r\n /** @private */ @query(\".icon\") private readonly _icon?: HTMLSpanElement;\r\n /** @private */ #iconRegistryUnobserve?: () => void;\r\n\r\n /** The name of the icon. */\r\n @property() name: string = \"\";\r\n\r\n /**\r\n * The appearance variant of the icon.\r\n * @default \"outlined\"\r\n */\r\n @property({ reflect: true }) variant: IconVariant = \"outlined\";\r\n\r\n /**\r\n * Whether the icon is filled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) filled = false;\r\n\r\n /**\r\n * The grade of the icon.\r\n * @default \"medium\"\r\n */\r\n @property() grade: IconGrade = \"medium\";\r\n\r\n /**\r\n * A value from 100 to 700 indicating the weight of the icon.\r\n * @default 400\r\n */\r\n @property({ type: Number }) weight: IconWeight = 400;\r\n\r\n /**\r\n * A value from 20 to 48 indicating the optical size of the icon.\r\n * @default 24\r\n */\r\n @property({ attribute: \"optical-size\", type: Number }) opticalSize = 24;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n if (\r\n !this.hasAttribute(\"aria-label\") &&\r\n !this.hasAttribute(\"aria-labelledby\") &&\r\n !this.hasAttribute(\"aria-hidden\")\r\n ) {\r\n this.ariaHidden = \"true\";\r\n }\r\n\r\n super.connectedCallback();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.#iconRegistryUnobserve?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override willUpdate(_changedProperties: PropertyValues<this>): void {\r\n super.willUpdate(_changedProperties);\r\n\r\n if (_changedProperties.has(\"name\") && !IconRegistry.isIconRegistered(this.name, this.variant)) {\r\n this.#iconRegistryUnobserve = IconRegistry.observe(this.name, this.variant, () => {\r\n this.requestUpdate();\r\n this.#iconRegistryUnobserve?.();\r\n this.#iconRegistryUnobserve = undefined;\r\n });\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override updated(_changedProperties: PropertyValues<this>): void {\r\n super.updated(_changedProperties);\r\n\r\n if (_changedProperties.has(\"filled\")) {\r\n this._icon?.style.setProperty(\"--_icon-fill\", this.filled ? \"1\" : \"0\");\r\n }\r\n if (_changedProperties.has(\"grade\")) {\r\n this._icon?.style.setProperty(\r\n \"--_icon-grade\",\r\n this.grade === \"low\" ? \"-25\" : this.grade === \"high\" ? \"200\" : \"0\",\r\n );\r\n }\r\n if (_changedProperties.has(\"weight\")) {\r\n this._icon?.style.setProperty(\"--_icon-weight\", `${this.weight}`);\r\n }\r\n if (_changedProperties.has(\"opticalSize\")) {\r\n this._icon?.style.setProperty(\"--_icon-optical-size\", `${this.opticalSize}`);\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return IconRegistry.isIconRegistered(this.name, this.variant)\r\n ? IconRegistry.renderIcon(this.name, this.variant, this.filled)\r\n : html`<div class=\"icon\" aria-hidden=\"true\" translate=\"no\">${this.name}</div>`;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-icon\": M3eIconElement;\r\n }\r\n}\r\n","import { IconRegistry, SvgIconInfo } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\nexport type { SvgIconInfo } from \"./IconRegistry\";\r\n\r\n/**\r\n * Registers an SVG icon to the internal icon registry used by `m3e-icon`.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param data The outlined and filled SVG information of the icon.\r\n */\r\nexport function registerIcon(\r\n name: string,\r\n variant: IconVariant,\r\n data: { outlined: SvgIconInfo; filled: SvgIconInfo },\r\n): void {\r\n IconRegistry.addIcon(name, variant, data);\r\n}\r\n"],"names":["PATH_DATA_PATTERN","VIEW_BOX_PATTERN","IconRegistry","addIcon","name","variant","fillSet","trustOutlinedViewBox","outlined","trustFilledViewBox","filled","viewBox","path","__classPrivateFieldGet","_a","_IconRegistry_validateSvgIconInfo","call","window","undefined","key","_IconRegistry_createKey","_IconRegistry_icons","set","svg","_IconRegistry_observers","get","forEach","x","isIconRegistered","has","renderIcon","data","observe","callback","push","callbacks","index","indexOf","splice","length","delete","info","trustViewBox","test","Error","value","Map","M3eIconElement","Role","LitElement","constructor","_M3eIconElement_iconRegistryUnobserve","grade","weight","opticalSize","connectedCallback","hasAttribute","ariaHidden","disconnectedCallback","willUpdate","_changedProperties","__classPrivateFieldSet","requestUpdate","updated","_icon","style","setProperty","render","html","styles","css","__decorate","query","prototype","property","reflect","type","Boolean","Number","attribute","customElement","registerIcon"],"mappings":"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"}
package/dist/icon.min.js CHANGED
@@ -3,5 +3,5 @@
3
3
  * Copyright (c) 2025–2026 matraic
4
4
  * See LICENSE file in the project root for full license text.
5
5
  */
6
- import{__classPrivateFieldGet as t,__classPrivateFieldSet as i,__decorate as e}from"tslib";import{svg as o,LitElement as s,html as a,css as n}from"lit";import{query as r,property as l}from"lit/decorators.js";import{Role as h,customElement as d}from"@m3e/web/core";var c,f,p,v,m;const g=/^[MmLlHhVvCcSsQqTtAaZz0-9.,\s-]+$/,u=/^-?\d+(\.\d+)?\s+-?\d+(\.\d+)?\s+-?\d+(\.\d+)?\s+-?\d+(\.\d+)?$/;class w{static addIcon(i,e,s){const a="string"==typeof s.outlined,n="string"==typeof s.filled;if("string"==typeof s.outlined&&(s.outlined={viewBox:"0 -960 960 960",path:s.outlined}),"string"==typeof s.filled&&(s.filled={viewBox:"0 -960 960 960",path:s.filled}),t(this,c,"m",m).call(this,i,e,s.outlined,a),t(this,c,"m",m).call(this,i,e,s.filled,n),void 0!==window){const a=t(this,c,"m",v).call(this,i,e);t(this,c,"f",f).set(a,{outlined:o`<svg viewBox="${s.outlined.viewBox}"><path d="${s.outlined.path}"/></svg>`,filled:o`<svg viewBox="${s.filled.viewBox}"><path d="${s.filled.path}"/></svg>`}),t(this,c,"f",p).get(a)?.forEach(t=>t())}}static isIconRegistered(i,e){return void 0!==window&&t(this,c,"f",f).has(t(this,c,"m",v).call(this,i,e))}static renderIcon(i,e,o){const s=t(this,c,"f",f).get(t(this,c,"m",v).call(this,i,e));return o?s?.filled:s?.outlined}static observe(i,e,o){if(void 0===window)return()=>{};const s=t(this,c,"m",v).call(this,i,e);return t(this,c,"f",p).has(s)?t(this,c,"f",p).get(s)?.push(o):t(this,c,"f",p).set(s,[o]),()=>{const i=t(this,c,"f",p).get(s);if(i){const e=i.indexOf(o);e>=0&&i.splice(e,1),0==i.length&&t(this,c,"f",p).delete(s)}}}}var y;c=w,v=function(t,i){return`${i}-${t}`},m=function(t,i,e,o=!1){if(!o&&!u.test(e.viewBox))throw new Error(`Unable to register icon '${t}' for variant '${i}'. Invalid viewbox data.`);if(!g.test(e.path))throw new Error(`Unable to register icon '${t}' for variant '${i}'. Invalid path data.`)},f={value:new Map},p={value:new Map};let b=class extends(h(s,"img")){constructor(){super(...arguments),y.set(this,void 0),this.name="",this.variant="outlined",this.filled=!1,this.grade="medium",this.weight=400,this.opticalSize=24}connectedCallback(){this.hasAttribute("aria-label")||this.hasAttribute("aria-labelledby")||this.hasAttribute("aria-hidden")||(this.ariaHidden="true"),super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),t(this,y,"f")?.call(this)}willUpdate(e){super.willUpdate(e),e.has("name")&&!w.isIconRegistered(this.name,this.variant)&&i(this,y,w.observe(this.name,this.variant,()=>{this.requestUpdate(),t(this,y,"f")?.call(this),i(this,y,void 0,"f")}),"f")}updated(t){super.updated(t),t.has("filled")&&this._icon?.style.setProperty("--_icon-fill",this.filled?"1":"0"),t.has("grade")&&this._icon?.style.setProperty("--_icon-grade","low"===this.grade?"-25":"high"===this.grade?"200":"0"),t.has("weight")&&this._icon?.style.setProperty("--_icon-weight",`${this.weight}`),t.has("opticalSize")&&this._icon?.style.setProperty("--_icon-optical-size",`${this.opticalSize}`)}render(){return w.isIconRegistered(this.name,this.variant)?w.renderIcon(this.name,this.variant,this.filled):a`<div class="icon" aria-hidden="true">${this.name}</div>`}};function $(t,i,e){w.addIcon(t,i,e)}y=new WeakMap,b.styles=n`:host { display: inline-block; user-select: none; font-size: var(--m3e-icon-size, 1.5rem); width: 1em; height: 1em; vertical-align: middle; overflow: hidden; } .icon { font-weight: normal; font-style: normal; line-height: 1; letter-spacing: normal; text-transform: none; white-space: nowrap; word-wrap: normal; direction: ltr; font-feature-settings: "liga"; -webkit-font-smoothing: antialiased; width: inherit; height: inherit; vertical-align: inherit; font-variation-settings: "FILL" var(--_icon-fill, 0), "wght" var(--_icon-weight, 400), "GRAD" var(--_icon-grade, 0), "opsz" var(--_icon-optical-size, 24); } :host([variant="outlined"]) .icon { font-family: "Material Symbols Outlined"; } :host([variant="rounded"]) .icon { font-family: "Material Symbols Rounded"; } :host([variant="sharp"]) .icon { font-family: "Material Symbols Sharp"; } svg { fill: currentColor; font-size: inherit; width: 1em; height: 1em; }`,e([r(".icon")],b.prototype,"_icon",void 0),e([l()],b.prototype,"name",void 0),e([l({reflect:!0})],b.prototype,"variant",void 0),e([l({type:Boolean,reflect:!0})],b.prototype,"filled",void 0),e([l()],b.prototype,"grade",void 0),e([l({type:Number})],b.prototype,"weight",void 0),e([l({attribute:"optical-size",type:Number})],b.prototype,"opticalSize",void 0),b=e([d("m3e-icon")],b);export{b as M3eIconElement,$ as registerIcon};
6
+ import{__classPrivateFieldGet as t,__classPrivateFieldSet as i,__decorate as e}from"tslib";import{svg as o,LitElement as s,html as a,css as n}from"lit";import{query as r,property as l}from"lit/decorators.js";import{Role as h,customElement as d}from"@m3e/web/core";var c,f,p,v,m;const g=/^[MmLlHhVvCcSsQqTtAaZz0-9.,\s-]+$/,u=/^-?\d+(\.\d+)?\s+-?\d+(\.\d+)?\s+-?\d+(\.\d+)?\s+-?\d+(\.\d+)?$/;class w{static addIcon(i,e,s){const a="string"==typeof s.outlined,n="string"==typeof s.filled;if("string"==typeof s.outlined&&(s.outlined={viewBox:"0 -960 960 960",path:s.outlined}),"string"==typeof s.filled&&(s.filled={viewBox:"0 -960 960 960",path:s.filled}),t(this,c,"m",m).call(this,i,e,s.outlined,a),t(this,c,"m",m).call(this,i,e,s.filled,n),void 0!==window){const a=t(this,c,"m",v).call(this,i,e);t(this,c,"f",f).set(a,{outlined:o`<svg viewBox="${s.outlined.viewBox}"><path d="${s.outlined.path}"/></svg>`,filled:o`<svg viewBox="${s.filled.viewBox}"><path d="${s.filled.path}"/></svg>`}),t(this,c,"f",p).get(a)?.forEach(t=>t())}}static isIconRegistered(i,e){return void 0!==window&&t(this,c,"f",f).has(t(this,c,"m",v).call(this,i,e))}static renderIcon(i,e,o){const s=t(this,c,"f",f).get(t(this,c,"m",v).call(this,i,e));return o?s?.filled:s?.outlined}static observe(i,e,o){if(void 0===window)return()=>{};const s=t(this,c,"m",v).call(this,i,e);return t(this,c,"f",p).has(s)?t(this,c,"f",p).get(s)?.push(o):t(this,c,"f",p).set(s,[o]),()=>{const i=t(this,c,"f",p).get(s);if(i){const e=i.indexOf(o);e>=0&&i.splice(e,1),0==i.length&&t(this,c,"f",p).delete(s)}}}}var y;c=w,v=function(t,i){return`${i}-${t}`},m=function(t,i,e,o=!1){if(!o&&!u.test(e.viewBox))throw new Error(`Unable to register icon '${t}' for variant '${i}'. Invalid viewbox data.`);if(!g.test(e.path))throw new Error(`Unable to register icon '${t}' for variant '${i}'. Invalid path data.`)},f={value:new Map},p={value:new Map};let b=class extends(h(s,"img")){constructor(){super(...arguments),y.set(this,void 0),this.name="",this.variant="outlined",this.filled=!1,this.grade="medium",this.weight=400,this.opticalSize=24}connectedCallback(){this.hasAttribute("aria-label")||this.hasAttribute("aria-labelledby")||this.hasAttribute("aria-hidden")||(this.ariaHidden="true"),super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),t(this,y,"f")?.call(this)}willUpdate(e){super.willUpdate(e),e.has("name")&&!w.isIconRegistered(this.name,this.variant)&&i(this,y,w.observe(this.name,this.variant,()=>{this.requestUpdate(),t(this,y,"f")?.call(this),i(this,y,void 0,"f")}),"f")}updated(t){super.updated(t),t.has("filled")&&this._icon?.style.setProperty("--_icon-fill",this.filled?"1":"0"),t.has("grade")&&this._icon?.style.setProperty("--_icon-grade","low"===this.grade?"-25":"high"===this.grade?"200":"0"),t.has("weight")&&this._icon?.style.setProperty("--_icon-weight",`${this.weight}`),t.has("opticalSize")&&this._icon?.style.setProperty("--_icon-optical-size",`${this.opticalSize}`)}render(){return w.isIconRegistered(this.name,this.variant)?w.renderIcon(this.name,this.variant,this.filled):a`<div class="icon" aria-hidden="true" translate="no">${this.name}</div>`}};function $(t,i,e){w.addIcon(t,i,e)}y=new WeakMap,b.styles=n`:host { display: inline-block; user-select: none; font-size: var(--m3e-icon-size, 1.5rem); width: 1em; height: 1em; vertical-align: middle; overflow: hidden; } .icon { font-weight: normal; font-style: normal; line-height: 1; letter-spacing: normal; text-transform: none; white-space: nowrap; word-wrap: normal; direction: ltr; font-feature-settings: "liga"; -webkit-font-smoothing: antialiased; width: inherit; height: inherit; vertical-align: inherit; font-variation-settings: "FILL" var(--_icon-fill, 0), "wght" var(--_icon-weight, 400), "GRAD" var(--_icon-grade, 0), "opsz" var(--_icon-optical-size, 24); } :host([variant="outlined"]) .icon { font-family: "Material Symbols Outlined"; } :host([variant="rounded"]) .icon { font-family: "Material Symbols Rounded"; } :host([variant="sharp"]) .icon { font-family: "Material Symbols Sharp"; } svg { fill: currentColor; font-size: inherit; width: 1em; height: 1em; }`,e([r(".icon")],b.prototype,"_icon",void 0),e([l()],b.prototype,"name",void 0),e([l({reflect:!0})],b.prototype,"variant",void 0),e([l({type:Boolean,reflect:!0})],b.prototype,"filled",void 0),e([l()],b.prototype,"grade",void 0),e([l({type:Number})],b.prototype,"weight",void 0),e([l({attribute:"optical-size",type:Number})],b.prototype,"opticalSize",void 0),b=e([d("m3e-icon")],b);export{b as M3eIconElement,$ as registerIcon};
7
7
  //# sourceMappingURL=icon.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon.min.js","sources":["../../src/icon/IconRegistry.ts","../../src/icon/IconElement.ts","../../src/icon/registerIcon.ts"],"sourcesContent":["import { svg, SVGTemplateResult } from \"lit\";\r\n\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\n/** @private */ const PATH_DATA_PATTERN = /^[MmLlHhVvCcSsQqTtAaZz0-9.,\\s-]+$/;\r\n/** @private */ const VIEW_BOX_PATTERN = /^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$/;\r\n\r\n/** Encapsulates information used to construct an SVG. */\r\nexport type SvgIconInfo = {\r\n /** The viewbox of the SVG. */\r\n viewBox: string;\r\n\r\n /** The path of the SVG. */\r\n path: string;\r\n};\r\n\r\n/** Represents the fill-axis SVG data for a single icon. */\r\nexport type SvgIconFillSet = {\r\n /** The unfilled (FILL=0) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n outlined: SvgIconInfo | string;\r\n\r\n /** The filled (FILL=1) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n filled: SvgIconInfo | string;\r\n};\r\n\r\n/**\r\n * Service to register and display icons used by the `m3e-icon` component.\r\n * @internal\r\n */\r\nexport class IconRegistry {\r\n /** @private */\r\n static readonly #icons = new Map<string, { outlined: SVGTemplateResult; filled: SVGTemplateResult }>();\r\n\r\n /** @private */ static readonly #observers = new Map<string, Array<() => void>>();\r\n\r\n /**\r\n * Adds an icon to the registry for the given variant and weight.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {SvgIconFillSet} fillSet The SVG data for both fill states (outlined and filled) of the icon.\r\n */\r\n static addIcon(name: string, variant: IconVariant, fillSet: SvgIconFillSet): void {\r\n const trustOutlinedViewBox = typeof fillSet.outlined === \"string\";\r\n const trustFilledViewBox = typeof fillSet.filled === \"string\";\r\n\r\n if (typeof fillSet.outlined === \"string\") {\r\n fillSet.outlined = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.outlined,\r\n };\r\n }\r\n if (typeof fillSet.filled === \"string\") {\r\n fillSet.filled = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.filled,\r\n };\r\n }\r\n\r\n this.#validateSvgIconInfo(name, variant, fillSet.outlined, trustOutlinedViewBox);\r\n this.#validateSvgIconInfo(name, variant, fillSet.filled, trustFilledViewBox);\r\n\r\n if (window !== undefined) {\r\n const key = this.#createKey(name, variant);\r\n this.#icons.set(key, {\r\n outlined: svg`<svg viewBox=\"${fillSet.outlined.viewBox}\"><path d=\"${fillSet.outlined.path}\"/></svg>`,\r\n filled: svg`<svg viewBox=\"${fillSet.filled.viewBox}\"><path d=\"${fillSet.filled.path}\"/></svg>`,\r\n });\r\n\r\n this.#observers.get(key)?.forEach((x) => x());\r\n }\r\n }\r\n\r\n /**\r\n * Determines whether an icon is registered for the given variant.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @returns {boolean} Whether `icon` is registered for the given `variant`.\r\n */\r\n static isIconRegistered(name: string, variant: IconVariant): boolean {\r\n return window !== undefined && this.#icons.has(this.#createKey(name, variant));\r\n }\r\n\r\n /**\r\n * Renders an icon from the registry.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {boolean} filled Whether to render a filled variant of the icon.\r\n * @returns {SVGTemplateResult | undefined} A `SVGTemplateResult` used to render the icon.\r\n */\r\n static renderIcon(name: string, variant: IconVariant, filled: boolean): SVGTemplateResult | undefined {\r\n const data = this.#icons.get(this.#createKey(name, variant));\r\n return filled ? data?.filled : data?.outlined;\r\n }\r\n\r\n /**\r\n * Begins observing registration for the specified icon.\r\n * @param {string} name The name of the icon to observe.\r\n * @param {IconVariant} variant The variant of the icon to observe.\r\n * @param {() => void} callback Callback invoked when the specified icon is registered for the given variant.\r\n * @returns {() => void} Function used to stop observing.\r\n */\r\n static observe(name: string, variant: IconVariant, callback: () => void): () => void {\r\n if (window === undefined) return () => {};\r\n\r\n const key = this.#createKey(name, variant);\r\n if (!this.#observers.has(key)) {\r\n this.#observers.set(key, [callback]);\r\n } else {\r\n this.#observers.get(key)?.push(callback);\r\n }\r\n\r\n return () => {\r\n const callbacks = this.#observers.get(key);\r\n if (callbacks) {\r\n const index = callbacks.indexOf(callback);\r\n if (index >= 0) {\r\n callbacks.splice(index, 1);\r\n }\r\n if (callbacks.length == 0) {\r\n this.#observers.delete(key);\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** @private */\r\n static #createKey(name: string, variant: IconVariant): string {\r\n return `${variant}-${name}`;\r\n }\r\n\r\n /** @private */\r\n static #validateSvgIconInfo(name: string, variant: IconVariant, info: SvgIconInfo, trustViewBox = false): void {\r\n if (!trustViewBox && !VIEW_BOX_PATTERN.test(info.viewBox)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid viewbox data.`);\r\n }\r\n if (!PATH_DATA_PATTERN.test(info.path)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid path data.`);\r\n }\r\n }\r\n}\r\n","import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport { customElement, Role } from \"@m3e/web/core\";\r\n\r\nimport { IconRegistry } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\nimport { IconGrade } from \"./IconGrade\";\r\nimport { IconWeight } from \"./IconWeight\";\r\n\r\n/**\r\n * A small symbol used to easily identify an action or category.\r\n *\r\n * @description\r\n * The `m3e-icon` component makes it easier to use Material Symbols in your application. Material Symbols are Google's newest icons supporting\r\n * a range of design variants. For more information, see:\r\n * - {@link https://developers.google.com/fonts/docs/material_symbols|Material Symbol Guide}\r\n * - {@link https://fonts.google.com/icons|Material Symbol Library}\r\n *\r\n * The Material Symbols font is the easiest way to incorporate Material Symbols into your application. Using the\r\n * {@link https://developers.google.com/fonts/docs/css2#forming_api_urls|Fonts CSS API}, you can use variable fonts to optimize icon\r\n * usage within your application. See {@link https://caniuse.com/variable-fonts|Can I Use's Variable Fonts} to determine whether\r\n * your user's browser support variable fonts.\r\n *\r\n * @example\r\n * The following example illustrates showing the `home` icon. The `name` attribute specifies the icon to present.\r\n * ```html\r\n * <m3e-icon name=\"home\"></m3e-icon>\r\n * ```\r\n * @example\r\n * The next example illustrates a link used to download a variable font for outlined icons with fill support.\r\n * ```html\r\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0\" rel=\"stylesheet\"/>\r\n * ```\r\n *\r\n * @tag m3e-icon\r\n *\r\n * @attr filled - Whether the icon is filled.\r\n * @attr grade - The grade of the icon.\r\n * @attr optical-size - A value from 20 to 48 indicating the optical size of the icon.\r\n * @attr name - The name of the icon.\r\n * @attr variant - The appearance variant of the icon.\r\n * @attr weight - A value from 100 to 700 indicating the weight of the icon.\r\n */\r\n@customElement(\"m3e-icon\")\r\nexport class M3eIconElement extends Role(LitElement, \"img\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-block;\r\n user-select: none;\r\n font-size: var(--m3e-icon-size, 1.5rem);\r\n width: 1em;\r\n height: 1em;\r\n vertical-align: middle;\r\n overflow: hidden;\r\n }\r\n .icon {\r\n font-weight: normal;\r\n font-style: normal;\r\n line-height: 1;\r\n letter-spacing: normal;\r\n text-transform: none;\r\n white-space: nowrap;\r\n word-wrap: normal;\r\n direction: ltr;\r\n font-feature-settings: \"liga\";\r\n -webkit-font-smoothing: antialiased;\r\n width: inherit;\r\n height: inherit;\r\n vertical-align: inherit;\r\n font-variation-settings:\r\n \"FILL\" var(--_icon-fill, 0),\r\n \"wght\" var(--_icon-weight, 400),\r\n \"GRAD\" var(--_icon-grade, 0),\r\n \"opsz\" var(--_icon-optical-size, 24);\r\n }\r\n :host([variant=\"outlined\"]) .icon {\r\n font-family: \"Material Symbols Outlined\";\r\n }\r\n :host([variant=\"rounded\"]) .icon {\r\n font-family: \"Material Symbols Rounded\";\r\n }\r\n :host([variant=\"sharp\"]) .icon {\r\n font-family: \"Material Symbols Sharp\";\r\n }\r\n svg {\r\n fill: currentColor;\r\n font-size: inherit;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n `;\r\n\r\n /** @private */ @query(\".icon\") private readonly _icon?: HTMLSpanElement;\r\n /** @private */ #iconRegistryUnobserve?: () => void;\r\n\r\n /** The name of the icon. */\r\n @property() name: string = \"\";\r\n\r\n /**\r\n * The appearance variant of the icon.\r\n * @default \"outlined\"\r\n */\r\n @property({ reflect: true }) variant: IconVariant = \"outlined\";\r\n\r\n /**\r\n * Whether the icon is filled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) filled = false;\r\n\r\n /**\r\n * The grade of the icon.\r\n * @default \"medium\"\r\n */\r\n @property() grade: IconGrade = \"medium\";\r\n\r\n /**\r\n * A value from 100 to 700 indicating the weight of the icon.\r\n * @default 400\r\n */\r\n @property({ type: Number }) weight: IconWeight = 400;\r\n\r\n /**\r\n * A value from 20 to 48 indicating the optical size of the icon.\r\n * @default 24\r\n */\r\n @property({ attribute: \"optical-size\", type: Number }) opticalSize = 24;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n if (\r\n !this.hasAttribute(\"aria-label\") &&\r\n !this.hasAttribute(\"aria-labelledby\") &&\r\n !this.hasAttribute(\"aria-hidden\")\r\n ) {\r\n this.ariaHidden = \"true\";\r\n }\r\n\r\n super.connectedCallback();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.#iconRegistryUnobserve?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override willUpdate(_changedProperties: PropertyValues<this>): void {\r\n super.willUpdate(_changedProperties);\r\n\r\n if (_changedProperties.has(\"name\") && !IconRegistry.isIconRegistered(this.name, this.variant)) {\r\n this.#iconRegistryUnobserve = IconRegistry.observe(this.name, this.variant, () => {\r\n this.requestUpdate();\r\n this.#iconRegistryUnobserve?.();\r\n this.#iconRegistryUnobserve = undefined;\r\n });\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override updated(_changedProperties: PropertyValues<this>): void {\r\n super.updated(_changedProperties);\r\n\r\n if (_changedProperties.has(\"filled\")) {\r\n this._icon?.style.setProperty(\"--_icon-fill\", this.filled ? \"1\" : \"0\");\r\n }\r\n if (_changedProperties.has(\"grade\")) {\r\n this._icon?.style.setProperty(\r\n \"--_icon-grade\",\r\n this.grade === \"low\" ? \"-25\" : this.grade === \"high\" ? \"200\" : \"0\",\r\n );\r\n }\r\n if (_changedProperties.has(\"weight\")) {\r\n this._icon?.style.setProperty(\"--_icon-weight\", `${this.weight}`);\r\n }\r\n if (_changedProperties.has(\"opticalSize\")) {\r\n this._icon?.style.setProperty(\"--_icon-optical-size\", `${this.opticalSize}`);\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return IconRegistry.isIconRegistered(this.name, this.variant)\r\n ? IconRegistry.renderIcon(this.name, this.variant, this.filled)\r\n : html`<div class=\"icon\" aria-hidden=\"true\">${this.name}</div>`;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-icon\": M3eIconElement;\r\n }\r\n}\r\n","import { IconRegistry, SvgIconInfo } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\nexport type { SvgIconInfo } from \"./IconRegistry\";\r\n\r\n/**\r\n * Registers an SVG icon to the internal icon registry used by `m3e-icon`.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param data The outlined and filled SVG information of the icon.\r\n */\r\nexport function registerIcon(\r\n name: string,\r\n variant: IconVariant,\r\n data: { outlined: SvgIconInfo; filled: SvgIconInfo },\r\n): void {\r\n IconRegistry.addIcon(name, variant, data);\r\n}\r\n"],"names":["PATH_DATA_PATTERN","VIEW_BOX_PATTERN","IconRegistry","addIcon","name","variant","fillSet","trustOutlinedViewBox","outlined","trustFilledViewBox","filled","viewBox","path","__classPrivateFieldGet","this","_a","_IconRegistry_validateSvgIconInfo","call","undefined","window","key","_IconRegistry_createKey","_IconRegistry_icons","set","svg","_IconRegistry_observers","get","forEach","x","isIconRegistered","has","renderIcon","data","observe","callback","push","callbacks","index","indexOf","splice","length","delete","info","trustViewBox","test","Error","value","Map","M3eIconElement","Role","LitElement","constructor","_M3eIconElement_iconRegistryUnobserve","grade","weight","opticalSize","connectedCallback","hasAttribute","ariaHidden","super","disconnectedCallback","willUpdate","_changedProperties","__classPrivateFieldSet","requestUpdate","updated","_icon","style","setProperty","render","html","registerIcon","styles","css","__decorate","query","prototype","property","reflect","type","Boolean","Number","attribute","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"icon.min.js","sources":["../../src/icon/IconRegistry.ts","../../src/icon/IconElement.ts","../../src/icon/registerIcon.ts"],"sourcesContent":["import { svg, SVGTemplateResult } from \"lit\";\r\n\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\n/** @private */ const PATH_DATA_PATTERN = /^[MmLlHhVvCcSsQqTtAaZz0-9.,\\s-]+$/;\r\n/** @private */ const VIEW_BOX_PATTERN = /^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$/;\r\n\r\n/** Encapsulates information used to construct an SVG. */\r\nexport type SvgIconInfo = {\r\n /** The viewbox of the SVG. */\r\n viewBox: string;\r\n\r\n /** The path of the SVG. */\r\n path: string;\r\n};\r\n\r\n/** Represents the fill-axis SVG data for a single icon. */\r\nexport type SvgIconFillSet = {\r\n /** The unfilled (FILL=0) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n outlined: SvgIconInfo | string;\r\n\r\n /** The filled (FILL=1) SVG representation (or path assuming viewBox=\"0 -960 960 960\") of the icon. */\r\n filled: SvgIconInfo | string;\r\n};\r\n\r\n/**\r\n * Service to register and display icons used by the `m3e-icon` component.\r\n * @internal\r\n */\r\nexport class IconRegistry {\r\n /** @private */\r\n static readonly #icons = new Map<string, { outlined: SVGTemplateResult; filled: SVGTemplateResult }>();\r\n\r\n /** @private */ static readonly #observers = new Map<string, Array<() => void>>();\r\n\r\n /**\r\n * Adds an icon to the registry for the given variant and weight.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {SvgIconFillSet} fillSet The SVG data for both fill states (outlined and filled) of the icon.\r\n */\r\n static addIcon(name: string, variant: IconVariant, fillSet: SvgIconFillSet): void {\r\n const trustOutlinedViewBox = typeof fillSet.outlined === \"string\";\r\n const trustFilledViewBox = typeof fillSet.filled === \"string\";\r\n\r\n if (typeof fillSet.outlined === \"string\") {\r\n fillSet.outlined = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.outlined,\r\n };\r\n }\r\n if (typeof fillSet.filled === \"string\") {\r\n fillSet.filled = {\r\n viewBox: \"0 -960 960 960\",\r\n path: fillSet.filled,\r\n };\r\n }\r\n\r\n this.#validateSvgIconInfo(name, variant, fillSet.outlined, trustOutlinedViewBox);\r\n this.#validateSvgIconInfo(name, variant, fillSet.filled, trustFilledViewBox);\r\n\r\n if (window !== undefined) {\r\n const key = this.#createKey(name, variant);\r\n this.#icons.set(key, {\r\n outlined: svg`<svg viewBox=\"${fillSet.outlined.viewBox}\"><path d=\"${fillSet.outlined.path}\"/></svg>`,\r\n filled: svg`<svg viewBox=\"${fillSet.filled.viewBox}\"><path d=\"${fillSet.filled.path}\"/></svg>`,\r\n });\r\n\r\n this.#observers.get(key)?.forEach((x) => x());\r\n }\r\n }\r\n\r\n /**\r\n * Determines whether an icon is registered for the given variant.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @returns {boolean} Whether `icon` is registered for the given `variant`.\r\n */\r\n static isIconRegistered(name: string, variant: IconVariant): boolean {\r\n return window !== undefined && this.#icons.has(this.#createKey(name, variant));\r\n }\r\n\r\n /**\r\n * Renders an icon from the registry.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param {boolean} filled Whether to render a filled variant of the icon.\r\n * @returns {SVGTemplateResult | undefined} A `SVGTemplateResult` used to render the icon.\r\n */\r\n static renderIcon(name: string, variant: IconVariant, filled: boolean): SVGTemplateResult | undefined {\r\n const data = this.#icons.get(this.#createKey(name, variant));\r\n return filled ? data?.filled : data?.outlined;\r\n }\r\n\r\n /**\r\n * Begins observing registration for the specified icon.\r\n * @param {string} name The name of the icon to observe.\r\n * @param {IconVariant} variant The variant of the icon to observe.\r\n * @param {() => void} callback Callback invoked when the specified icon is registered for the given variant.\r\n * @returns {() => void} Function used to stop observing.\r\n */\r\n static observe(name: string, variant: IconVariant, callback: () => void): () => void {\r\n if (window === undefined) return () => {};\r\n\r\n const key = this.#createKey(name, variant);\r\n if (!this.#observers.has(key)) {\r\n this.#observers.set(key, [callback]);\r\n } else {\r\n this.#observers.get(key)?.push(callback);\r\n }\r\n\r\n return () => {\r\n const callbacks = this.#observers.get(key);\r\n if (callbacks) {\r\n const index = callbacks.indexOf(callback);\r\n if (index >= 0) {\r\n callbacks.splice(index, 1);\r\n }\r\n if (callbacks.length == 0) {\r\n this.#observers.delete(key);\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** @private */\r\n static #createKey(name: string, variant: IconVariant): string {\r\n return `${variant}-${name}`;\r\n }\r\n\r\n /** @private */\r\n static #validateSvgIconInfo(name: string, variant: IconVariant, info: SvgIconInfo, trustViewBox = false): void {\r\n if (!trustViewBox && !VIEW_BOX_PATTERN.test(info.viewBox)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid viewbox data.`);\r\n }\r\n if (!PATH_DATA_PATTERN.test(info.path)) {\r\n throw new Error(`Unable to register icon '${name}' for variant '${variant}'. Invalid path data.`);\r\n }\r\n }\r\n}\r\n","import { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport { customElement, Role } from \"@m3e/web/core\";\r\n\r\nimport { IconRegistry } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\nimport { IconGrade } from \"./IconGrade\";\r\nimport { IconWeight } from \"./IconWeight\";\r\n\r\n/**\r\n * A small symbol used to easily identify an action or category.\r\n *\r\n * @description\r\n * The `m3e-icon` component makes it easier to use Material Symbols in your application. Material Symbols are Google's newest icons supporting\r\n * a range of design variants. For more information, see:\r\n * - {@link https://developers.google.com/fonts/docs/material_symbols|Material Symbol Guide}\r\n * - {@link https://fonts.google.com/icons|Material Symbol Library}\r\n *\r\n * The Material Symbols font is the easiest way to incorporate Material Symbols into your application. Using the\r\n * {@link https://developers.google.com/fonts/docs/css2#forming_api_urls|Fonts CSS API}, you can use variable fonts to optimize icon\r\n * usage within your application. See {@link https://caniuse.com/variable-fonts|Can I Use's Variable Fonts} to determine whether\r\n * your user's browser support variable fonts.\r\n *\r\n * @example\r\n * The following example illustrates showing the `home` icon. The `name` attribute specifies the icon to present.\r\n * ```html\r\n * <m3e-icon name=\"home\"></m3e-icon>\r\n * ```\r\n * @example\r\n * The next example illustrates a link used to download a variable font for outlined icons with fill support.\r\n * ```html\r\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0\" rel=\"stylesheet\"/>\r\n * ```\r\n *\r\n * @tag m3e-icon\r\n *\r\n * @attr filled - Whether the icon is filled.\r\n * @attr grade - The grade of the icon.\r\n * @attr optical-size - A value from 20 to 48 indicating the optical size of the icon.\r\n * @attr name - The name of the icon.\r\n * @attr variant - The appearance variant of the icon.\r\n * @attr weight - A value from 100 to 700 indicating the weight of the icon.\r\n */\r\n@customElement(\"m3e-icon\")\r\nexport class M3eIconElement extends Role(LitElement, \"img\") {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-block;\r\n user-select: none;\r\n font-size: var(--m3e-icon-size, 1.5rem);\r\n width: 1em;\r\n height: 1em;\r\n vertical-align: middle;\r\n overflow: hidden;\r\n }\r\n .icon {\r\n font-weight: normal;\r\n font-style: normal;\r\n line-height: 1;\r\n letter-spacing: normal;\r\n text-transform: none;\r\n white-space: nowrap;\r\n word-wrap: normal;\r\n direction: ltr;\r\n font-feature-settings: \"liga\";\r\n -webkit-font-smoothing: antialiased;\r\n width: inherit;\r\n height: inherit;\r\n vertical-align: inherit;\r\n font-variation-settings:\r\n \"FILL\" var(--_icon-fill, 0),\r\n \"wght\" var(--_icon-weight, 400),\r\n \"GRAD\" var(--_icon-grade, 0),\r\n \"opsz\" var(--_icon-optical-size, 24);\r\n }\r\n :host([variant=\"outlined\"]) .icon {\r\n font-family: \"Material Symbols Outlined\";\r\n }\r\n :host([variant=\"rounded\"]) .icon {\r\n font-family: \"Material Symbols Rounded\";\r\n }\r\n :host([variant=\"sharp\"]) .icon {\r\n font-family: \"Material Symbols Sharp\";\r\n }\r\n svg {\r\n fill: currentColor;\r\n font-size: inherit;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n `;\r\n\r\n /** @private */ @query(\".icon\") private readonly _icon?: HTMLSpanElement;\r\n /** @private */ #iconRegistryUnobserve?: () => void;\r\n\r\n /** The name of the icon. */\r\n @property() name: string = \"\";\r\n\r\n /**\r\n * The appearance variant of the icon.\r\n * @default \"outlined\"\r\n */\r\n @property({ reflect: true }) variant: IconVariant = \"outlined\";\r\n\r\n /**\r\n * Whether the icon is filled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) filled = false;\r\n\r\n /**\r\n * The grade of the icon.\r\n * @default \"medium\"\r\n */\r\n @property() grade: IconGrade = \"medium\";\r\n\r\n /**\r\n * A value from 100 to 700 indicating the weight of the icon.\r\n * @default 400\r\n */\r\n @property({ type: Number }) weight: IconWeight = 400;\r\n\r\n /**\r\n * A value from 20 to 48 indicating the optical size of the icon.\r\n * @default 24\r\n */\r\n @property({ attribute: \"optical-size\", type: Number }) opticalSize = 24;\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n if (\r\n !this.hasAttribute(\"aria-label\") &&\r\n !this.hasAttribute(\"aria-labelledby\") &&\r\n !this.hasAttribute(\"aria-hidden\")\r\n ) {\r\n this.ariaHidden = \"true\";\r\n }\r\n\r\n super.connectedCallback();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.#iconRegistryUnobserve?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override willUpdate(_changedProperties: PropertyValues<this>): void {\r\n super.willUpdate(_changedProperties);\r\n\r\n if (_changedProperties.has(\"name\") && !IconRegistry.isIconRegistered(this.name, this.variant)) {\r\n this.#iconRegistryUnobserve = IconRegistry.observe(this.name, this.variant, () => {\r\n this.requestUpdate();\r\n this.#iconRegistryUnobserve?.();\r\n this.#iconRegistryUnobserve = undefined;\r\n });\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override updated(_changedProperties: PropertyValues<this>): void {\r\n super.updated(_changedProperties);\r\n\r\n if (_changedProperties.has(\"filled\")) {\r\n this._icon?.style.setProperty(\"--_icon-fill\", this.filled ? \"1\" : \"0\");\r\n }\r\n if (_changedProperties.has(\"grade\")) {\r\n this._icon?.style.setProperty(\r\n \"--_icon-grade\",\r\n this.grade === \"low\" ? \"-25\" : this.grade === \"high\" ? \"200\" : \"0\",\r\n );\r\n }\r\n if (_changedProperties.has(\"weight\")) {\r\n this._icon?.style.setProperty(\"--_icon-weight\", `${this.weight}`);\r\n }\r\n if (_changedProperties.has(\"opticalSize\")) {\r\n this._icon?.style.setProperty(\"--_icon-optical-size\", `${this.opticalSize}`);\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return IconRegistry.isIconRegistered(this.name, this.variant)\r\n ? IconRegistry.renderIcon(this.name, this.variant, this.filled)\r\n : html`<div class=\"icon\" aria-hidden=\"true\" translate=\"no\">${this.name}</div>`;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-icon\": M3eIconElement;\r\n }\r\n}\r\n","import { IconRegistry, SvgIconInfo } from \"./IconRegistry\";\r\nimport { IconVariant } from \"./IconVariant\";\r\n\r\nexport type { SvgIconInfo } from \"./IconRegistry\";\r\n\r\n/**\r\n * Registers an SVG icon to the internal icon registry used by `m3e-icon`.\r\n * @param {string} name The name of the icon.\r\n * @param {IconVariant} variant The variant of the icon.\r\n * @param data The outlined and filled SVG information of the icon.\r\n */\r\nexport function registerIcon(\r\n name: string,\r\n variant: IconVariant,\r\n data: { outlined: SvgIconInfo; filled: SvgIconInfo },\r\n): void {\r\n IconRegistry.addIcon(name, variant, data);\r\n}\r\n"],"names":["PATH_DATA_PATTERN","VIEW_BOX_PATTERN","IconRegistry","addIcon","name","variant","fillSet","trustOutlinedViewBox","outlined","trustFilledViewBox","filled","viewBox","path","__classPrivateFieldGet","this","_a","_IconRegistry_validateSvgIconInfo","call","undefined","window","key","_IconRegistry_createKey","_IconRegistry_icons","set","svg","_IconRegistry_observers","get","forEach","x","isIconRegistered","has","renderIcon","data","observe","callback","push","callbacks","index","indexOf","splice","length","delete","info","trustViewBox","test","Error","value","Map","M3eIconElement","Role","LitElement","constructor","_M3eIconElement_iconRegistryUnobserve","grade","weight","opticalSize","connectedCallback","hasAttribute","ariaHidden","super","disconnectedCallback","willUpdate","_changedProperties","__classPrivateFieldSet","requestUpdate","updated","_icon","style","setProperty","render","html","registerIcon","styles","css","__decorate","query","prototype","property","reflect","type","Boolean","Number","attribute","customElement"],"mappings":"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"}
package/dist/menu.js CHANGED
@@ -6,7 +6,7 @@
6
6
  import { __decorate, __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
7
7
  import { LitElement, nothing, html, unsafeCSS, css } from 'lit';
8
8
  import { query, state, property } from 'lit/decorators.js';
9
- import { KeyboardClick, Focusable, AttachInternals, Disabled, FocusController, isLinkButtonMixin, renderPseudoLink, DesignToken, HtmlFor, ActionElementBase, customElement, LinkButton, Role, HoverController, setCustomState, hasAssignedNodes, SuppressInitialAnimation, ScrollController, deleteCustomState, addCustomState, registerStyleSheet, Checked, prefersReducedMotion } from '@m3e/web/core';
9
+ import { KeyboardClick, Focusable, AttachInternals, Disabled, FocusController, isLinkButtonMixin, renderPseudoLink, DesignToken, HtmlFor, ActionElementBase, customElement, LinkButton, Role, HoverController, setCustomState, hasAssignedNodes, SuppressInitialAnimation, ScrollController, ClickOutsideController, deleteCustomState, addCustomState, registerStyleSheet, Checked, prefersReducedMotion } from '@m3e/web/core';
10
10
  import { addAriaReferencedId, removeAriaReferencedId, RovingTabIndexManager } from '@m3e/web/core/a11y';
11
11
  import { positionAnchor } from '@m3e/web/core/anchoring';
12
12
  import { M3eDirectionality } from '@m3e/web/core/bidi';
@@ -355,7 +355,7 @@ _M3eMenuItemElement_handleMouseEnter = function _M3eMenuItemElement_handleMouseE
355
355
  __decorate([state()], M3eMenuItemElement.prototype, "_hasSubmenu", void 0);
356
356
  M3eMenuItemElement = M3eMenuItemElement_1 = __decorate([customElement("m3e-menu-item")], M3eMenuItemElement);
357
357
 
358
- var _M3eMenuElement_instances, _M3eMenuElement_trigger, _M3eMenuElement_anchorCleanup, _M3eMenuElement_listManager, _M3eMenuElement_keyDownHandler, _M3eMenuElement_mouseEnterHandler, _M3eMenuElement_documentClickHandler, _M3eMenuElement_scrollController, _M3eMenuElement_toggleHandler, _M3eMenuElement_handleSlotChange, _M3eMenuElement_handleKeyDown, _M3eMenuElement_handleMouseEnter, _M3eMenuElement_handleDocumentClick, _M3eMenuElement_getAbsolutePosition, _M3eMenuElement_deactivate;
358
+ var _M3eMenuElement_instances, _M3eMenuElement_trigger, _M3eMenuElement_anchorCleanup, _M3eMenuElement_listManager, _M3eMenuElement_keyDownHandler, _M3eMenuElement_mouseEnterHandler, _M3eMenuElement_scrollController, _M3eMenuElement_clickOutsideController, _M3eMenuElement_toggleHandler, _M3eMenuElement_handleSlotChange, _M3eMenuElement_handleKeyDown, _M3eMenuElement_handleMouseEnter, _M3eMenuElement_getAbsolutePosition, _M3eMenuElement_deactivate;
359
359
  var M3eMenuElement_1;
360
360
  /**
361
361
  * Presents a list of choices on a temporary surface.
@@ -449,21 +449,35 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends SuppressIni
449
449
  /** @private */
450
450
  _M3eMenuElement_mouseEnterHandler.set(this, () => __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleMouseEnter).call(this));
451
451
  /** @private */
452
- _M3eMenuElement_documentClickHandler.set(this, e => __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleDocumentClick).call(this, e));
453
- /** @private */
454
452
  _M3eMenuElement_scrollController.set(this, new ScrollController(this, {
455
453
  target: null,
456
454
  callback: target => target instanceof M3eMenuElement_1 ? target.items.filter(x => x instanceof M3eMenuItemElement).forEach(x => x.submenu?.hide()) : this.hideAll()
457
455
  }));
458
456
  /** @private */
457
+ _M3eMenuElement_clickOutsideController.set(this, new ClickOutsideController(this, {
458
+ target: null,
459
+ callback: composedPath => {
460
+ // If the menu isn't a submenu and no submenu is being clicked, close the entire menu
461
+ if (!this.submenu && !composedPath.some(x => x instanceof M3eMenuElement_1)) {
462
+ this.hide();
463
+ }
464
+ }
465
+ }));
466
+ /** @private */
459
467
  _M3eMenuElement_toggleHandler.set(this, e => {
460
- if (e.newState === "closed") {
461
- __classPrivateFieldGet(this, _M3eMenuElement_anchorCleanup, "f")?.call(this);
462
- __classPrivateFieldSet(this, _M3eMenuElement_anchorCleanup, undefined, "f");
463
- } else {
464
- setTimeout(() => {
465
- __classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").setActiveItem(__classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").items.find(x => !x.disabled));
466
- }, 40);
468
+ switch (e.newState) {
469
+ case "open":
470
+ __classPrivateFieldGet(this, _M3eMenuElement_clickOutsideController, "f").observe(this);
471
+ if (__classPrivateFieldGet(this, _M3eMenuElement_trigger, "f")) {
472
+ __classPrivateFieldGet(this, _M3eMenuElement_clickOutsideController, "f").observe(__classPrivateFieldGet(this, _M3eMenuElement_trigger, "f"));
473
+ }
474
+ setTimeout(() => __classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").setActiveItem(__classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").items.find(x => !x.disabled)), 40);
475
+ break;
476
+ case "closed":
477
+ __classPrivateFieldGet(this, _M3eMenuElement_clickOutsideController, "f").unobserveAll();
478
+ __classPrivateFieldGet(this, _M3eMenuElement_anchorCleanup, "f")?.call(this);
479
+ __classPrivateFieldSet(this, _M3eMenuElement_anchorCleanup, undefined, "f");
480
+ break;
467
481
  }
468
482
  });
469
483
  /**
@@ -500,7 +514,6 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends SuppressIni
500
514
  this.addEventListener("keydown", __classPrivateFieldGet(this, _M3eMenuElement_keyDownHandler, "f"));
501
515
  this.addEventListener("mouseenter", __classPrivateFieldGet(this, _M3eMenuElement_mouseEnterHandler, "f"));
502
516
  this.addEventListener("toggle", __classPrivateFieldGet(this, _M3eMenuElement_toggleHandler, "f"));
503
- document.addEventListener("click", __classPrivateFieldGet(this, _M3eMenuElement_documentClickHandler, "f"));
504
517
  }
505
518
  /** @inheritdoc */
506
519
  disconnectedCallback() {
@@ -508,7 +521,6 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends SuppressIni
508
521
  this.removeEventListener("keydown", __classPrivateFieldGet(this, _M3eMenuElement_keyDownHandler, "f"));
509
522
  this.removeEventListener("mouseenter", __classPrivateFieldGet(this, _M3eMenuElement_mouseEnterHandler, "f"));
510
523
  this.removeEventListener("toggle", __classPrivateFieldGet(this, _M3eMenuElement_toggleHandler, "f"));
511
- document.removeEventListener("click", __classPrivateFieldGet(this, _M3eMenuElement_documentClickHandler, "f"));
512
524
  __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_deactivate).call(this);
513
525
  }
514
526
  /**
@@ -628,8 +640,8 @@ _M3eMenuElement_anchorCleanup = new WeakMap();
628
640
  _M3eMenuElement_listManager = new WeakMap();
629
641
  _M3eMenuElement_keyDownHandler = new WeakMap();
630
642
  _M3eMenuElement_mouseEnterHandler = new WeakMap();
631
- _M3eMenuElement_documentClickHandler = new WeakMap();
632
643
  _M3eMenuElement_scrollController = new WeakMap();
644
+ _M3eMenuElement_clickOutsideController = new WeakMap();
633
645
  _M3eMenuElement_toggleHandler = new WeakMap();
634
646
  _M3eMenuElement_instances = new WeakSet();
635
647
  _M3eMenuElement_handleSlotChange = function _M3eMenuElement_handleSlotChange() {
@@ -680,11 +692,6 @@ _M3eMenuElement_handleKeyDown = function _M3eMenuElement_handleKeyDown(e) {
680
692
  _M3eMenuElement_handleMouseEnter = function _M3eMenuElement_handleMouseEnter() {
681
693
  this._activate();
682
694
  };
683
- _M3eMenuElement_handleDocumentClick = function _M3eMenuElement_handleDocumentClick(e) {
684
- if (!this.submenu && !e.composedPath().some(x => x instanceof M3eMenuElement_1 || x === __classPrivateFieldGet(this, _M3eMenuElement_trigger, "f"))) {
685
- this.hide();
686
- }
687
- };
688
695
  _M3eMenuElement_getAbsolutePosition = function _M3eMenuElement_getAbsolutePosition(element) {
689
696
  let x = 0,
690
697
  y = 0;