{"_id":"@adaept/ae-icon5","_rev":"6-9e1e6b941380c0efd3583b69647f165f","name":"@adaept/ae-icon5","dist-tags":{"latest":"1.5.0"},"versions":{"1.2.3":{"name":"@adaept/ae-icon5","version":"1.2.3","author":{"name":"adaept"},"license":"MIT","_id":"@adaept/ae-icon5@1.2.3","maintainers":[{"name":"adaept","email":"peterennis@yahoo.com"}],"homepage":"https://aeicon5.adaept.com","bugs":{"url":"https://github.com/adaept/ae-icon5"},"dist":{"shasum":"f943c12cc4dbb811db572ebf1c23da4d76a23491","tarball":"https://registry.npmjs.org/@adaept/ae-icon5/-/ae-icon5-1.2.3.tgz","fileCount":1350,"integrity":"sha512-XU5weK3eiNoOGU2OG2ogfPTtW0IQC/SQWwvy0XRd5WVhKq35m2N+mynbiiBU9EWJCxRiHmzYen7LoqezQtFtPw==","signatures":[{"sig":"MEUCIQCBSb1r+4y4LbCeqjhz/m1WcGiSOPt8Fg/YNHXfU4f/QAIgewhoAfBsgdFphZ0FiSDBkNebir0WRoHrXUi5LNkAfeE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1220816,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoi0SCRA9TVsSAnZWagAAuaEP/Rr3wX7/pfVExCojrFUt\n281uyfRvyITgM0u7qurVlAMUt3Ij/pg6NB8JVeN7HUXwrPoi1zOkrg+oHekG\nXr6g2SykEho1rcDFkR5cYpi7JXgYUBUo4CpMUUW363Ufb72KdS0V/ZhP40mA\nwrlxHrbkwO5uTnNAs/4DqRFlfAhOwArfteZ15cRuwNSnNYkporS7YwvGGH1K\nqrMMqIuji2CVjWFQwZ3W7XqGan4yy8M5aOOLhULGLUc6oMfqyFe7j3IIMvTX\nDiiEiK0lLM42pkz+tmTvXAzJdvCUFMUM3VvUDCHfXf91PiEMhbG384GmT8IV\noorEOzDRkT3EDYSU5tbR14jej4abTXZctofxcEHGW0wHUqpDSYLZWFjSm6so\nqp9jP55PD8zRAE2fVhy1TrIP5fryI3gx9cdvUICPxWvuQTYYPP/HrxFx/ioc\nZq8EoqexsfwpqEkdm+WxgShsv5d+LaFjHTr84GgdUsNde+6UBJ94p6htWoXy\ngLBgqIl0tqE3ZODgwIqO3Ff1BPd7diO8WpwADx8WVbjJDJ83n8g7gTs3Sphj\n2FX08ZQvnameVJ6w4YNCV/0VvKc7tpIfiwxK1DLsdKUHFsS/q0DkKBY8BtRn\nR1GJA1K4yFiw0l8sey/q5/pAPHp0lW+JnoiXYyx5dWIOtMj0+nnZbpwG6fNg\niuuX\r\n=ItZI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.cjs.js","types":"dist/types/components.d.ts","es2015":"dist/esm/index.mjs","es2017":"dist/esm/index.mjs","module":"dist/index.js","gitHead":"2ea99f925ff926ebd106a892fb1e2a99edb1fc74","private":false,"scripts":{"test":"stencil test --spec --e2e","build":"stencil build","start":"stencil build --dev --watch --serve","now-build":"stencil build","test.watch":"stencil test --spec --e2e --watchAll"},"_npmUser":{"name":"adaept","email":"peterennis@yahoo.com"},"collection":"dist/collection/collection-manifest.json","repository":{"url":"git+https://github.com/adaept/ae-icon5.git","type":"git"},"_npmVersion":"6.13.4","description":"adaept Icon5 Component","directories":{},"_nodeVersion":"12.18.3","dependencies":{"ionicons":"5.2.3"},"_hasShrinkwrap":false,"collection:main":"dist/collection/index.js","devDependencies":{"jest":"26.6.1","eslint":"^7.10.0","jest-cli":"26.6.1","puppeteer":"~5.4.1","@types/jest":"26.0.15","@stencil/core":"2.2.0","@types/puppeteer":"~3.0.4","eslint-plugin-node":"^11.1.0","eslint-plugin-import":"^2.22.1","eslint-plugin-promise":"^4.2.1","eslint-config-standard":"^14.1.1","eslint-plugin-standard":"^4.0.1","@typescript-eslint/parser":"^4.2.0","@typescript-eslint/eslint-plugin":"^4.2.0"},"_npmOperationalInternal":{"tmp":"tmp/ae-icon5_1.2.3_1604463889962_0.81179252372926","host":"s3://npm-registry-packages"}},"1.3.0":{"name":"@adaept/ae-icon5","version":"1.3.0","author":{"name":"adaept"},"license":"MIT","_id":"@adaept/ae-icon5@1.3.0","maintainers":[{"name":"adaept","email":"peterennis@yahoo.com"}],"homepage":"https://aeicon5.adaept.com","bugs":{"url":"https://github.com/adaept/ae-icon5-component"},"dist":{"shasum":"a59d2da33e23419008c83e7af5905e693c14f5dc","tarball":"https://registry.npmjs.org/@adaept/ae-icon5/-/ae-icon5-1.3.0.tgz","fileCount":1315,"integrity":"sha512-IWph7+XTcDM391xqO60/Ezc4UurRR6sFzVvtEsFPj44e4epLNbd6g7oKQa0M51TPv29xDX0hTJeGBO7CkHjtbw==","signatures":[{"sig":"MEUCIQCViQRG8QwgPI+ArbKQmekvPdJxtu6gGu5RwSZcptLt3wIgRG4Exi7mFEK5IC2BAPpKS241j2eGkDGudODeflMfgTg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1027530,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfo54wCRA9TVsSAnZWagAAee4P/05fEGIdPqtmboa3EjuD\n5MlawZs30e4p7M8mmXYHnirBoeR+vaYG/uIsQOJGCxBRBizQsovXhgK0XlZf\nhUUOTYSDS/juqAAyMeIDP9G0eU4llfBDAiE4a+ot8L0aSDioWAdhylG++s25\nN1sQvvPbEsVbeATk3ILse9QWxNQzSayyNzUBmSTAZu0rkpvh3wE1o7uacijF\n8GmBGanN672qLgZcHvAAuV9lN7dXXNrb5wElZoIcdUeS+YbtorfqncWf5wPX\nlc0FEh9U16JxcjCJJ+ZFiE7aEKzpxsa/biCZk2QyW/Q0psTpl0x/jkq52zes\n2jagblNuR2Ij4yLtzyLZORePgDFfN9pll5EqpIgRF5R4kKY8HOTuQbSKlaip\nl8kRKiOeyB2mBq4dbskXcF1Z+usk8Swjco3ZJPkfGCDo2B0il73e21Qqnvlu\nezmiY500UZ4B6jzSDhyf4DCWBXdkneHhQ7VTnOeD5pEO7rr0A5s5wJ/t59X+\n/Z78U1GFuaZdMxRi6vLCxBoUGNmjxh+YS0rCds84tyD7N7CxFOaPD9vppeGE\nr/Pznkz3g9UrMoJlN9qeQxQOHEHQpdksPorxeOH7kNVK1Ja7UZJ1ohJrYC6H\nkzV/OjWMgj7E3sxlKeOc5MSaGWtfkq+hmkJFspaB6qvNojtfaaW3fjCO0+ol\nu6tm\r\n=45iH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.cjs.js","types":"dist/types/components.d.ts","es2015":"dist/esm/index.mjs","es2017":"dist/esm/index.mjs","module":"dist/index.js","gitHead":"40f1d774343120685e757be110bf69cf7f29b296","private":false,"scripts":{"test":"stencil test --spec --e2e","build":"stencil build","start":"stencil build --dev --watch --serve","now-build":"stencil build","test.watch":"stencil test --spec --e2e --watchAll"},"_npmUser":{"name":"adaept","email":"peterennis@yahoo.com"},"collection":"dist/collection/collection-manifest.json","repository":{"url":"git+https://github.com/adaept/ae-icon5-component.git","type":"git"},"_npmVersion":"6.13.4","description":"adaept Icon5 Component","directories":{},"_nodeVersion":"12.18.3","dependencies":{"ionicons":"5.2.3"},"_hasShrinkwrap":false,"collection:main":"dist/collection/index.js","devDependencies":{"jest":"26.6.1","eslint":"^7.10.0","jest-cli":"26.6.1","puppeteer":"~5.4.1","@types/jest":"26.0.15","@stencil/core":"2.2.0","@types/puppeteer":"~3.0.4","eslint-plugin-node":"^11.1.0","eslint-plugin-import":"^2.22.1","eslint-plugin-promise":"^4.2.1","eslint-config-standard":"^14.1.1","eslint-plugin-standard":"^4.0.1","@typescript-eslint/parser":"^4.2.0","@typescript-eslint/eslint-plugin":"^4.2.0"},"_npmOperationalInternal":{"tmp":"tmp/ae-icon5_1.3.0_1604558384362_0.4601931791604128","host":"s3://npm-registry-packages"}},"1.4.0":{"name":"@adaept/ae-icon5","version":"1.4.0","author":{"name":"adaept"},"license":"MIT","_id":"@adaept/ae-icon5@1.4.0","maintainers":[{"name":"peterennis","email":"peterennis@yahoo.com"}],"homepage":"https://aeicon5.web.app","bugs":{"url":"https://github.com/adaept/ae-icon5-component"},"dist":{"shasum":"e804be6b84230278e4cc32955a95f2d666288c86","tarball":"https://registry.npmjs.org/@adaept/ae-icon5/-/ae-icon5-1.4.0.tgz","fileCount":48,"integrity":"sha512-YFzCuMazuQeFmeBJBpvT1gHeXKOIq375XpEK2p6GUYBYSQ7XNm0hOXFMfqlkHw9J0ttBtDD228benj1ZFeXn5A==","signatures":[{"sig":"MEUCIQCHCFaDGvhyr2tL7RYvx9FFcv/LzfP2rur73/z+hdQbYAIgaLryZbNki4Sl4SR9urCvhxXWEhcAAU+5syXsiT1dWTg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":518986},"main":"dist/index.cjs.js","types":"dist/types/index.d.ts","unpkg":"dist/aeicon5/aeicon5.esm.js","module":"dist/index.js","engines":{"node":">=22"},"gitHead":"8f2e2bf374ae65a145210b9e57002d525b62369d","private":false,"scripts":{"lint":"eslint .","test":"stencil test --spec --e2e","build":"stencil build","smoke":"node testing/smoke.mjs","start":"stencil build --dev --watch --serve","lint.fix":"eslint . --fix","prebuild":"node scripts/gen-build-stamp.mjs","prestart":"node scripts/gen-build-stamp.mjs","gen.stamp":"node scripts/gen-build-stamp.mjs","now-build":"stencil build","test.unit":"vitest run","test.watch":"stencil test --spec --e2e --watchAll","check.guide":"node scripts/check-guide-pins.mjs","check.icons":"node scripts/check-icon-manifest.mjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"peterennis","email":"peterennis@yahoo.com"},"collection":"dist/collection/collection-manifest.json","repository":{"url":"git+https://github.com/adaept/ae-icon5-component.git","type":"git"},"_npmVersion":"8.12.1","description":"adaept Icon5 Component","directories":{},"_nodeVersion":"22.22.3","dependencies":{"ionicons":"^8.0.13"},"_hasShrinkwrap":false,"customElements":"dist/components/index.js","collection:main":"dist/collection/index.js","devDependencies":{"jest":"^29.7.0","jsdom":"^26.1.0","eslint":"^9.39.4","vitest":"^4.1.8","globals":"^16.5.0","jest-cli":"^29.7.0","puppeteer":"^24.1.0","@eslint/js":"^9.39.4","typescript":"~5.9.3","@types/jest":"^29.5.14","@stencil/core":"^4.43.5","typescript-eslint":"^8.60.1"},"_npmOperationalInternal":{"tmp":"tmp/ae-icon5_1.4.0_1786054701655_0.6271792214002063","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@adaept/ae-icon5","version":"1.5.0","private":false,"description":"adaept Icon5 Component","homepage":"https://aeicon5.web.app","main":"dist/index.cjs.js","module":"dist/index.js","unpkg":"dist/aeicon5/aeicon5.esm.js","types":"dist/types/index.d.ts","customElements":"dist/components/index.js","collection":"dist/collection/collection-manifest.json","collection:main":"dist/collection/index.js","scripts":{"gen.stamp":"node scripts/gen-build-stamp.mjs","gen.iconlinemap":"node scripts/gen-icon-line-map.mjs","prebuild":"node scripts/gen-build-stamp.mjs && node scripts/gen-icon-line-map.mjs","build":"stencil build","now-build":"stencil build","prestart":"node scripts/gen-build-stamp.mjs && node scripts/gen-icon-line-map.mjs","start":"stencil build --dev --watch --serve","test":"stencil test --spec --e2e","test.watch":"stencil test --spec --e2e --watchAll","lint":"eslint .","lint.fix":"eslint . --fix","check.icons":"node scripts/check-icon-manifest.mjs","check.guide":"node scripts/check-guide-pins.mjs","test.unit":"vitest run","smoke":"node testing/smoke.mjs","e2e.testids":"node testing/e2e.testids.mjs","prepublishOnly":"npm run build"},"dependencies":{"ionicons":"^8.1.0"},"devDependencies":{"@eslint/js":"^9.39.4","@stencil/core":"^4.44.0","@types/jest":"^29.5.14","eslint":"^9.39.4","globals":"^16.5.0","jest":"^29.7.0","jest-cli":"^29.7.0","jsdom":"^26.1.0","puppeteer":"^25.6.0","typescript":"~5.9.3","typescript-eslint":"^8.60.1","vitest":"^4.1.8"},"engines":{"node":">=22"},"repository":{"type":"git","url":"git+https://github.com/adaept/ae-icon5-component.git"},"author":{"name":"adaept"},"license":"MIT","bugs":{"url":"https://github.com/adaept/ae-icon5-component"},"gitHead":"dc5a23fb1463f6d359eb1b14237f705728e5f213","_id":"@adaept/ae-icon5@1.5.0","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-AlAvfNgFTXl2WfBScmPKbG5DCxvJWF7noEH1csFgKazXxDn438eNBABR3KGPHvF2aaU0JSc9sLF3e8ZpeL50Gg==","shasum":"12158d6a8b2487b7ac1770caf4658b217ab2197a","tarball":"https://registry.npmjs.org/@adaept/ae-icon5/-/ae-icon5-1.5.0.tgz","fileCount":48,"unpackedSize":560540,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG7zBCiFiyKsJncMlB+VIEmk7CDzIatoZwFhE4w9YSUGAiA2hgUi6uq+kovn75RBNcj2NQWam3cgoJ1tivpiVK7zNg=="}]},"_npmUser":{"name":"peterennis","email":"peterennis@yahoo.com"},"directories":{},"maintainers":[{"name":"peterennis","email":"peterennis@yahoo.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ae-icon5_1.5.0_1787263518971_0.586819430112578"},"_hasShrinkwrap":false}},"time":{"created":"2020-11-04T04:24:49.917Z","modified":"2026-08-20T22:05:19.360Z","1.2.3":"2020-11-04T04:24:50.190Z","1.3.0":"2020-11-05T06:39:44.516Z","1.4.0":"2026-08-06T22:18:21.858Z","1.5.0":"2026-08-20T22:05:19.134Z"},"bugs":{"url":"https://github.com/adaept/ae-icon5-component"},"author":{"name":"adaept"},"license":"MIT","homepage":"https://aeicon5.web.app","repository":{"type":"git","url":"git+https://github.com/adaept/ae-icon5-component.git"},"description":"adaept Icon5 Component","maintainers":[{"name":"peterennis","email":"peterennis@yahoo.com"}],"readme":"# @adaept/ae-icon5\n\nA small [Stencil](https://stenciljs.com/) web component that renders\n[ionicons](https://ionic.io/ionicons) (and adaept logo/ambigram SVGs) as\n`<ae-icon5-component>`. Shadow DOM, themeable via CSS custom properties.\n\n- **npm:** `@adaept/ae-icon5` · **element:** `<ae-icon5-component>` · **demo:** https://aeicon5.web.app\n- Built on ionicons 8 / Stencil 4.\n\n---\n\n## Install\n\n```bash\nnpm i @adaept/ae-icon5\n```\n\n## Register the element\n\nThere are two builds. Pick one.\n\n**1. Custom elements (tree-shakable — recommended).** Imports only what you use and\nself-registers the tag:\n\n```js\nimport '@adaept/ae-icon5/dist/components';   // defines <ae-icon5-component>\n```\n\n**2. Lazy loader (back-compat).** Registers the component lazily at runtime:\n\n```js\nimport { defineCustomElements } from '@adaept/ae-icon5/dist/loader';\ndefineCustomElements();\n```\n\nThen use it anywhere in HTML:\n\n```html\n<ae-icon5-component name=\"football\" aesize=\"ae48\"></ae-icon5-component>\n```\n\n> `name` is an ionicons icon name. ionicons fetches the SVG at runtime, so the icon set\n> must be available to the host app (a build-time icon manifest is planned — see the\n> modernization plan §5).\n\n---\n\n## How it works\n\n`<ae-icon5-component>` renders an inner `<ion-icon>` inside its **shadow DOM**. Because the\ninner icon is encapsulated, you style it through **CSS custom properties**, which pierce the\nshadow boundary — no `::part` needed for the common cases.\n\n### Sizing — `aesize`\n\nUse `aesize=\"aeNN\"` where `NN` is the pixel size (multiples of 8, `ae16`…`ae128`, plus\n`ae192`…`ae1024`):\n\n```html\n<ae-icon5-component name=\"rocket\" aesize=\"ae64\"></ae-icon5-component>\n```\n\nStroke-width variants for outline icons use `aeswNN` (`aesw32`…`aesw80`):\n\n```html\n<ae-icon5-component name=\"football-outline\" aesize=\"aesw48\"></ae-icon5-component>\n```\n\n### Coloring icons\n\nThere are **two** ways to color an icon, by design:\n\n| You want… | Use | Example |\n|---|---|---|\n| an **Ionic theme color** | the `color` attribute (`primary`, `secondary`, `tertiary`, `success`, `warning`, `danger`, `light`, `medium`, `dark`) | `color=\"success\"` |\n| **any other color** (hex, `rgb()`, CSS named color, a var) | the `--ae-color` custom property | `style=\"--ae-color: mediumvioletred\"` |\n\n```html\n<!-- theme color (resolved by ionicons) -->\n<ae-icon5-component name=\"checkmark\" color=\"success\" aesize=\"ae32\"></ae-icon5-component>\n\n<!-- any CSS color via the custom property -->\n<ae-icon5-component name=\"heart\" style=\"--ae-color: #ed2939\" aesize=\"ae32\"></ae-icon5-component>\n<ae-icon5-component name=\"leaf\" style=\"--ae-color: seagreen\" aesize=\"ae32\"></ae-icon5-component>\n```\n\nYou can also set `--ae-color` from a stylesheet to theme many icons at once:\n\n```css\nae-icon5-component { --ae-color: rebeccapurple; }\n```\n\n`--ae-color` falls back to `--color` (default `pink`) when unset.\n\n> **Migration note (v1.4.0):** earlier versions bundled ~100 named-web-color classes\n> (`color=\"mediumvioletred\"`, `color=\"papayawhip\"`, …) **inside** the component. Those were\n> demo-only and have been **removed from the shipped component** to keep it lean. Ionic theme\n> colors via `color=` are unchanged; for everything else use `--ae-color`. The demo\n> (`src/index.html`) shows the pattern.\n\n### Themeable hover\n\nHovering an icon draws a ring. It is fully configurable through CSS custom properties\n(defaults shown). The old hardcoded red square ring is gone:\n\n```css\nae-icon5-component {\n  --ae-hover-ring-color: var(--ae-color, rebeccapurple); /* ring color — see below */\n  --ae-hover-ring-width: 0.0625em;     /* ring thickness — in em, see below       */\n  --ae-hover-radius: 50%;              /* shape: 50% = circle, 0 = square         */\n  --ae-hover-clip-path: none;          /* non-round/square shapes, e.g. a pentagon */\n  --ae-hover-inset: 0;                 /* pulls the ring in from the icon's box edge */\n  --ae-hover-scale: 1;                 /* zoom on hover: 1 = none, e.g. 1.5        */\n  --ae-hover-bg: transparent;          /* fill behind the icon on hover           */\n}\n```\n\nThe ring/shape renders on a layer behind the icon (not on the icon itself), so it never clips the\nicon's own artwork regardless of shape.\n\n**Ring color defaults:** an icon colored via `--ae-color` or an Ionic `color=\"…\"` theme\nattribute gets a ring in that same color; an icon with no color of its own (still the\n`pink` default) gets a **rebeccapurple** ring instead of pink-on-pink, so hover stays\nvisible/distinct without you having to set anything.\n\n**Ring width scales with icon size:** the default is `em`, not a fixed pixel value, so the\nring stays proportionally the same thickness whether the icon is `aesize=\"ae16\"` or\n`aesize=\"ae1024\"` (`em` resolves against the icon's own font-size, which is what `aesize`/\n`aesw*` set). `0.0625em` looks like a 2px ring at the demo's dominant `aesize=\"ae32\"`. Override\nwith a fixed `px` value instead if you want a constant ring width regardless of icon size.\n\nExample — a thick blue square that zooms slightly on hover:\n\n```css\nae-icon5-component.fancy {\n  --ae-hover-ring-color: #1e90ff;\n  --ae-hover-ring-width: 4px;\n  --ae-hover-radius: 0;\n  --ae-hover-scale: 1.2;\n}\n```\n\n### Hover-effect presets — `aetype`\n\n> **New in v1.5.0:** `aetype` was a documented but inert (WIP, no-op) prop in earlier versions —\n> it now actually drives the hover effect described below, plus the new `aerotatedeg` prop.\n\n`aetype` selects a named preset on top of the CSS custom properties above, so most consumers don't\nneed to hand-write `--ae-hover-*` at all (modernization plan §4.1):\n\n| `aetype` | Hover effect | Demo `id` | Status |\n|---|---|---|---|\n| `round` | circular ring (default, unchanged) | `1` | implemented |\n| `square` | square ring | `2` | implemented |\n| `pentagon` | true regular pentagon ring — a filled donut shape (`clip-path: polygon(evenodd, …)`, an outer + inner pentagon), not a `box-shadow` ring like the others, so it stays a complete outline instead of clipping into disconnected points | `3` | implemented |\n| `rotate` | rotates by `--ae-hover-rotate-deg` (`aerotatedeg` prop, default `180`) — no ring, pure rotation | `0` (header ae logo) | implemented |\n| `pulse` | pulsing scale animation | `4` | **not implemented — follow-up cycle** |\n\n```html\n<ae-icon5-component name=\"add-circle\" aetype=\"square\" aesize=\"ae48\"></ae-icon5-component>\n<ae-icon5-component name=\"refresh-circle\" aetype=\"pentagon\" aesize=\"ae48\"></ae-icon5-component>\n<ae-icon5-component src=\"assets/aeicons/ae-logo.svg\" adaept=\"adaept\" aetype=\"rotate\" aerotatedeg=\"180\"></ae-icon5-component>\n```\n\nThe `--ae-hover-*` custom properties stay the escape hatch — setting them directly always works,\nwith or without `aetype`.\n\n### Props (current)\n\n| Prop | Type | Notes |\n|---|---|---|\n| `name` | string | ionicons icon name (e.g. `football`, `add-circle-outline`) |\n| `aesize` | string | size class, `aeNN` / `aeswNN` |\n| `color` | string | Ionic **theme** color only (use `--ae-color` for others) |\n| `src` | string | URL to an SVG (used with `adaept`) |\n| `adaept` | string | render mode: `aelogos`, `namigram`, `mydataform`/`mydatapanel`, `adaept` |\n| `arialabel` | string | accessibility label, applied as `aria-label` on the inner `<ion-icon>`; defaults to `name` if not set (see below) |\n| `decorative` | boolean | when `true`, the inner `<ion-icon>` gets `aria-hidden=\"true\"` and no `aria-label` instead — for icons that are fragments of a larger decorative group whose *container* carries the meaningful label (see the `adaeptZone` demo row) |\n| `aetype` | string | hover-effect preset: `round` / `square` / `pentagon` / `rotate` (see [Hover-effect presets](#hover-effect-presets--aetype) above); `pulse` is planned but not yet implemented |\n| `aerotatedeg` | number | rotation angle in degrees for `aetype=\"rotate\"`'s hover effect (default `180`); ignored for other `aetype` values |\n\n**`arialabel` defaults to `name`** — every icon gets a sensible accessible name out of the box.\nSet `arialabel` explicitly only when you want something other than the icon name, e.g.\n`arialabel=\"Close\"` for a `name=\"close\"` icon used as a dismiss button:\n\n```html\n<ae-icon5-component name=\"close\" arialabel=\"Close\" aesize=\"ae24\"></ae-icon5-component>\n```\n\n---\n\n## Icon sources & scoped icons\n\nBy default `<ion-icon name=\"…\">` fetches its SVG from ionicons **at runtime**. To avoid\nthat network fetch (and to let host apps drop a wholesale copy of all ionicons SVGs), this\ncomponent ships a small **build-time manifest** that registers a curated default set from\nionicons' ES modules via `addIcons` — bundled, no fetch.\n\n- **Default set** — a curated list (`src/icons/manifest.ts`, ~34 icons: the sport balls,\n  common app/menu/fab icons). These render from bundled data. Any name **not** in the set\n  still falls back to ionicons' runtime fetch, so large galleries keep working.\n- **Register your own** — bundle exactly the icons your app uses (this is how a host app\n  drops the full ionicons SVG copy):\n\n  ```js\n  import { registerIcons } from '@adaept/ae-icon5';      // icon utilities (package root)\n  import { home, settings, search } from 'ionicons/icons';\n\n  registerIcons({ home, settings, search }); // kebab name → SVG data, bundled\n  ```\n\n  `registerIcons` is a thin wrapper over ionicons' `addIcons` (also re-exported), so\n  `import { addIcons } from 'ionicons'` works identically if you prefer.\n\n- **Why ES imports?** Named imports from `ionicons/icons` are tree-shaken to just what you\n  register, and if ionicons **renames or removes** an icon, your build fails on the missing\n  export instead of silently rendering a blank (a runtime 404). The bundled manifest is\n  guarded in CI:\n\n  ```bash\n  npm run check.icons   # validates every manifest name against the installed ionicons\n  ```\n\n### Icon `set` (source) — `set`\n\nThe `set` prop selects the icon source. Only `ionicons` is implemented this cycle (the\ndefault); it is the seam for adding providers such as Iconify later **without** API changes:\n\n```html\n<ae-icon5-component name=\"football\" set=\"ionicons\"></ae-icon5-component>\n```\n\n> **Roadmap:** Iconify (`set=\"iconify:mdi\"`, …) is planned for ≈ v1.6.0 (modernization plan\n> §6 / D3). Unknown sets fall back to `ionicons`.\n\n---\n\n## Demo\n\nThe showcase in `www/` is deployed to **https://aeicon5.web.app**. It is built separately\nfrom the published component and carries a **build stamp** in the footer:\n\n```\n8.0.13/4.43.5/1.4.0 · 75124fa@master · built 2026-06-05T…Z\n```\n\n— the **version triple** `ionicons/Stencil/component` plus the git sha, branch and build\ntime. It is generated by `scripts/gen-build-stamp.mjs` (run automatically via the `prebuild`\n/ `prestart` npm hooks) into `src/assets/build-stamp.js`, which is **demo-only** and never\nimported by the published component.\n\nClicking any icon in the demo also shows a **source** link in the click-info panel, pointing at\nthe first line in `src/index.html` where that icon `name` is used — a quick way to jump from\n\"I like how this looks\" to a working code example. The `name -> line` lookup is generated by\n`scripts/gen-icon-line-map.mjs` (same `prebuild`/`prestart` hooks) into\n`src/assets/icon-line-map.js`, also demo-only. Icons rendered via `src` instead of `name` (e.g.\nthe `adaeptZone` marks) have no line to link to, so the panel just omits it.\n\nThe **`adaeptZone`** row (the \"adaept\" hover animation) renders from\n`src/assets/{at,dp,ae,pd,ta}.svg` — vendored copies of the canonical marks in\n`adaept5tudio/design-system/assets/` (a sibling repo; see that repo's `design-system/README.md`\nand `rvw/Code_review 2026-08-14.md` here). There's no cross-repo build link, so re-sync those\nfiles by hand when the design-system source changes — each vendored file's header comment says\nwhere it came from.\n\n---\n\n## Develop\n\n```bash\nnpm start          # Stencil dev server (watch + serve) at the demo\nnpm run build      # build dist + dist-custom-elements + www\nnpm run lint       # ESLint 9 flat config\n```\n\n**Local dev against aedh without publishing** — use `npm pack` (not `npm link`):\n\n```bash\nnpm pack                                   # → adaept-ae-icon5-<version>.tgz\n# in aedh:\nnpm i ../ae-icon5-component/adaept-ae-icon5-<version>.tgz\n```\n\n## Test\n\n```bash\nnpm test           # component specs — Stencil/Jest (newSpecPage)\nnpm run test.unit  # Vitest POC (pure unit, jsdom) — the Vitest baseline\nnpm run smoke      # Puppeteer smoke: self-serves ./www, asserts it renders\nnpm run e2e.testids # Puppeteer, typed data-testid selectors (testing/test-ids.mjs)\nnpm run check.icons # validate the scoped-icon manifest vs installed ionicons\nnpm run check.guide # validate docs/THIRD-PARTY-GUIDE.md pins vs package.json\n```\n\n- **Specs** stay on Stencil's built-in **Jest** (`*.spec.ts`); the full Jest → Vitest\n  crossover is deferred to sync with aedh (plan §12 / D4).\n- **Smoke** runs against the local `www` by default; set `BASE_URL` to hit the deployed\n  demo: `BASE_URL=https://aeicon5.web.app npm run smoke`.\n- **`e2e.testids`** is a separate, typed-selector test (dev plan A22) — it sets\n  `window.__AE_E2E__` before navigating so `testing/test-ids.mjs`'s `data-testid` attributes\n  attach, then asserts against them (currently: the demo's build-stamp element). A normal\n  `smoke` run, or any real page load, never sets that flag — verified empirically that a normal\n  load carries zero `data-testid` attributes. Cross-project id registry:\n  `adaept5tudio/docs/e2e-testing-strategy.md` §5a.\n\n## CI / Release\n\n- **`.github/workflows/ci.yml`** — on push/PR to `master`: install → lint → `check.icons`\n  → build → spec tests → Vitest → smoke the built demo.\n- **`.github/workflows/release.yml`** — on a `v*` tag: build + test → `npm publish` via\n  **Trusted Publishing (OIDC, no token)** → deploy `www/` to the **aeicon5** Firebase site\n  (needs `FIREBASE_SERVICE_ACCOUNT`) → smoke the deployed demo → GitHub Release.\n\n### Release runbook (maintainer)\n\nA `v*` tag triggers `.github/workflows/release.yml`: build + test → `npm publish` (Trusted\nPublishing, OIDC, no token) → deploy `www/` to Firebase → smoke test → GitHub Release. See\n[CI / Release](#ci--release) above for the high-level flow.\n\nThe step-by-step **studio-internal** setup (npm org membership, 2FA, Firebase/GitHub secrets,\ntroubleshooting, fallbacks) is **adaept-specific operational detail**, not something an npm\nconsumer or a third-party dev copying this pattern needs — it's maintained privately in\nadaept5tudio's `docs/ae-icon5-release-runbook.md`, not in this public repo. If you're building\nyour own package from this one, the generic (non-adaept) version of \"wire up trusted publishing\"\nis in [`docs/THIRD-PARTY-GUIDE.md`](docs/THIRD-PARTY-GUIDE.md) §7.\n\n## Build your own icon component package (recipe)\n\nA bullet-proof, reproducible procedure to create a package like this one — a Stencil web\ncomponent that wraps an icon set, ships tree-shakable + lazy builds, themeable styling, a\nbuild-stamped demo, and a publish/deploy pipeline. Each step names the **canonical file in\nthis repo** to copy from. A fuller, version-pinned procedural guide lives at\n[`docs/THIRD-PARTY-GUIDE.md`](docs/THIRD-PARTY-GUIDE.md) (its pins are CI-checked against\n`package.json` via `npm run check.guide`).\n\n> **Pinned toolchain** (keep these in sync): Node **22**, `@stencil/core` **^4.43**,\n> `ionicons` **^8**, `typescript` **~5.9**, `eslint` **9** flat + `typescript-eslint` **8**,\n> `jest` **29**, `puppeteer` **25**, `vitest` **4** + `jsdom`.\n\n**1. Scaffold + pin the toolchain.**\n- `npm init stencil@latest component my-icons` (choose the *component* starter), then `cd my-icons`.\n- Set `\"engines\": { \"node\": \">=22\" }` and pin the versions above in `package.json`\n  (copy the `dependencies` / `devDependencies` blocks from this repo's [`package.json`](package.json)).\n- `npm install`.\n\n**2. Output targets** — edit [`stencil.config.ts`](stencil.config.ts):\n- `dist-custom-elements` with `customElementsExportBehavior: 'auto-define-custom-elements'` (primary, tree-shakable),\n- `dist` (lazy loader, back-compat), and `www` (demo). Keep `shadow: true` on the component.\n\n**3. Component + themeable CSS** — model on\n[`src/components/ae-icon5-component/`](src/components/ae-icon5-component):\n- Render an inner `<ion-icon>`; forward `name`/`color`.\n- Theme through **CSS custom properties** (they pierce shadow DOM): a `--xx-color` for arbitrary\n  colors (theme colors stay on the `color=` attribute) and `--xx-hover-*` for the hover ring.\n  **Do not** bundle a big named-color palette in the component (it bloats every consumer).\n- Start timers in `connectedCallback` and clear them in `disconnectedCallback` (never in the constructor).\n\n**4. Scoped icons (the important bit)** — model on [`src/icons/`](src/icons):\n- `manifest.ts` maps kebab `name` → **named ES imports** from `ionicons/icons` (NOT\n  `import * as` — that defeats tree-shaking). Register them with `addIcons` on\n  `componentWillLoad`.\n- Re-export `addIcons` + a `registerIcons(map)` helper from a package-root\n  [`src/index.ts`](src/index.ts) so consumers bundle their own icons (no runtime SVG fetch).\n- Add an icon-source *seam* (a `set` prop) even if you only implement one source, so others slot\n  in later without API churn.\n\n**5. Build stamp + demo** — copy [`scripts/gen-build-stamp.mjs`](scripts/gen-build-stamp.mjs):\n- Generate `src/assets/build-stamp.js` (git sha/branch/time + the `iconset/Stencil/component`\n  version triple) via `prebuild` / `prestart` npm hooks; show it in the demo footer. Gitignore it.\n\n**6. Tests + a rename guard** — copy [`scripts/check-icon-manifest.mjs`](scripts/check-icon-manifest.mjs),\n[`testing/smoke.mjs`](testing/smoke.mjs), [`vitest.config.ts`](vitest.config.ts):\n- Spec tests on Stencil/Jest (`*.spec.ts`); a Vitest POC under `test/**/*.vitest.ts`; a\n  Puppeteer smoke that self-serves `./www`; optionally, typed `data-testid` selectors\n  ([`testing/test-ids.mjs`](testing/test-ids.mjs) + [`testing/e2e.testids.mjs`](testing/e2e.testids.mjs))\n  if the demo needs finer-grained E2E coverage than smoke's generic checks.\n- `check.icons` validates every manifest name against the **installed** icon set — so a renamed\n  icon fails the build instead of silently 404-ing.\n\n**7. CI + release** — copy [`.github/workflows/ci.yml`](.github/workflows/ci.yml) and\n[`release.yml`](.github/workflows/release.yml):\n- CI: install → lint → `check.icons` → build → Jest → Vitest → smoke.\n- Release (on `v*` tag): publish to npm + deploy the demo + GitHub Release.\n- **Publish with npm Trusted Publishing (OIDC) — no token to store/rotate.** Register your\n  repo+workflow as a trusted publisher on the npm package and give the job\n  `permissions: id-token: write` + npm ≥ 11.5.1 (see [`docs/THIRD-PARTY-GUIDE.md`](docs/THIRD-PARTY-GUIDE.md)\n  §7 for the generic step-by-step). For the demo deploy add a **`FIREBASE_SERVICE_ACCOUNT`**\n  secret. _(Token fallback exists if OIDC isn't an option — see the guide.)_\n\n**8. Package hygiene (don't ship the demo to consumers).** In `package.json`:\n- Entry fields: `main` (cjs), `module` (esm), `unpkg`, `types` → `dist/types/index.d.ts`,\n  `customElements` → `dist/components/index.js`. Remove any stale `es2015`/`es2017` entries.\n- `files`: ship `dist/` but **negate the runtime-fetch SVG copy and demo assets** so they\n  don't bloat consumers:\n  ```jsonc\n  \"files\": [\"dist/\", \"!dist/<namespace>/svg\", \"!dist/<namespace>/svg/**\",\n            \"!dist/collection/assets\", \"!dist/collection/assets/**\"]\n  ```\n- Add `\"prepublishOnly\": \"npm run build\"`. Verify with **`npm publish --dry-run`** (check the\n  file list — no demo svgs / no build-stamp leak).\n- Set `homepage` to the deployed demo URL.\n\n**9. Publish.** Bump `version`, commit, then `git tag vX.Y.Z && git push origin vX.Y.Z` — the\nrelease workflow does the rest.\n\n> **Maintainers:** the dedicated [`docs/THIRD-PARTY-GUIDE.md`](docs/THIRD-PARTY-GUIDE.md) must be\n> kept in sync with each release (review §8, CF-10). Its pinned toolchain is **CI-enforced** —\n> `npm run check.guide` fails if the guide's pins drift from `package.json`. When the versions\n> above change, update both this recipe and that guide.\n\n## License\n\nMIT © adaept\n","readmeFilename":"README.md"}