{"_id":"@afixt/apg-react","_rev":"8-2e3b09c0d047a7f7c4f4e8d6d0f4d5c5","name":"@afixt/apg-react","dist-tags":{"latest":"2.3.0"},"versions":{"1.0.0":{"name":"@afixt/apg-react","version":"1.0.0","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@1.0.0","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"d86fafd15f61134303d67050743085b4dc3c9e27","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-1.0.0.tgz","fileCount":11,"integrity":"sha512-crxunlww/kdj+y6dm49GBS9qCeESwXU2H48V/xooWV6SbFQO1lTExSlNwXPqVDXdmc7c6r8G+jTHAqBFWNMQQw==","signatures":[{"sig":"MEQCIBG1k/0/UN3LtOFC1j2Tn0RHIoZp7eCakNCHUvXwUVIdAiAnIUtHlg4ZaYaWnNNXbIVbu/DTdHqqNMTpzcQmmFZO/A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":774638},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./variables.css":"./components/variables.css"},"gitHead":"b0a8188275c916c613527dce4e451f7886ee1253","scripts":{"test":"jest","build":"rollup -c && cp index.d.ts dist/index.d.ts","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","storybook":"storybook dev -p 6006","markdownlint":"markdownlint **/*.md --ignore node_modules","prepublishOnly":"npm run build","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"10.2.4","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.4.21","react":"^18.2.0","rollup":"^4.0.0","puppeteer":"^21.6.1","react-dom":"^18.2.0","storybook":"^8.6.18","babel-jest":"^29.7.0","prop-types":"^15.8.1","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","react-router-dom":"^6.21.1","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","@babel/preset-react":"^7.23.3","react-test-renderer":"^18.2.0","@rollup/plugin-babel":"^6.0.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-commonjs":"^26.0.0","@testing-library/jest-dom":"^6.2.0","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","@storybook/addon-interactions":"^8.6.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"peerDependenciesMeta":{"react-router-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/apg-react_1.0.0_1776304946239_0.7245229697550006","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@afixt/apg-react","version":"1.1.0","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@1.1.0","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"09735d2d160137e9a9b0722dcf5f5e0ce6b292bc","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-1.1.0.tgz","fileCount":42,"integrity":"sha512-wOEfGDsT6ZxEuSDWSRA9e/lT7/XnJGGyt8y4p1nE3cyUg4mpsZ7vYhG8laRlxACOfIZBZhlIWl1Ffj2oxUaVBg==","signatures":[{"sig":"MEUCIChLy46CCPJfnPK0G+86vIPq8BxEOni/v+vtpiF2J1WGAiEAi1z7pMPw21oP9rbDG6IDyfEVHy1SmVf/bgWi+TVpo4s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":674931},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./variables.css":"./components/variables.css"},"gitHead":"0d3518402cb8b431f322ba0a2ef2d12e2a14d6ac","scripts":{"test":"jest","build":"rollup -c","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","storybook":"storybook dev -p 6006","markdownlint":"markdownlint **/*.md --ignore node_modules","prepublishOnly":"npm run build","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"10.2.4","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.4.21","react":"^18.2.0","tslib":"^2.8.1","rollup":"^4.0.0","puppeteer":"^21.6.1","react-dom":"^18.2.0","storybook":"^8.6.18","babel-jest":"^29.7.0","prop-types":"^15.8.1","typescript":"^6.0.2","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","react-router-dom":"^6.21.1","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","@babel/preset-react":"^7.23.3","react-test-renderer":"^18.2.0","@rollup/plugin-babel":"^6.0.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-commonjs":"^26.0.0","@babel/preset-typescript":"^7.28.5","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","@storybook/addon-interactions":"^8.6.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"peerDependenciesMeta":{"react-router-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/apg-react_1.1.0_1776343193434_0.7470524629441857","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@afixt/apg-react","version":"1.1.1","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@1.1.1","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"f2485ba3679ed4d776da3b4a6253d58e2280ed31","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-1.1.1.tgz","fileCount":42,"integrity":"sha512-cg13PdkXIatiXL+DuMkqwBMSDb2CODzKTa/Y/Y95ERx0/pqFDsLzvg1XgpaCrKKbo55gFbxtOpQqfRsgyl0GVA==","signatures":[{"sig":"MEUCIQD8FXV+l6knNwM4Fz1+Ukmws6Hn93o5/gl9vrJADpzybAIgapZGLLyR/R4reUvvpJiZcY8Uwdtc8j9hevR42kmBGSo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":674980},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./variables.css":"./components/variables.css"},"gitHead":"0d3518402cb8b431f322ba0a2ef2d12e2a14d6ac","scripts":{"test":"jest","build":"rollup -c","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","storybook":"storybook dev -p 6006","markdownlint":"markdownlint **/*.md --ignore node_modules","prepublishOnly":"npm run build","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"10.2.4","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.4.21","react":"^18.2.0","tslib":"^2.8.1","rollup":"^4.0.0","puppeteer":"^21.6.1","react-dom":"^18.2.0","storybook":"^8.6.18","babel-jest":"^29.7.0","prop-types":"^15.8.1","typescript":"^6.0.2","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","react-router-dom":"^6.21.1","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","@babel/preset-react":"^7.23.3","react-test-renderer":"^18.2.0","@rollup/plugin-babel":"^6.0.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-commonjs":"^26.0.0","@babel/preset-typescript":"^7.28.5","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","@storybook/addon-interactions":"^8.6.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"peerDependenciesMeta":{"react-router-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/apg-react_1.1.1_1776343582494_0.14415620837231313","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@afixt/apg-react","version":"1.2.0","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@1.2.0","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"2e8d8d8ec8bf158d4c8c0ecc22816f5b8ce5fcd7","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-1.2.0.tgz","fileCount":42,"integrity":"sha512-mOgfGk19i0urhw7OUuzD8QSwjdgLiWQ3lstYi5lA+Ti5DPZ8JxFPTTlP/oyuUTFlcdfWFLQLr3pk3ngXA00nug==","signatures":[{"sig":"MEYCIQDzJZDACoaJ5xK33eRs9OutabAo/QOwvTzIZeY93r5CvAIhAKREf0mHe6UQBlYkGOMj3NibMV7pY8llYJh3SUUUAwSb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":689222},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./variables.css":"./components/variables.css"},"gitHead":"a86656781f1655c67d8aa1947741d43392407210","scripts":{"test":"jest","build":"rollup -c","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","storybook":"storybook dev -p 6006","markdownlint":"markdownlint **/*.md --ignore node_modules","prepublishOnly":"npm run build","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"10.2.4","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.4.21","react":"^18.2.0","tslib":"^2.8.1","rollup":"^4.0.0","puppeteer":"^21.6.1","react-dom":"^18.2.0","storybook":"^8.6.18","babel-jest":"^29.7.0","prop-types":"^15.8.1","typescript":"^6.0.2","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","react-router-dom":"^6.21.1","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","@babel/preset-react":"^7.23.3","react-test-renderer":"^18.2.0","@rollup/plugin-babel":"^6.0.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^14.1.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-commonjs":"^26.0.0","@babel/preset-typescript":"^7.28.5","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","@storybook/addon-interactions":"^8.6.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"peerDependenciesMeta":{"react-router-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/apg-react_1.2.0_1776359020212_0.6880895844715482","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@afixt/apg-react","version":"1.3.0","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@1.3.0","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"5509302f538e7a12bdb5927b2f3b665d239179ad","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-1.3.0.tgz","fileCount":43,"integrity":"sha512-nq3URRBqbBbf7EBBmTI1jfWQW8/nTZtF5AkKpbWLM5Y+8QL5oiGjmR3zrhfp4XjIEG0gQYY0+40ySNaTgUxKTg==","signatures":[{"sig":"MEYCIQCENAacP57y6YEHVQJDZfM4QGaY6AIKEofH66mKGmLWlgIhAO6s8XPKLrzBzPUvoNa79RZJqefcOr/17GzqGHsRtmo6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":703064},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./variables.css":"./components/variables.css"},"gitHead":"66695a1ce2c38048e3ddb22a4e8dd64a1ce0eba7","scripts":{"lint":"eslint .","size":"size-limit","test":"jest","build":"rollup -c","check":"npm run typecheck && npm run lint && npm run stylelint && npm run format:check && npm run markdownlint","dupes":"jscpd","links":"lychee --no-progress '**/*.md'","format":"prettier --write .","prepare":"husky","lint:fix":"eslint . --fix","security":"npm-run-all -s security:audit security:osv security:secrets","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","check:all":"npm-run-all -s check test dupes license:check build size security:audit","storybook":"storybook dev -p 6006","stylelint":"stylelint '**/*.css' --ignore-path .gitignore","typecheck":"tsc --noEmit","format:check":"prettier --check .","markdownlint":"markdownlint-cli2 '**/*.md' '#node_modules'","security:osv":"osv-scanner --lockfile=package-lock.json","license:check":"license-checker-rseidelsohn --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;0BSD;CC0-1.0;Unlicense;Python-2.0;WTFPL;BlueOak-1.0.0' --excludePrivatePackages --summary","stylelint:fix":"stylelint '**/*.css' --ignore-path .gitignore --fix","license:report":"license-checker-rseidelsohn --production --csv --out reports/licenses.csv","prepublishOnly":"npm run build","security:audit":"npm audit --omit=dev --audit-level=high","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build","markdownlint:fix":"markdownlint-cli2 --fix '**/*.md' '#node_modules'","security:secrets":"trufflehog git file://. --only-verified --fail","security:semgrep":"semgrep --config=p/javascript --config=p/typescript --config=p/react --config=p/owasp-top-ten --config=p/security-audit --config=p/secrets --error --metrics=off"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"overrides":{"axe-core":"npm:empty-npm-package@1.0.0"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"11.12.1","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.4.2","vite":"^5.4.21","husky":"9.1.7","jscpd":"4.2.4","react":"^18.2.0","tslib":"^2.8.1","eslint":"9.39.4","rollup":"^4.0.0","globals":"17.6.0","prettier":"3.8.3","puppeteer":"^24.42.0","react-dom":"^18.2.0","storybook":"^8.6.18","stylelint":"17.12.0","tsc-files":"1.1.4","@eslint/js":"9.39.4","babel-jest":"^29.7.0","prop-types":"^15.8.1","size-limit":"12.1.0","typescript":"^6.0.2","lint-staged":"16.4.0","npm-run-all":"4.1.5","@commitlint/cli":"20.5.3","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","react-router-dom":"^7.14.2","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","markdownlint-cli2":"0.22.1","typescript-eslint":"8.60.0","@babel/preset-react":"^7.23.3","eslint-plugin-jsdoc":"^63.0.0","eslint-plugin-react":"7.37.5","react-test-renderer":"^18.2.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","eslint-plugin-promise":"7.3.0","eslint-plugin-sonarjs":"4.0.3","eslint-plugin-unicorn":"64.0.0","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^16.3.2","eslint-config-prettier":"10.1.8","eslint-plugin-import-x":"4.16.2","jest-environment-jsdom":"^30.3.0","@rollup/plugin-commonjs":"^29.0.2","@babel/preset-typescript":"^7.28.5","eslint-plugin-no-secrets":"2.3.3","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","eslint-plugin-react-hooks":"7.1.1","stylelint-config-standard":"40.0.0","@total-typescript/ts-reset":"0.6.1","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","eslint-plugin-react-refresh":"0.5.2","license-checker-rseidelsohn":"4.4.2","@double-great/stylelint-a11y":"3.4.14","@size-limit/preset-small-lib":"12.1.0","@storybook/addon-interactions":"^8.6.14","@commitlint/config-conventional":"20.5.3","prettier-plugin-organize-imports":"4.3.0","stylelint-declaration-strict-value":"1.11.1"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"peerDependenciesMeta":{"react-router-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/apg-react_1.3.0_1785422565468_0.34014709846783564","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@afixt/apg-react","version":"2.2.0","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","_id":"@afixt/apg-react@2.2.0","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"homepage":"https://github.com/AFixt/apg-react#readme","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"f5247f8c46f8b1f16cc924d4f4eb0a45cfa8fed4","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-2.2.0.tgz","fileCount":49,"integrity":"sha512-ELCx3DkH7QmVjh5OyD5jIXmlYGX0AUHUyA7EAKcrV5GNvGd+2sA4ArTqRwv7W77KUJH2miEtkOsAqTNLHjXvTw==","signatures":[{"sig":"MEUCIBzg5+i0QeHe+8uYGMWv3gt+cZAD3eyrw5sGSL9cGjBmAiEA3fOEDe8xOkG7oajzMGTRgEDW348XiT+4A45J4XwzwtA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1087767},"main":"dist/index.cjs.js","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./package.json":"./package.json","./variables.css":"./components/variables.css"},"gitHead":"ef00dfc0a22cd138511d730bb06101e1a5c6070f","scripts":{"lint":"eslint .","size":"size-limit","test":"jest","build":"npm run clean && rollup -c","check":"npm run typecheck && npm run lint && npm run stylelint && npm run format:check && npm run markdownlint","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","dupes":"jscpd","links":"lychee --no-progress '**/*.md'","serve":"vite --config vite.demos.config.mjs","format":"prettier --write .","prepare":"husky","lint:fix":"eslint . --fix","security":"npm-run-all -s security:audit security:osv security:secrets","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","check:all":"npm-run-all -s check test dupes license:check build size security:audit","storybook":"storybook dev -p 6006","stylelint":"stylelint '**/*.css' --ignore-path .gitignore","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.demos.json","demos:build":"vite build --config vite.demos.config.mjs","format:check":"prettier --check .","markdownlint":"markdownlint-cli2 '**/*.md' '#node_modules'","security:osv":"osv-scanner --lockfile=package-lock.json","license:check":"license-checker-rseidelsohn --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;0BSD;CC0-1.0;Unlicense;Python-2.0;WTFPL;BlueOak-1.0.0' --excludePrivatePackages --summary","stylelint:fix":"stylelint '**/*.css' --ignore-path .gitignore --fix","license:report":"license-checker-rseidelsohn --production --csv --out reports/licenses.csv","prepublishOnly":"npm run build","security:audit":"npm audit --omit=dev --audit-level=high","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build","markdownlint:fix":"markdownlint-cli2 --fix '**/*.md' '#node_modules'","security:secrets":"trufflehog git file://. --only-verified --fail","security:semgrep":"semgrep --config=p/javascript --config=p/typescript --config=p/react --config=p/owasp-top-ten --config=p/security-audit --config=p/secrets --error --metrics=off","validate:usecases":"npx --yes @afixt/usecase-runner@2.0.2 validate usecases/"},"_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"overrides":{"uuid":"^11.1.1","axe-core":"npm:empty-npm-package@1.0.0"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"10.9.8","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.4.2","vite":"^6.4.3","husky":"9.1.7","jscpd":"4.2.4","react":"^18.2.0","tslib":"^2.8.1","eslint":"9.39.4","rollup":"^4.0.0","globals":"17.6.0","prettier":"3.8.3","puppeteer":"^24.42.0","react-dom":"^18.2.0","storybook":"^8.6.18","stylelint":"17.12.0","tsc-files":"1.1.4","@eslint/js":"9.39.4","babel-jest":"^29.7.0","prop-types":"^15.8.1","size-limit":"12.1.0","typescript":"^6.0.2","lint-staged":"16.4.0","npm-run-all":"4.1.5","@commitlint/cli":"20.5.3","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","@types/react-dom":"18.3.7","react-router-dom":"^7.14.2","@babel/preset-env":"^7.23.7","@storybook/blocks":"^8.6.14","markdownlint-cli2":"0.23.2","typescript-eslint":"8.60.0","@babel/preset-react":"^7.23.3","eslint-plugin-jsdoc":"^63.0.0","eslint-plugin-react":"7.37.5","react-test-renderer":"^18.2.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","eslint-plugin-promise":"7.3.0","eslint-plugin-sonarjs":"4.0.3","eslint-plugin-unicorn":"64.0.0","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^16.3.2","eslint-config-prettier":"10.1.8","eslint-plugin-import-x":"4.16.2","jest-environment-jsdom":"^30.3.0","@rollup/plugin-commonjs":"^29.0.2","@babel/preset-typescript":"^7.28.5","eslint-plugin-no-secrets":"2.3.3","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","eslint-plugin-react-hooks":"7.1.1","stylelint-config-standard":"40.0.0","@total-typescript/ts-reset":"0.6.1","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.14","eslint-plugin-react-refresh":"0.5.2","license-checker-rseidelsohn":"4.4.2","@double-great/stylelint-a11y":"3.4.14","@size-limit/preset-small-lib":"12.1.0","@storybook/addon-interactions":"^8.6.14","@commitlint/config-conventional":"20.5.3","prettier-plugin-organize-imports":"4.3.0","stylelint-declaration-strict-value":"1.11.1"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/apg-react_2.2.0_1787835292101_0.9919009499976328","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"_id":"@afixt/apg-react@2.3.0","bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"dist":{"shasum":"3f54dc5c5032ad1b5023bed3c13432ab7cd5d150","tarball":"https://registry.npmjs.org/@afixt/apg-react/-/apg-react-2.3.0.tgz","fileCount":49,"integrity":"sha512-hvdscAUkF3MJkZw1+ceBP2ffUrufYEhArBUX4ZSAoT4J3QnEgvDpuu2+Tmyb6wktkFkugAXAiioTNIzDqihj+A==","signatures":[{"sig":"MEUCIDfijKSDRJJcVpRRin2STdkNFUV/2Aa7uZVoHsEBvX5CAiEA6XgaZNBJdZae1gwVRT10uoI5rA7fFHxD7aZq08j18uw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCPTfXd7a2TpH/W7Y0vepqLH48BRaLytg+UbA6oDisHvwIgZfhWm12cRp5gK9VXjJX+4rDBDbF6c8FRKtgv7AsZ5qk="}],"unpackedSize":1151133},"main":"dist/index.cjs.js","name":"@afixt/apg-react","types":"dist/index.d.ts","author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"module":"dist/index.esm.js","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"},"./styles.css":"./dist/styles.css","./package.json":"./package.json","./variables.css":"./components/variables.css"},"gitHead":"feb0626b6a566ee0c3dfa18b2cfeb0b0731aaefc","license":"MIT","scripts":{"knip":"knip","lint":"eslint .","size":"size-limit","test":"jest","build":"npm run clean && rollup -c","check":"npm run typecheck && npm run lint && npm run knip && npm run stylelint && npm run format:check && npm run markdownlint","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","dupes":"jscpd","links":"lychee --no-progress '**/*.md'","serve":"vite --config vite.demos.config.mjs","format":"prettier --write .","prepare":"husky","lint:fix":"eslint . --fix","security":"npm-run-all -s security:audit security:osv security:secrets","test:all":"npm test && npm run test:e2e:build","test:e2e":"jest --config e2e/jest.config.js --runInBand","check:all":"npm-run-all -s check test dupes license:check build size security:audit","storybook":"storybook dev -p 6006","stylelint":"stylelint '**/*.css' --ignore-path .gitignore","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.demos.json","demos:build":"vite build --config vite.demos.config.mjs","format:check":"prettier --check .","markdownlint":"markdownlint-cli2 '**/*.md' '#node_modules'","security:osv":"osv-scanner --lockfile=package-lock.json","license:check":"license-checker-rseidelsohn --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;0BSD;CC0-1.0;Unlicense;Python-2.0;WTFPL;BlueOak-1.0.0' --excludePrivatePackages --summary","stylelint:fix":"stylelint '**/*.css' --ignore-path .gitignore --fix","license:report":"license-checker-rseidelsohn --production --csv --out reports/licenses.csv","prepublishOnly":"npm run build","security:audit":"npm audit --omit=dev --audit-level=high","test:e2e:build":"npm run build-storybook && npm run test:e2e","build-storybook":"storybook build","markdownlint:fix":"markdownlint-cli2 --fix '**/*.md' '#node_modules'","security:secrets":"trufflehog git file://. --only-verified --fail","security:semgrep":"semgrep --config=p/javascript --config=p/typescript --config=p/react --config=p/owasp-top-ten --config=p/security-audit --config=p/secrets --error --metrics=off","validate:usecases":"npx --yes @afixt/usecase-runner@3.0.0 validate usecases/"},"version":"2.3.0","_npmUser":{"name":"karlgroves","email":"karlgroves@gmail.com"},"homepage":"https://github.com/AFixt/apg-react#readme","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"overrides":{"uuid":"^11.1.1","axe-core":"npm:empty-npm-package@1.0.0","smol-toml":"^1.7.1"},"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"_npmVersion":"12.0.2","description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","directories":{},"maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"sideEffects":["**/*.css"],"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.4.2","knip":"6.33.0","vite":"^6.4.3","husky":"9.1.7","jscpd":"4.2.4","react":"^18.2.0","tslib":"^2.8.1","eslint":"9.39.4","rollup":"^4.0.0","globals":"17.6.0","prettier":"3.8.3","puppeteer":"^24.42.0","react-dom":"^18.2.0","storybook":"^8.6.18","stylelint":"17.12.0","tsc-files":"1.1.4","@eslint/js":"9.39.4","babel-jest":"^29.7.0","size-limit":"12.1.0","typescript":"^6.0.2","lint-staged":"16.4.0","npm-run-all":"4.1.5","@commitlint/cli":"20.5.3","@storybook/test":"^8.6.18","@storybook/react":"^8.6.18","@types/react-dom":"18.3.7","react-router-dom":"^7.14.2","@babel/preset-env":"^7.23.7","@commitlint/types":"20.5.0","markdownlint-cli2":"0.23.2","typescript-eslint":"8.60.0","@babel/preset-react":"^7.23.3","eslint-plugin-jsdoc":"^63.0.0","eslint-plugin-react":"7.37.5","react-test-renderer":"^18.2.0","@vitejs/plugin-react":"^4.7.0","@storybook/react-vite":"^8.6.18","eslint-plugin-promise":"7.3.0","eslint-plugin-sonarjs":"4.0.3","eslint-plugin-unicorn":"64.0.0","rollup-plugin-postcss":"^4.0.0","@storybook/addon-links":"^8.6.18","@testing-library/react":"^16.3.2","eslint-config-prettier":"10.1.8","eslint-plugin-import-x":"4.16.2","jest-environment-jsdom":"^30.3.0","@rollup/plugin-commonjs":"^29.0.2","@babel/preset-typescript":"^7.28.5","eslint-plugin-no-secrets":"2.3.3","@rollup/plugin-typescript":"^12.3.0","@testing-library/jest-dom":"^6.2.0","eslint-plugin-react-hooks":"7.1.1","stylelint-config-standard":"40.0.0","@total-typescript/ts-reset":"0.6.1","@rollup/plugin-node-resolve":"^16.0.0","@storybook/addon-essentials":"^8.6.18","eslint-plugin-react-refresh":"0.5.2","license-checker-rseidelsohn":"4.4.2","@double-great/stylelint-a11y":"3.4.14","@size-limit/preset-small-lib":"12.1.0","@storybook/addon-interactions":"^8.6.18","@commitlint/config-conventional":"20.5.3","prettier-plugin-organize-imports":"4.3.0","stylelint-declaration-strict-value":"1.11.1"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/apg-react_2.3.0_1789045985420_0.8126945135968031"}}},"time":{"created":"2026-04-16T02:02:26.238Z","modified":"2026-09-10T13:13:05.769Z","1.0.0":"2026-04-16T02:02:26.439Z","1.1.0":"2026-04-16T12:39:53.595Z","1.1.1":"2026-04-16T12:46:22.647Z","1.2.0":"2026-04-16T17:03:40.427Z","1.3.0":"2026-07-30T14:42:45.671Z","2.2.0":"2026-08-27T12:54:52.245Z","2.3.0":"2026-09-10T13:13:05.537Z"},"bugs":{"url":"https://github.com/AFixt/apg-react/issues"},"author":{"url":"https://www.karlgroves.com","name":"Karl Groves","email":"karlgroves@gmail.com"},"license":"MIT","homepage":"https://github.com/AFixt/apg-react#readme","keywords":["react","accessibility","a11y","aria","wai-aria","apg","components","accessible-components","design-system","keyboard-navigation","screen-reader"],"repository":{"url":"git+https://github.com/AFixt/apg-react.git","type":"git"},"description":"Accessible React components implementing every pattern in the WAI-ARIA Authoring Practices Guide (APG)","maintainers":[{"name":"macmilan","email":"marko.macmilan@gmail.com"},{"name":"jw1982","email":"john.watts@afixt.com"},{"name":"karlgroves","email":"karlgroves@gmail.com"}],"readme":"# apg-react\n\n[![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n[![npm](https://img.shields.io/npm/v/@afixt/apg-react)](https://www.npmjs.com/package/@afixt/apg-react)\n[![Storybook](https://img.shields.io/badge/storybook-live%20demo-ff4785)](https://afixt.github.io/apg-react/)\n\n**Accessible React components implementing every pattern in the\n[W3C ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/patterns/).**\n\nEach component ships with the full APG keyboard-interaction model, correct ARIA\nroles and state, focus management, and a Bootstrap-flavored visual default you\ncan restyle via CSS custom properties. Written in TypeScript with full type\ndeclarations. All user-facing strings are translatable via an optional `labels`\nprop.\n\n## Why\n\nMost component libraries treat accessibility as a checklist. This library treats\nthe APG as the specification. Every component is tested against the APG's\nkeyboard model, ARIA contract, and focus-management requirements — with **291\nunit tests**, **37 dedicated accessibility-contract tests**, and **E2E tests\ndriving a real browser**. Every assertion is implemented from first principles\nagainst the DOM.\n\n## Install\n\n```sh\nnpm install @afixt/apg-react\n```\n\nPeer dependencies:\n\n- `react` ≥ 18\n- `react-dom` ≥ 18\n\nThere are no other runtime dependencies. In particular, this library does\n**not** depend on a router — see [Router integration](#router-integration) if\nyou use one.\n\n## Quick start\n\n```tsx\nimport { Button, Accordion, ModalDialog } from '@afixt/apg-react';\nimport '@afixt/@afixt/apg-react/styles.css'; // full baseline styles\n// or, to cherry-pick tokens only:\n// import '@afixt/@afixt/apg-react/variables.css';\n\nfunction App() {\n  return <Button label=\"Save\" action={() => save()} />;\n}\n```\n\nComponents are tree-shakeable; only what you import will land in your bundle.\n\n## Components\n\nComponents are organized by the APG pattern they implement. Follow each link for\nthe official APG documentation.\n\n### Widgets\n\n| Component          | APG pattern                                                                                                      |\n| ------------------ | ---------------------------------------------------------------------------------------------------------------- |\n| `Accordion`        | [Accordion](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/)                                                 |\n| `Alert`            | [Alert](https://www.w3.org/WAI/ARIA/apg/patterns/alert/)                                                         |\n| `AlertDialog`      | [Alert Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/)                                            |\n| `Breadcrumb`       | [Breadcrumb](https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/)                                               |\n| `Button`           | [Button](https://www.w3.org/WAI/ARIA/apg/patterns/button/)                                                       |\n| `Carousel`         | [Carousel](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/)                                                   |\n| `Checkbox`         | [Checkbox (dual & tri-state)](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/)                                |\n| `CheckboxGroup`    | [Checkbox — parent/child mixed state](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/)                        |\n| `Combobox`         | [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) — supports `none`, `list`, `both`                 |\n| `Disclosure`       | [Disclosure](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/)                                               |\n| `Feed`             | [Feed](https://www.w3.org/WAI/ARIA/apg/patterns/feed/)                                                           |\n| `Grid`             | [Grid](https://www.w3.org/WAI/ARIA/apg/patterns/grid/)                                                           |\n| `Link`             | [Link pattern](https://www.w3.org/WAI/ARIA/apg/patterns/link/) _(see [Router integration](#router-integration))_ |\n| `Listbox`          | [Listbox](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/) — single & multi-select                             |\n| `MenuButton`       | [Menu Button](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/)                                             |\n| `Menubar`          | [Menu / Menubar](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/)                                              |\n| `Meter`            | [`role=meter`](https://w3c.github.io/aria/#meter)                                                                |\n| `ModalDialog`      | [Dialog (Modal)](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)                                         |\n| `NonModalDialog`   | [Dialog (Modal)](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) — non-modal: no focus trap, no backdrop |\n| `Progressbar`      | [`role=progressbar`](https://w3c.github.io/aria/#progressbar)                                                    |\n| `RadioGroup`       | [Radio Group](https://www.w3.org/WAI/ARIA/apg/patterns/radio/)                                                   |\n| `Slider`           | [Slider](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)                                                       |\n| `SliderMultiThumb` | [Slider (Multi-Thumb)](https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/)                              |\n| `Spinbutton`       | [Spinbutton](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/)                                               |\n| `Switch`           | [Switch](https://www.w3.org/WAI/ARIA/apg/patterns/switch/)                                                       |\n| `Tabs`             | [Tabs](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) — automatic or manual activation, horizontal or vertical  |\n| `Textbox`          | [`role=textbox`](https://w3c.github.io/aria/#textbox) — single- and multi-line                                   |\n| `Toolbar`          | [Toolbar](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/)                                                     |\n| `Tooltip`          | [Tooltip](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/)                                                     |\n| `TreeGrid`         | [Tree Grid](https://www.w3.org/WAI/ARIA/apg/patterns/treegrid/)                                                  |\n| `TreeView`         | [Tree View](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/)                                                  |\n| `WindowSplitter`   | [Window Splitter](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/)                                      |\n\n### Structural\n\n| Component | Purpose                                                                                                                                           |\n| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `Article` | Semantic `<article>` with heading + posinset/setsize for use inside `Feed`. Focusable and in the page tab sequence, as the Feed pattern requires. |\n\n## Keyboard reference\n\nEvery component implements the full keyboard model specified by its APG pattern.\nHighlights:\n\n- **Roving tabindex** where the pattern calls for it: `RadioGroup`, `Toolbar`,\n  `Tabs`, `Grid`, `TreeView`, `TreeGrid`, `Menubar`, `Listbox`.\n- **`aria-activedescendant`** for virtual focus: `Combobox`.\n- **Focus return** on dialog dismiss: `ModalDialog`, `NonModalDialog`,\n  `AlertDialog`, `MenuButton`, `Menubar`.\n- **Escape** closes popups: `ModalDialog`, `NonModalDialog` (only while focus is\n  inside it), `AlertDialog`, `MenuButton`, `Menubar`, `Combobox`, `Tooltip`.\n- **A way out of a long composite**: `Feed` — `Ctrl+Home` and `Ctrl+End` move\n  focus to the focusable element before and after the feed, so a keyboard user\n  need not Tab through every article to get past it.\n\nExplore the [live Storybook demo](https://afixt.github.io/apg-react/) or run\n`npm run storybook` locally to see every keyboard path with step-by-step `play`\ninteractions.\n\n## Styling\n\nThe package ships two CSS files:\n\n- `@afixt/apg-react/styles.css` — full baseline styles for every component.\n- `@afixt/apg-react/variables.css` — only the design tokens, if you want to\n  write your own styles.\n\nAll visual choices are driven by CSS custom properties defined in\n`variables.css`. Override them at `:root` or at a container scope:\n\n```css\n:root {\n  --apg-color-primary: #7c3aed;\n  --apg-radius-md: 0.25rem;\n  --apg-font-family: 'Inter', system-ui, sans-serif;\n}\n```\n\nKey token groups: colors (`--apg-color-*`), spacing (`--apg-space-*`), radii\n(`--apg-radius-*`), typography (`--apg-font-*`), focus ring\n(`--apg-focus-ring-*`), shadows (`--apg-shadow-*`), z-index (`--apg-z-*`).\n\n## Router integration\n\n`Link` and `Breadcrumb` render navigable links. By default they emit a plain\n`<a href>`, so the library never forces a router on you and importing\n`@afixt/apg-react` works with no router installed.\n\nIf your app uses a router, supply its link component once at the root and every\ndescendant `Link` and `Breadcrumb` will use it for client-side navigation:\n\n```tsx\nimport { Link as RouterLink } from 'react-router-dom';\nimport { LinkComponentProvider } from '@afixt/apg-react';\n\n<BrowserRouter>\n  <LinkComponentProvider value={RouterLink}>\n    <App />\n  </LinkComponentProvider>\n</BrowserRouter>;\n```\n\nYou can also override it per instance, which takes precedence over the provider:\n\n```tsx\n<Link to=\"/profile\" linkComponent={RouterLink}>\n  View profile\n</Link>\n<Breadcrumb items={items} linkComponent={RouterLink} />\n```\n\nTo send a single link back to a plain anchor inside a provider — an external\nURL, a download, a full page load — pass `null`:\n\n```tsx\n<Link to=\"https://example.com/report.pdf\" linkComponent={null}>\n  Download the report\n</Link>\n```\n\nOmitting the prop and passing `null` are different: omitting defers to the\nprovider, `null` opts out of it.\n\nAny component accepting a `to` prop works — React Router, TanStack Router, or\nyour own wrapper around a framework's link. Extra props are forwarded verbatim,\nwhich makes the injected component responsible for the other half of the\ncontract: it must pass `onClick`, `onKeyDown`, and the rest through to the\nanchor it renders, or the consumer's handlers will never fire.\n\nWithout a provider or prop, a `to` given as a location object is flattened to\n`pathname + search + hash` for the anchor's `href`.\n\nThe fallback puts that value straight into `href` — the library does not rewrite\nor sanitize it, exactly as a hand-written `<a href>` would not. Up to and\nincluding 1.3.0 every `to` was resolved by React Router first, so if you\ninterpolate untrusted input into `to`, validate it yourself before rendering.\n\n> **Upgrading from ≤ 1.3.0:** these components used to import React Router\n> directly, which made the router a hard requirement for _every_ consumer. If\n> you relied on client-side navigation through them, wrap your app in\n> `LinkComponentProvider` as shown above; otherwise navigation will fall back to\n> full page loads.\n\n## Internationalization (i18n)\n\nComponents that render hardcoded user-facing strings (aria-labels, button text)\naccept an optional `labels` prop — an object whose keys map to English defaults.\nPass your own translations without forking:\n\n```tsx\n<Alert message=\"Saved\" type=\"info\" labels={{ dismiss: \"Fermer\" }} />\n<Carousel slides={slides} labels={{ previousSlide: \"Anterior\", nextSlide: \"Siguiente\" }} />\n<ModalDialog isOpen onClose={close} labels={{ closeDialog: \"Cerrar\" }}>…</ModalDialog>\n<Spinbutton min={0} max={10} labels={{ increaseValue: \"Erhöhen\", decreaseValue: \"Verringern\" }} />\n<Breadcrumb items={items} navLabel=\"Fil d'Ariane\" />\n```\n\nWhen `labels` is omitted, the English defaults are used. Only the keys you\noverride are affected; the rest keep their defaults.\n\n## Implementer responsibilities\n\nA handful of concerns must be satisfied by you — they cannot be handled at the\nlibrary level:\n\n- **Visible focus indicators.** The default focus ring uses a soft box-shadow;\n  ensure your brand palette preserves ≥3:1 contrast against the background.\n- **Color contrast.** If you override tokens, verify WCAG 1.4.3 (4.5:1 for text)\n  and 1.4.11 (3:1 for UI).\n- **External labels.** Where a component exposes `ariaLabelledby`, make sure the\n  referenced element exists and carries a meaningful name.\n- **Focus restoration on unmount.** Dialog components return focus to the\n  invoking element when dismissed, but if you unmount them imperatively,\n  re-establish focus yourself.\n- **Live regions for dynamic content.** Components that produce their own\n  `role=alert` / `role=status` fire announcements; adjacent dynamic content you\n  write still needs its own live region.\n\n## Testing\n\n```sh\nnpm test               # unit + a11y contract suite (jsdom)\nnpm run test:e2e:build # builds Storybook, runs Puppeteer E2E tests\nnpm run test:all       # both\n```\n\n- **291 unit tests** across 32 suites; 92%+ statement coverage.\n- **37 accessibility-contract tests** built on a hand-rolled ARIA-aware DOM\n  assertion library — no external a11y libraries of any kind.\n- **E2E tests** drive a real Chromium against a built Storybook: accessible-name\n  presence, `aria-*` id resolution, ARIA boolean grammar, Tab reachability.\n- **Use cases** (`usecases/`) document every user interaction in the DSL of\n  [`@afixt/usecase-runner`](https://www.npmjs.com/package/@afixt/usecase-runner)\n  so the APG keyboard and ARIA contract for each component can be exercised by\n  automation. See [`usecases/README.md`](./usecases/README.md).\n\n## Development\n\n```sh\n# First-time setup: installs optional binaries (trufflehog, lychee, etc.)\n# used by git hooks. Safe to re-run.\nbash scripts/bootstrap.sh\n\nnpm install\nnpm run storybook     # http://localhost:6006\nnpm run serve         # http://localhost:8080/demos/index.html\nnpm test\nnpm run build         # produces dist/\n```\n\n### Demo server\n\n`npm run serve` starts the static demo pages in [`demos/`](demos/README.md) —\none page per APG pattern, each rendering this library's own component. They are\nthe target that the `AFixt/apg-qa` use-case suite and the APG test-runner\nrepositories assert against, so a demo page never reimplements the pattern it\ndemonstrates.\n\n### Quality gates\n\nEvery PR runs the same gates locally and in CI. Run them all with one command:\n\n```sh\nnpm run check:all\n```\n\nwhich runs, in order: `typecheck` → `lint` → `knip` → `stylelint` →\n`format:check` → `markdownlint` → `test` → `dupes` → `license:check` → `build` →\n`size` → `security:audit`.\n\nIndividual gates:\n\n```sh\nnpm run typecheck     # tsc --noEmit with strict + noUncheckedIndexedAccess\nnpm run lint          # ESLint flat config (components + tests + stories)\nnpm run knip          # Knip: unused files, exports and dependencies\nnpm run stylelint     # Stylelint on all CSS (incl. a11y rules)\nnpm run format        # Prettier --write\nnpm run format:check  # Prettier --check (CI gate)\nnpm run markdownlint  # markdownlint-cli2 on all Markdown\nnpm run dupes         # jscpd duplicate detection\nnpm run license:check # production-dep license allowlist\nnpm run size          # size-limit bundle budgets\nnpm run security      # npm audit + OSV-Scanner + trufflehog\n```\n\nGit hooks (installed automatically via Husky's `prepare` script):\n\n- **pre-commit** — lint-staged (ESLint, Prettier, Stylelint, markdownlint on\n  staged files only) + typecheck of staged TS + trufflehog.\n- **commit-msg** — commitlint with `@commitlint/config-conventional`.\n- **pre-push** — runs the full `check` suite + tests + `dupes` +\n  `license:check` + optional link check.\n- **post-merge** — reinstall + `npm audit` when `package-lock.json` changes\n  after a pull.\n\nBypass a hook with `--no-verify` (use sparingly).\n\nScheduled workflows:\n\n- **`.github/workflows/security.yml`** (Mondays 06:00 UTC) — CodeQL,\n  OSV-Scanner, Semgrep OWASP Top 10, npm audit.\n- **`.github/workflows/docs.yml`** (Mondays 07:00 UTC) — lychee link check\n  across Markdown.\n\nSee `docs/adr/` for tooling decisions (why Jest not Vitest, why Rollup not Vite,\netc.).\n\n## Contributing\n\nIssues and PRs are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Versioning\n\nThis library follows [Semantic Versioning](https://semver.org). Breaking changes\nland in major releases; new components and opt-in features in minor; fixes in\npatch. See [CHANGELOG.md](./CHANGELOG.md).\n\nCutting a release is documented in [docs/RELEASING.md](./docs/RELEASING.md).\n\n## License\n\nMIT © [AFixt, Inc.](https://www.afixt.com) — see [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}