├── ROADMAP.md
├── src
├── test.html
├── styles
│ ├── pages
│ │ └── pages.css
│ ├── layout
│ │ ├── _main.css
│ │ ├── _scroll-spy.css
│ │ ├── layout.css
│ │ ├── _header.css
│ │ ├── _core.css
│ │ └── _header-nav.css
│ ├── _code.css
│ └── index.css
├── why.html
├── index.html
├── how.html
├── components-chips.html
├── components-details.html
├── components-dialog.html
├── components-select.html
├── components-tooltip.html
├── components.html
├── foundations.html
├── getting-started.html
├── getting-started-integrations.html
├── components-tree-view.html
├── getting-started-css-apis.html
├── components-textarea.html
├── getting-started-quick-start.html
├── components-switch.html
├── components-checkbox.html
├── components-accordion.html
├── foundations-elevations.html
├── foundations-typography.html
├── components-input.html
├── components-radio.html
├── common
│ ├── breadcrumbs.html
│ ├── header.html
│ └── docs-nav.html
├── assets
│ └── background-image.svg
└── _layout.html
├── .nvmrc
├── CNAME
├── .tool-versions
├── packages
├── css
│ ├── foundations
│ │ ├── NOTES.md
│ │ ├── lib
│ │ │ ├── helpers
│ │ │ │ ├── index.css
│ │ │ │ └── _sr-only.css
│ │ │ ├── _radiuses.css
│ │ │ ├── _elevations.css
│ │ │ ├── _focus.css
│ │ │ ├── foundations.css
│ │ │ ├── _reset.css
│ │ │ └── _spacings.css
│ │ ├── README.md
│ │ └── package.json
│ ├── grid-system
│ │ ├── NOTES.md
│ │ ├── README.md
│ │ ├── lib
│ │ │ ├── _variables.css
│ │ │ ├── _column.css
│ │ │ ├── _row.css
│ │ │ ├── _container.css
│ │ │ ├── grid-system.css
│ │ │ └── _container-breakpoints.css
│ │ └── package.json
│ ├── iconography
│ │ ├── NOTES.md
│ │ ├── lib
│ │ │ ├── iconography.css
│ │ │ └── fonts
│ │ │ │ └── wcag-icons
│ │ │ │ ├── PNG
│ │ │ │ ├── copy.png
│ │ │ │ ├── exeen.png
│ │ │ │ ├── figma.png
│ │ │ │ ├── dev-dojo.png
│ │ │ │ ├── github.png
│ │ │ │ ├── wcag-ui.png
│ │ │ │ ├── checkmark.png
│ │ │ │ ├── chevron-up.png
│ │ │ │ ├── linked-in.png
│ │ │ │ ├── chevron-down.png
│ │ │ │ ├── chevron-left.png
│ │ │ │ ├── chevron-right.png
│ │ │ │ ├── scheme-dark.png
│ │ │ │ ├── scheme-light.png
│ │ │ │ └── scheme-system.png
│ │ │ │ ├── fonts
│ │ │ │ ├── wcag-icons.ttf
│ │ │ │ └── wcag-icons.woff
│ │ │ │ ├── SVG
│ │ │ │ ├── chevron-up.svg
│ │ │ │ ├── chevron-down.svg
│ │ │ │ ├── chevron-left.svg
│ │ │ │ ├── chevron-right.svg
│ │ │ │ ├── checkmark.svg
│ │ │ │ ├── scheme-dark.svg
│ │ │ │ ├── scheme-system.svg
│ │ │ │ ├── copy.svg
│ │ │ │ ├── linked-in.svg
│ │ │ │ ├── scheme-light.svg
│ │ │ │ ├── github.svg
│ │ │ │ ├── dev-dojo.svg
│ │ │ │ └── figma.svg
│ │ │ │ ├── Read Me.txt
│ │ │ │ └── demo-files
│ │ │ │ └── demo.js
│ │ ├── README.md
│ │ └── package.json
│ └── typography
│ │ ├── lib
│ │ ├── fonts
│ │ │ ├── fonts.css
│ │ │ └── inter
│ │ │ │ ├── Inter.woff2
│ │ │ │ ├── Inter-Italic.woff2
│ │ │ │ └── style.css
│ │ └── typography.css
│ │ ├── README.md
│ │ └── package.json
├── components
│ ├── dialog
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ └── dialog.css
│ │ │ ├── dialog.events.js
│ │ │ ├── dialog.attributes.js
│ │ │ └── dialog.js
│ │ ├── README.md
│ │ └── __tests__
│ │ │ └── dialog.test.js
│ ├── input
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── variants
│ │ │ │ │ └── variants.css
│ │ │ │ ├── modifiers
│ │ │ │ │ └── modifiers.css
│ │ │ │ ├── dimensions
│ │ │ │ │ ├── dimensions.css
│ │ │ │ │ ├── _medium.css
│ │ │ │ │ ├── _large.css
│ │ │ │ │ └── _small.css
│ │ │ │ ├── states
│ │ │ │ │ ├── states.css
│ │ │ │ │ ├── _hover.css
│ │ │ │ │ ├── _active.css
│ │ │ │ │ ├── _focus.css
│ │ │ │ │ └── _disabled.css
│ │ │ │ └── input.css
│ │ │ ├── input.attributes.js
│ │ │ ├── input.events.js
│ │ │ └── input.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ │ └── input.test.js
│ │ └── package.json
│ ├── radio
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── variants
│ │ │ │ │ └── variants.css
│ │ │ │ ├── modifiers
│ │ │ │ │ └── modifiers.css
│ │ │ │ ├── dimensions
│ │ │ │ │ ├── dimensions.css
│ │ │ │ │ ├── _medium.css
│ │ │ │ │ ├── _large.css
│ │ │ │ │ └── _small.css
│ │ │ │ ├── states
│ │ │ │ │ ├── states.css
│ │ │ │ │ ├── _hover.css
│ │ │ │ │ ├── _active.css
│ │ │ │ │ ├── _focus.css
│ │ │ │ │ └── _disabled.css
│ │ │ │ └── radio.css
│ │ │ ├── radio.attributes.js
│ │ │ ├── radio.events.js
│ │ │ └── radio.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ │ └── radio.test.js
│ │ └── package.json
│ ├── checkbox
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── modifiers
│ │ │ │ │ └── modifiers.css
│ │ │ │ ├── variants
│ │ │ │ │ └── variants.css
│ │ │ │ ├── dimensions
│ │ │ │ │ ├── dimensions.css
│ │ │ │ │ ├── _medium.css
│ │ │ │ │ ├── _large.css
│ │ │ │ │ └── _small.css
│ │ │ │ ├── states
│ │ │ │ │ ├── states.css
│ │ │ │ │ ├── _hover.css
│ │ │ │ │ ├── _active.css
│ │ │ │ │ ├── _focus.css
│ │ │ │ │ └── _disabled.css
│ │ │ │ └── checkbox.css
│ │ │ ├── checkbox.attributes.js
│ │ │ ├── checkbox.events.js
│ │ │ └── checkbox.js
│ │ ├── README.md
│ │ └── __tests__
│ │ │ └── checkbox.test.js
│ ├── switch
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── modifiers
│ │ │ │ │ └── modifiers.css
│ │ │ │ ├── variants
│ │ │ │ │ └── variants.css
│ │ │ │ ├── dimensions
│ │ │ │ │ ├── dimensions.css
│ │ │ │ │ ├── _medium.css
│ │ │ │ │ ├── _large.css
│ │ │ │ │ └── _small.css
│ │ │ │ ├── states
│ │ │ │ │ ├── states.css
│ │ │ │ │ ├── _hover.css
│ │ │ │ │ ├── _active.css
│ │ │ │ │ ├── _focus.css
│ │ │ │ │ └── _disabled.css
│ │ │ │ └── switch.css
│ │ │ ├── switch.attributes.js
│ │ │ ├── switch.events.js
│ │ │ └── switch.js
│ │ ├── README.md
│ │ └── __tests__
│ │ │ └── switch.test.js
│ ├── textarea
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── modifiers
│ │ │ │ │ └── modifiers.css
│ │ │ │ ├── variants
│ │ │ │ │ └── variants.css
│ │ │ │ ├── dimensions
│ │ │ │ │ ├── dimensions.css
│ │ │ │ │ ├── _medium.css
│ │ │ │ │ ├── _large.css
│ │ │ │ │ └── _small.css
│ │ │ │ ├── states
│ │ │ │ │ ├── states.css
│ │ │ │ │ ├── _hover.css
│ │ │ │ │ ├── _active.css
│ │ │ │ │ ├── _focus.css
│ │ │ │ │ └── _disabled.css
│ │ │ │ └── textarea.css
│ │ │ ├── textarea.attributes.js
│ │ │ ├── textarea.events.js
│ │ │ └── textarea.js
│ │ ├── README.md
│ │ └── __tests__
│ │ │ └── textarea.test.js
│ ├── details
│ │ ├── lib
│ │ │ ├── details.events.js
│ │ │ ├── styles
│ │ │ │ ├── details.css
│ │ │ │ └── _core.css
│ │ │ └── details.attributes.js
│ │ ├── README.md
│ │ └── __tests__
│ │ │ └── details.test.js
│ ├── select
│ │ ├── lib
│ │ │ ├── select.events.js
│ │ │ ├── select.attributes.js
│ │ │ ├── styles
│ │ │ │ └── select.css
│ │ │ └── select.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ │ └── select.test.js
│ │ └── package.json
│ ├── tooltip
│ │ ├── lib
│ │ │ ├── tooltip.events.js
│ │ │ ├── tooltip.attributes.js
│ │ │ ├── styles
│ │ │ │ └── tooltip.css
│ │ │ └── tooltip.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ │ └── tooltip.test.js
│ │ └── package.json
│ ├── accordion
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── accordion.css
│ │ │ │ └── _core.css
│ │ │ ├── accordion.attributes.js
│ │ │ ├── accordion.events.js
│ │ │ └── accordion.js
│ │ └── __tests__
│ │ │ └── accordion.test.js
│ ├── tree-view
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── tree-view.css
│ │ │ │ └── _core.css
│ │ │ ├── tree-view.events.js
│ │ │ ├── tree-view.attributes.js
│ │ │ └── tree-view.js
│ │ ├── __tests__
│ │ │ └── tree-view.test.js
│ │ └── README.md
│ ├── scroll-spy
│ │ ├── lib
│ │ │ ├── styles
│ │ │ │ ├── scroll-spy.css
│ │ │ │ └── _core.css
│ │ │ ├── scroll-spy.attributes.js
│ │ │ └── scroll-spy.events.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ │ └── scroll-spy.test.js
│ │ └── package.json
│ └── button
│ │ ├── lib
│ │ ├── styles
│ │ │ ├── modifiers
│ │ │ │ ├── modifiers.css
│ │ │ │ ├── _square.css
│ │ │ │ └── _circle.css
│ │ │ ├── dimensions
│ │ │ │ ├── dimensions.css
│ │ │ │ ├── _medium.css
│ │ │ │ ├── _large.css
│ │ │ │ └── _small.css
│ │ │ ├── states
│ │ │ │ ├── states.css
│ │ │ │ ├── _hover.css
│ │ │ │ ├── _active.css
│ │ │ │ ├── _focus.css
│ │ │ │ └── _disabled.css
│ │ │ ├── variants
│ │ │ │ └── variants.css
│ │ │ ├── button.css
│ │ │ └── _core.css
│ │ ├── button.attributes.js
│ │ ├── button.events.js
│ │ └── button.js
│ │ ├── README.md
│ │ ├── __tests__
│ │ └── button.test.js
│ │ └── package.json
└── js
│ ├── core
│ ├── lib
│ │ ├── polyfills
│ │ │ └── index.js
│ │ ├── storage
│ │ │ └── index.js
│ │ ├── encoding
│ │ │ ├── index.js
│ │ │ └── _jwt.js
│ │ ├── _error.js
│ │ ├── events
│ │ │ ├── index.js
│ │ │ ├── _dispatchComponentEvent.js
│ │ │ ├── _cancelEvent.js
│ │ │ └── _dispatchCustomEvent.js
│ │ ├── helpers
│ │ │ ├── index.js
│ │ │ ├── _debounce.js
│ │ │ ├── _throttle.js
│ │ │ └── _files.js
│ │ ├── decorator
│ │ │ ├── _buildExtendOptions.js
│ │ │ ├── _generateIsAttribute.js
│ │ │ ├── _exposeComponent.js
│ │ │ ├── _assertMetaKey.js
│ │ │ ├── _defineCustomElement.js
│ │ │ ├── index.js
│ │ │ └── _applyMixins.js
│ │ └── core.js
│ ├── README.md
│ ├── __tests__
│ │ └── core.test.js
│ └── package.json
│ └── dom
│ ├── README.md
│ ├── __tests__
│ └── dom.test.js
│ ├── lib
│ ├── _containsHTML.js
│ ├── _createFragment.js
│ ├── _findNodes.js
│ ├── _outerHTML.js
│ ├── _ensureElement.js
│ ├── _createElement.js
│ ├── _insertElement.js
│ ├── _wrapElement.js
│ ├── _insertHTML.js
│ └── dom.js
│ └── package.json
├── .husky
├── pre-commit
└── pre-push
├── .npmrc
├── scripts
├── templates
│ └── component
│ │ ├── lib
│ │ ├── styles
│ │ │ ├── component-name.css
│ │ │ └── _core.css
│ │ ├── component-name.events.js
│ │ ├── component-name.attributes.js
│ │ └── component-name.js
│ │ ├── __tests__
│ │ └── component-name.test.js
│ │ └── README.md
├── _cli-utils.mjs
├── unpublish.mjs
└── _template-utils.mjs
├── .posthtmlrc
├── pnpm-workspace.yaml
├── .vscode
├── launch.json
└── settings.json
├── .prettierrc
├── jsconfig.json
├── commitlint.config.js
├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── coding-styleguides
│ └── a11y.md
└── workflows
│ └── static.yml
├── LICENSE
└── docs
└── GETTING-STARTED.md
/ROADMAP.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/test.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | wcag-ui.com
2 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 22.17.1
2 |
--------------------------------------------------------------------------------
/packages/css/foundations/NOTES.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/css/grid-system/NOTES.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/css/iconography/NOTES.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | pnpm commitlint
2 |
--------------------------------------------------------------------------------
/.husky/pre-push:
--------------------------------------------------------------------------------
1 | pnpm commitlint
2 |
--------------------------------------------------------------------------------
/packages/components/dialog/lib/styles/dialog.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | @wcag-ui:registry=http://localhost:4873/
2 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/details/lib/details.events.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/components/select/lib/select.events.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/components/tooltip/lib/tooltip.events.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/js/core/lib/polyfills/index.js:
--------------------------------------------------------------------------------
1 | import './_customElements';
2 |
--------------------------------------------------------------------------------
/packages/components/select/lib/select.attributes.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/components/tooltip/lib/tooltip.attributes.js:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/css/typography/lib/fonts/fonts.css:
--------------------------------------------------------------------------------
1 | @import './inter/style.css' layer(inter);
2 |
--------------------------------------------------------------------------------
/src/styles/pages/pages.css:
--------------------------------------------------------------------------------
1 | @import "./_foundations-colors.css" layer(foundations.colors);
2 |
--------------------------------------------------------------------------------
/packages/components/tooltip/lib/styles/tooltip.css:
--------------------------------------------------------------------------------
1 | /* @layer wcag-ui.components.tooltip {
2 | } */
3 |
--------------------------------------------------------------------------------
/src/styles/layout/_main.css:
--------------------------------------------------------------------------------
1 | main {
2 | grid-area: main;
3 |
4 | padding-block: 8rem;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/components/details/lib/styles/details.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.details);
2 |
--------------------------------------------------------------------------------
/packages/components/accordion/lib/styles/accordion.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.accordion);
2 |
--------------------------------------------------------------------------------
/packages/components/tree-view/lib/styles/tree-view.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.tree-view);
2 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/lib/styles/scroll-spy.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.scroll-spy);
2 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/iconography.css:
--------------------------------------------------------------------------------
1 | @import "./fonts/wcag-icons/style.css" layer(wcag-ui.foundations.iconography);
2 |
--------------------------------------------------------------------------------
/scripts/templates/component/lib/styles/component-name.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.component-name);
2 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/helpers/index.css:
--------------------------------------------------------------------------------
1 | @import "./_flex.css" layer(flex);
2 | @import "./_sr-only.css" layer(sr-only);
3 |
--------------------------------------------------------------------------------
/packages/components/accordion/lib/accordion.attributes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: function () {
3 | this.update();
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/packages/css/typography/lib/fonts/inter/Inter.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/typography/lib/fonts/inter/Inter.woff2
--------------------------------------------------------------------------------
/packages/components/tree-view/lib/styles/_core.css:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/suspicious/noEmptyBlock: */
2 | [is="wcag-tree-view"] {
3 | }
4 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/modifiers/modifiers.css:
--------------------------------------------------------------------------------
1 | @import "./_square.css" layer(modifiers.square);
2 | @import "./_circle.css" layer(modifiers.circle);
3 |
--------------------------------------------------------------------------------
/scripts/templates/component/lib/styles/_core.css:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/suspicious/noEmptyBlock: */
2 | [is="wcag-component-name"] {
3 | }
4 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/copy.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/exeen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/exeen.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/figma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/figma.png
--------------------------------------------------------------------------------
/packages/css/typography/lib/fonts/inter/Inter-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/typography/lib/fonts/inter/Inter-Italic.woff2
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/dev-dojo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/dev-dojo.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/github.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/wcag-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/wcag-ui.png
--------------------------------------------------------------------------------
/packages/components/select/lib/styles/select.css:
--------------------------------------------------------------------------------
1 | /* biome-ignore lint/suspicious/noEmptyBlock: It could be filled in the future */
2 | @layer wcag-ui.components.select {
3 | }
4 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/_radiuses.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /* TODO: ask design for radiuses tokens */
3 | --wcag-r--s: 4px;
4 | --wcag-r--m: 6px;
5 | --wcag-r--l: 8px;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/checkmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/checkmark.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-up.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/linked-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/linked-in.png
--------------------------------------------------------------------------------
/packages/js/dom/README.md:
--------------------------------------------------------------------------------
1 | # `dom`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const dom = require('dom');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-down.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-left.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/chevron-right.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-dark.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-light.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/PNG/scheme-system.png
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/fonts/wcag-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/fonts/wcag-icons.ttf
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/fonts/wcag-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devdojo-it/wcag-ui/HEAD/packages/css/iconography/lib/fonts/wcag-icons/fonts/wcag-icons.woff
--------------------------------------------------------------------------------
/packages/css/typography/lib/typography.css:
--------------------------------------------------------------------------------
1 | @import "./fonts/fonts.css" layer(wcag-ui.foundations.typography.fonts);
2 | @import "./_core.css" layer(wcag-ui.foundations.typography);
3 |
--------------------------------------------------------------------------------
/packages/js/core/README.md:
--------------------------------------------------------------------------------
1 | # `core`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const core = require('core');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/button/README.md:
--------------------------------------------------------------------------------
1 | # `button`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const button = require('button');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/dialog/README.md:
--------------------------------------------------------------------------------
1 | # `dialog`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const dialog = require('dialog');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/input/README.md:
--------------------------------------------------------------------------------
1 | # `input`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const input = require('input');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/radio/README.md:
--------------------------------------------------------------------------------
1 | # `radio`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const radio = require('radio');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/select/README.md:
--------------------------------------------------------------------------------
1 | # `select`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const select = require('select');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/details/README.md:
--------------------------------------------------------------------------------
1 | # `details`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const details = require('details');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/tooltip/README.md:
--------------------------------------------------------------------------------
1 | # `tooltip`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const tooltip = require('tooltip');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/tree-view/lib/tree-view.events.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { events } from '@wcag-ui/core';
3 |
4 | export default {};
5 |
--------------------------------------------------------------------------------
/packages/components/checkbox/README.md:
--------------------------------------------------------------------------------
1 | # `checkbox`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const checkbox = require('checkbox');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/switch/README.md:
--------------------------------------------------------------------------------
1 | # `checkbox`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const checkbox = require('checkbox');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/textarea/README.md:
--------------------------------------------------------------------------------
1 | # `textarea`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const textarea = require('textarea');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/components/tree-view/lib/tree-view.attributes.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { events } from '@wcag-ui/core';
3 |
4 | export default {};
5 |
--------------------------------------------------------------------------------
/packages/css/foundations/README.md:
--------------------------------------------------------------------------------
1 | # `typography`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const typography = require('typography');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/css/grid-system/README.md:
--------------------------------------------------------------------------------
1 | # `typography`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const typography = require('typography');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/css/typography/README.md:
--------------------------------------------------------------------------------
1 | # `typography`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const typography = require('typography');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/scripts/templates/component/lib/component-name.events.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { events } from '@wcag-ui/core';
3 |
4 | export default {};
5 |
--------------------------------------------------------------------------------
/src/why.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/packages/components/button/lib/button.attributes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | disabled: function (oldValue, newValue) {
3 | console.log('disabled changed', oldValue, newValue, this.textContent);
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/README.md:
--------------------------------------------------------------------------------
1 | # `scroll-spy`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const scrollSpy = require('scroll-spy');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/packages/css/iconography/README.md:
--------------------------------------------------------------------------------
1 | # `iconography`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const iconography = require('iconography');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
--------------------------------------------------------------------------------
/scripts/templates/component/lib/component-name.attributes.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { events } from '@wcag-ui/core';
3 |
4 | export default {};
5 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/lib/scroll-spy.attributes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | target: (_oldValue, _newValue) => {
3 | // console.log("disabled changed", oldValue, newValue, this.textContent);
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/dimensions/dimensions.css:
--------------------------------------------------------------------------------
1 | @import "./_medium.css" layer(dimensions.medium);
2 | @import "./_small.css" layer(dimensions.small);
3 | @import "./_large.css" layer(dimensions.large);
4 |
--------------------------------------------------------------------------------
/src/how.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.posthtmlrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": {
3 | "posthtml-extend": {
4 | "root": "./src"
5 | },
6 | "posthtml-include": {
7 | "root": "./src"
8 | },
9 | "posthtml-markdownit": {}
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/_variables.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-gs--container--size: 100vw;
3 | --wcag-gs--container--gap: 1.5rem;
4 | --wcag-gs--cols: 12;
5 | --wcag-gs--gap: 1.5rem;
6 | --wcag-gs--v-gap: 1.5rem;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/js/dom/__tests__/dom.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const dom = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(dom(), 'Hello from dom');
7 | console.info('dom tests passed');
8 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/_column.css:
--------------------------------------------------------------------------------
1 | :where(col, [col]) {
2 | display: flex;
3 | flex-flow: column nowrap;
4 | grid-column: auto / span var(--wcag-gs--cols);
5 |
6 | max-inline-size: var(--wcag-gs--container--size);
7 | }
8 |
--------------------------------------------------------------------------------
/packages/js/core/lib/storage/index.js:
--------------------------------------------------------------------------------
1 | import { CookieStorage } from "./_cookieStorage";
2 |
3 | /**
4 | * Storage utilities bundle.
5 | */
6 | const storage = {
7 | CookieStorage,
8 | };
9 |
10 | export { storage };
11 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - packages/**/*
3 |
4 | onlyBuiltDependencies:
5 | - '@parcel/watcher'
6 | - '@swc/core'
7 | - esbuild
8 | - lightningcss-cli
9 | - lmdb
10 | - msgpackr-extract
11 | - sharp
12 |
--------------------------------------------------------------------------------
/packages/js/core/__tests__/core.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const core = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(core(), 'Hello from core');
7 | console.info('core tests passed');
8 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_containsHTML.js:
--------------------------------------------------------------------------------
1 | /**
2 | * returns true if the provided string contains HTML tags
3 | *
4 | * @param {string} str
5 | * @return {boolean}
6 | */
7 | export const containsHTML = (str) => /<[a-z][\s\S]*>/i.test(str);
8 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/modifiers/_square.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--m-square--aspect-ratio: 1;
3 | }
4 |
5 | [is="wcag-button"][square] {
6 | --wcag-button--aspect-ratio: var(--wcag-button--m-square--aspect-ratio);
7 | }
8 |
--------------------------------------------------------------------------------
/packages/components/input/__tests__/input.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const input = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(input(), 'Hello from input');
7 | console.info('input tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/radio/__tests__/radio.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const radio = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(radio(), 'Hello from radio');
7 | console.info('radio tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/switch/__tests__/switch.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const sw = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(sw(), 'Hello from switch');
7 | console.info('switch tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/states/states.css:
--------------------------------------------------------------------------------
1 | @import "./_hover.css" layer(states.hover);
2 | @import "./_active.css" layer(states.active);
3 | @import "./_focus.css" layer(states.focus);
4 | @import "./_disabled.css" layer(states.disabled);
5 |
--------------------------------------------------------------------------------
/packages/components/button/__tests__/button.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const button = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(button(), 'Hello from button');
7 | console.info('button tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/button/lib/button.events.js:
--------------------------------------------------------------------------------
1 | export default {
2 | click: function (e) {
3 | console.log('button clicked', this.textContent);
4 | },
5 | focus: function (e) {
6 | console.log('button focused', this.textContent);
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/packages/components/dialog/__tests__/dialog.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const dialog = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(dialog(), 'Hello from dialog');
7 | console.info('dialog tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/select/__tests__/select.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const select = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(select(), 'Hello from select');
7 | console.info('select tests passed');
8 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/_elevations.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-e--sm: 0 0.2rem 2rem 0 hsla(248, 28%, 55%, 0.08);
3 | --wcag-e--md: 0 0.4rem 4rem -0.2rem hsla(248, 28%, 55%, 0.1);
4 | --wcag-e--lg: 0 1.8rem 6rem 0.2rem hsla(248, 28%, 55%, 0.1);
5 | }
6 |
--------------------------------------------------------------------------------
/src/styles/_code.css:
--------------------------------------------------------------------------------
1 | /* @import 'npm:highlight.js/styles/tomorrow-night-blue.min.css'; */
2 | @import 'npm:highlight.js/styles/a11y-dark.min.css';
3 |
4 | .hljs {
5 | background-color: hsl(247, 69%, 14%);
6 | border: 1px solid hsl(245, 93%, 28%);
7 | }
8 |
--------------------------------------------------------------------------------
/packages/components/tooltip/__tests__/tooltip.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const tooltip = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(tooltip(), 'Hello from tooltip');
7 | console.info('tooltip tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/checkbox/__tests__/checkbox.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const checkbox = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(checkbox(), 'Hello from checkbox');
7 | console.info('checkbox tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/textarea/__tests__/textarea.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const textarea = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(textarea(), 'Hello from textarea');
7 | console.info('textarea tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/tree-view/__tests__/tree-view.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const treeView = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(treeView(), 'Hello from treeView');
7 | console.info('treeView tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/accordion/__tests__/accordion.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const accordion = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(accordion(), 'Hello from accordion');
7 | console.info('accordion tests passed');
8 |
--------------------------------------------------------------------------------
/packages/components/details/__tests__/details.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const details = require('../lib/details');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(details(), 'Hello from details');
7 | console.info('details tests passed');
8 |
--------------------------------------------------------------------------------
/src/components-chips.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Details Docs Example
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components-details.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Details Docs Example
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components-dialog.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Details Docs Example
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components-select.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Details Docs Example
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components-tooltip.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Details Docs Example
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/__tests__/scroll-spy.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const scrollSpy = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(scrollSpy(), 'Hello from scrollSpy');
7 | console.info('scrollSpy tests passed');
8 |
--------------------------------------------------------------------------------
/src/foundations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/variants/variants.css:
--------------------------------------------------------------------------------
1 | @import "./_primary.css" layer(variants.primary);
2 | @import "./_secondary.css" layer(variants.secondary);
3 | @import "./_tertiary.css" layer(variants.tertiary);
4 | @import "./_destructive.css" layer(variants.destructive);
5 |
--------------------------------------------------------------------------------
/packages/components/dialog/lib/dialog.events.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | // click: function (e) {
4 | // console.log("button clicked", this.textContent);
5 | // },
6 | // focus: function (e) {
7 | // console.log("button focused", this.textContent);
8 | // },
9 | };
10 |
--------------------------------------------------------------------------------
/scripts/templates/component/__tests__/component-name.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const componentName = require('..');
4 | const assert = require('node:assert').strict;
5 |
6 | assert.strictEqual(componentName(), 'Hello from componentName');
7 | console.info('componentName tests passed');
8 |
--------------------------------------------------------------------------------
/src/getting-started.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/helpers/_sr-only.css:
--------------------------------------------------------------------------------
1 | [sr-only] {
2 | position: absolute;
3 |
4 | width: 1px;
5 | height: 1px;
6 | padding: 0;
7 | border: 0;
8 | margin: -1px;
9 |
10 | overflow: hidden;
11 | white-space: nowrap;
12 |
13 | clip: rect(0, 0, 0, 0);
14 | }
15 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/lib/scroll-spy.events.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | // click: function (e) {
4 | // console.log("button clicked", this.textContent);
5 | // },
6 | // focus: function (e) {
7 | // console.log("button focused", this.textContent);
8 | // },
9 | };
10 |
--------------------------------------------------------------------------------
/packages/js/core/lib/encoding/index.js:
--------------------------------------------------------------------------------
1 | import { base64 } from "./_base64";
2 | import { jwt } from "./_jwt";
3 | import { md5 } from "./_md5";
4 |
5 | /**
6 | * Encoding utilities bundle.
7 | */
8 | const encoding = {
9 | base64,
10 | jwt,
11 | md5,
12 | };
13 |
14 | export { encoding };
15 |
--------------------------------------------------------------------------------
/src/styles/layout/_scroll-spy.css:
--------------------------------------------------------------------------------
1 | body > aside[scroll-spy] {
2 | grid-area: scroll-spy;
3 |
4 | [is="wcag-scroll-spy"] {
5 | position: sticky;
6 | inset-block-start: calc(var(--docs--header--min-height) + 3rem);
7 |
8 | inline-size: 19.3rem;
9 | margin: 0 auto 0 2rem;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/components/tree-view/README.md:
--------------------------------------------------------------------------------
1 | # `TreeView`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const treeView = require('@wcag-ui/tree-view');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
13 | ## HTML before
14 |
15 | ```html
16 | ```
17 |
18 | ## HTML after
19 |
20 | ```html
21 | ```
22 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/chevron-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/chevron-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/chevron-left.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Usare IntelliSense per informazioni sui possibili attributi.
3 | // Al passaggio del mouse vengono visualizzate le descrizioni degli attributi esistenti.
4 | // Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": []
7 | }
8 |
--------------------------------------------------------------------------------
/scripts/templates/component/README.md:
--------------------------------------------------------------------------------
1 | # `ComponentName`
2 |
3 | > TODO: description
4 |
5 | ## Usage
6 |
7 | ```
8 | const componentName = require('@wcag-ui/component-name');
9 |
10 | // TODO: DEMONSTRATE API
11 | ```
12 |
13 | ## HTML before
14 |
15 | ```html
16 | ```
17 |
18 | ## HTML after
19 |
20 | ```html
21 | ```
22 |
--------------------------------------------------------------------------------
/src/getting-started-integrations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/checkmark.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "htmlWhitespaceSensitivity": "ignore",
6 | "proseWrap": "never",
7 | "bracketSameLine": true,
8 | "overrides": [
9 | {
10 | "files": ["*.js"],
11 | "options": {
12 | "singleQuote": true
13 | }
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ESNext",
4 | "moduleResolution": "Bundler",
5 | "target": "ES2022",
6 | "jsx": "react",
7 | "allowImportingTsExtensions": true,
8 | "checkJs": true,
9 | "strictNullChecks": true,
10 | "strictFunctionTypes": true
11 | },
12 | "exclude": ["node_modules", "**/node_modules/*"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/modifiers/_circle.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--m-circle--aspect-ratio: 1;
3 | --wcag-button--m-circle--border-radius: 50%;
4 | }
5 |
6 | [is="wcag-button"][circle] {
7 | --wcag-button--aspect-ratio: var(--wcag-button--m-circle--aspect-ratio);
8 | --wcag-button--border-radius: var(--wcag-button--m-circle--border-radius);
9 | }
10 |
--------------------------------------------------------------------------------
/packages/components/details/lib/details.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | open: function (_oldValue, newValue) {
5 | const state = newValue === null ? 'close' : 'open';
6 | this.setAttribute('aria-expanded', state === 'open');
7 |
8 | events.dispatchComponentEvent.call(this, 'toggle', { state });
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/input.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.input);
2 | @import "./variants/variants.css" layer(wcag-ui.components.input);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.input);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.input);
5 | @import "./states/states.css" layer(wcag-ui.components.input);
6 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/radio.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.radio);
2 | @import "./variants/variants.css" layer(wcag-ui.components.radio);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.radio);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.radio);
5 | @import "./states/states.css" layer(wcag-ui.components.radio);
6 |
--------------------------------------------------------------------------------
/packages/components/accordion/lib/accordion.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'wcag-details.toggle': function (_e) {
5 | // NOTE: this works only with
6 | // because native element doesn't bubble the `toggle` event
7 |
8 | events.dispatchComponentEvent.call(this, 'toggle', {});
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/button.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.button);
2 | @import "./variants/variants.css" layer(wcag-ui.components.button);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.button);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.button);
5 | @import "./states/states.css" layer(wcag-ui.components.button);
6 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/switch.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.switch);
2 | @import "./variants/variants.css" layer(wcag-ui.components.switch);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.switch);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.switch);
5 | @import "./states/states.css" layer(wcag-ui.components.switch);
6 |
--------------------------------------------------------------------------------
/packages/components/dialog/lib/dialog.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | open: function (_oldValue, newValue) {
5 | const state = newValue === null ? 'close' : 'open';
6 | this.setAttribute('aria-expanded', (state === 'open').toString());
7 |
8 | events.dispatchComponentEvent.call(this, 'toggle', { state });
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/checkbox.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.checkbox);
2 | @import "./variants/variants.css" layer(wcag-ui.components.checkbox);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.checkbox);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.checkbox);
5 | @import "./states/states.css" layer(wcag-ui.components.checkbox);
6 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/textarea.css:
--------------------------------------------------------------------------------
1 | @import "./_core.css" layer(wcag-ui.components.textarea);
2 | @import "./variants/variants.css" layer(wcag-ui.components.textarea);
3 | @import "./dimensions/dimensions.css" layer(wcag-ui.components.textarea);
4 | @import "./modifiers/modifiers.css" layer(wcag-ui.components.textarea);
5 | @import "./states/states.css" layer(wcag-ui.components.textarea);
6 |
--------------------------------------------------------------------------------
/packages/js/core/lib/_error.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Throws a standardized wcag-ui error.
3 | *
4 | * @param {string} componentName - Component name for context (e.g., "Dialog").
5 | * @param {string} errorMessage - Error message.
6 | * @returns {never}
7 | */
8 | export const error = (componentName, errorMessage) => {
9 | throw new Error(`wcag-ui.${componentName} error: ${errorMessage}`);
10 | };
11 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_createFragment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * create an document fragment, appends the specified children to it and returns it
3 | *
4 | * @param {...ChildNode} children to append
5 | * @return {Element}
6 | */
7 | export const createFragment = (...children) => {
8 | const fragment = document.createDocumentFragment();
9 |
10 | fragment.append(...children);
11 |
12 | return fragment;
13 | };
14 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | rules: {
4 | // TODO Add Scope Enum Here
5 | // 'scope-enum': [2, 'always', ['yourscope', 'yourscope']],
6 | 'type-enum': [
7 | 2,
8 | 'always',
9 | ['feat', 'fix', 'docs', 'chore', 'style', 'refactor', 'ci', 'test', 'revert', 'perf', 'build', 'rel'],
10 | ],
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/packages/js/core/lib/events/index.js:
--------------------------------------------------------------------------------
1 | import { cancelEvent } from "./_cancelEvent";
2 | import { dispatchCustomEvent } from "./_dispatchCustomEvent";
3 | import { dispatchComponentEvent } from "./_dispatchComponentEvent";
4 |
5 | /**
6 | * Events utilities bundle.
7 | */
8 | const events = {
9 | cancelEvent,
10 | dispatchCustomEvent,
11 | dispatchComponentEvent,
12 | };
13 |
14 | export { events };
15 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/scheme-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/components-tree-view.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | TreeView Docs Example
7 |
8 | TreeView
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/getting-started-css-apis.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Getting Started
8 | CSS APIs
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/styles/layout/layout.css:
--------------------------------------------------------------------------------
1 | @import "./_variables.css" layer(variables);
2 | @import "./_core.css" layer(core);
3 | @import "./_header.css" layer(header);
4 | @import "./_header-nav.css" layer(header.nav);
5 | @import "./_color-scheme.css" layer(color-scheme);
6 | @import "./_aside.css" layer(aside);
7 | @import "./_main.css" layer(main);
8 | @import "./_scroll-spy.css" layer(scroll-spy);
9 | @import "./_footer.css" layer(footer);
10 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/scheme-system.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/components-textarea.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Textarea Docs Example
7 |
8 | Textarea
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/getting-started-quick-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Getting Started
8 | Quick Start
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/js/core/lib/helpers/index.js:
--------------------------------------------------------------------------------
1 | import { debounce } from './_debounce';
2 | import { throttle } from './_throttle';
3 |
4 | import { files } from './_files';
5 | import { strings } from './_strings';
6 | import { types } from './_types';
7 |
8 | /**
9 | * General-purpose helpers bundle (debounce/throttle, string utils, types, files).
10 | */
11 | const helpers = {
12 | debounce,
13 | throttle,
14 | files,
15 | strings,
16 | types,
17 | };
18 |
19 | export { helpers };
20 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/checkbox.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'aria-label': function (_oldValue, newValue) {
5 | if (this.label) {
6 | const textContent = this.label.textContent;
7 |
8 | if (textContent !== newValue) {
9 | this.label.childNodes[0].textContent = newValue;
10 |
11 | events.dispatchComponentEvent.call(this, 'aria-label.change', { label: newValue });
12 | }
13 | }
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/copy.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/components/input/lib/input.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'aria-label': function (oldValue, newValue) {
5 | if (this.label) {
6 | const textContent = this.label.textContent;
7 |
8 | if (textContent !== newValue) {
9 | this.label.childNodes[0].textContent = newValue;
10 |
11 | events.dispatchComponentEvent.call(this, 'aria-label.change', { value: newValue, oldValue });
12 | }
13 | }
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/radio.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'aria-label': function (oldValue, newValue) {
5 | if (this.label) {
6 | const textContent = this.label.textContent;
7 |
8 | if (textContent !== newValue) {
9 | this.label.childNodes[0].textContent = newValue;
10 |
11 | events.dispatchComponentEvent.call(this, 'aria-label.change', { value: newValue, oldValue });
12 | }
13 | }
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/switch.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'aria-label': function (oldValue, newValue) {
5 | if (this.label) {
6 | const textContent = this.label.textContent;
7 |
8 | if (textContent !== newValue) {
9 | this.label.childNodes[0].textContent = newValue;
10 |
11 | events.dispatchComponentEvent.call(this, 'aria-label.change', { value: newValue, oldValue });
12 | }
13 | }
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/textarea.attributes.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | 'aria-label': function (oldValue, newValue) {
5 | if (this.label) {
6 | const textContent = this.label.textContent;
7 |
8 | if (textContent !== newValue) {
9 | this.label.childNodes[0].textContent = newValue;
10 |
11 | events.dispatchComponentEvent.call(this, 'aria-label.change', { value: newValue, oldValue });
12 | }
13 | }
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-f--outline-width: 2px;
3 | --wcag-f--outline-style: solid;
4 | --wcag-f--outline-color: hsl(245, 93%, 38%);
5 | --wcag-f--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | :where(:focus-visible, :has(> [sr-only]):focus-within) {
9 | outline-width: var(--wcag-f--outline-width);
10 | outline-style: var(--wcag-f--outline-style);
11 | outline-color: var(--wcag-f--outline-color);
12 | outline-offset: var(--wcag-f--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-input--s-hov--color: ;
4 | --wcag-input--s-hov--background-color: ;
5 | */
6 | --wcag-input--s-hov--border-color: var(--wcag-c--neutral-600);
7 | }
8 |
9 | [is="wcag-input"]:hover {
10 | /*
11 | --wcag-input--color: var(--wcag-input--s-hov--color);
12 | --wcag-input--background-color: var(--wcag-input--s-hov--background-color);
13 | */
14 |
15 | --wcag-input--border-color: var(--wcag-input--s-hov--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-radio--s-hov--color: ;
4 | --wcag-radio--s-hov--background-color: ;
5 | */
6 | --wcag-radio--s-hov--border-color: var(--wcag-c--neutral-600);
7 | }
8 |
9 | [is="wcag-radio"]:hover {
10 | /*
11 | --wcag-radio--color: var(--wcag-radio--s-hov--color);
12 | --wcag-radio--background-color: var(--wcag-radio--s-hov--background-color);
13 | */
14 |
15 | --wcag-radio--border-color: var(--wcag-radio--s-hov--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/_row.css:
--------------------------------------------------------------------------------
1 | /* biome-ignore lint/correctness/noUnknownTypeSelector: */
2 | :where(row, [row]) {
3 | display: grid;
4 | grid-template-columns: repeat(var(--wcag-gs--cols), minmax(0, 1fr));
5 | grid-template-rows: auto;
6 | grid-auto-flow: row;
7 | /* grid-column-gap: 0; */
8 | gap: var(--wcag-gs--v-gap) var(--wcag-gs--gap);
9 |
10 | inline-size: 100%;
11 | margin: 0;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components-switch.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Switch Docs Example
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/components/tooltip/lib/tooltip.js:
--------------------------------------------------------------------------------
1 | import { componentDecorator } from '@wcag-ui/core';
2 |
3 | import attributes from './tooltip.attributes';
4 | import events from './tooltip.events';
5 |
6 | export class Tooltip extends HTMLElement {
7 | static extendsElement = 'span';
8 | static attributes = attributes;
9 | static events = events;
10 |
11 | static {
12 | componentDecorator(this);
13 | }
14 |
15 | constructor() {
16 | super();
17 |
18 | this.#init();
19 | }
20 |
21 | #init() {}
22 | }
23 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-switch--s-hov--color: ;
4 | --wcag-switch--s-hov--background-color: ;
5 | */
6 | --wcag-switch--s-hov--border-color: var(--wcag-c--neutral-600);
7 | }
8 |
9 | [is="wcag-switch"]:hover {
10 | /*
11 | --wcag-switch--color: var(--wcag-switch--s-hov--color);
12 | --wcag-switch--background-color: var(--wcag-switch--s-hov--background-color);
13 | */
14 |
15 | --wcag-switch--border-color: var(--wcag-switch--s-hov--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/src/components-checkbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Checkbox Docs Example
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/foundations.css:
--------------------------------------------------------------------------------
1 | @layer wcag-ui.core, wcag-ui.foundations, wcag-ui.components;
2 |
3 | @import "./_reset.css" layer(wcag-ui.core.reset);
4 | @import "./helpers/index.css" layer(wcag-ui.core.helpers);
5 | @import "./_focus.css" layer(wcag-ui.core.focus);
6 | @import "./_colors.css" layer(wcag-ui.foundations.colors);
7 | @import "./_elevations.css" layer(wcag-ui.foundations.elevations);
8 | @import "./_spacings.css" layer(wcag-ui.foundations.spacings);
9 | @import "./_radiuses.css" layer(wcag-ui.foundations.radiuses);
10 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-checkbox--s-hov--color: ;
4 | --wcag-checkbox--s-hov--background-color: ;
5 | */
6 | --wcag-checkbox--s-hov--border-color: var(--wcag-c--neutral-600);
7 | }
8 |
9 | [is="wcag-checkbox"]:hover {
10 | /*
11 | --wcag-checkbox--color: var(--wcag-checkbox--s-hov--color);
12 | --wcag-checkbox--background-color: var(--wcag-checkbox--s-hov--background-color);
13 | */
14 |
15 | --wcag-checkbox--border-color: var(--wcag-checkbox--s-hov--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-input--s-act--color: ;
4 | --wcag-input--s-act--background-color: ;
5 | */
6 |
7 | --wcag-input--s-act--border-color: var(--wcag-c--neutral-600);
8 | }
9 |
10 | [is="wcag-input"]:where(:active, [aria-pressed="true"]) {
11 | /*
12 | --wcag-input--color: var(--wcag-input--s-act--color);
13 | --wcag-input--background-color: var(--wcag-input--s-act--background-color);
14 | */
15 | --wcag-input--border-color: var(--wcag-input--s-act--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-radio--s-act--color: ;
4 | --wcag-radio--s-act--background-color: ;
5 | */
6 |
7 | --wcag-radio--s-act--border-color: var(--wcag-c--neutral-600);
8 | }
9 |
10 | [is="wcag-radio"]:where(:active, [aria-pressed="true"]) {
11 | /*
12 | --wcag-radio--color: var(--wcag-radio--s-act--color);
13 | --wcag-radio--background-color: var(--wcag-radio--s-act--background-color);
14 | */
15 | --wcag-radio--border-color: var(--wcag-radio--s-act--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-textarea--s-hov--color: ;
4 | --wcag-textarea--s-hov--background-color: ;
5 | */
6 | --wcag-textarea--s-hov--border-color: var(--wcag-c--neutral-600);
7 | }
8 |
9 | [is="wcag-textarea"]:hover {
10 | /*
11 | --wcag-textarea--color: var(--wcag-textarea--s-hov--color);
12 | --wcag-textarea--background-color: var(--wcag-textarea--s-hov--background-color);
13 | */
14 |
15 | --wcag-textarea--border-color: var(--wcag-textarea--s-hov--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/_container.css:
--------------------------------------------------------------------------------
1 | /* biome-ignore lint/correctness/noUnknownTypeSelector: */
2 | :where(container, [container]) {
3 | display: flex;
4 | flex-flow: column nowrap;
5 | gap: var(--wcag-gs--container--gap);
6 |
7 | inline-size: var(--wcag-gs--container--size);
8 | block-size: auto;
9 | padding: 0;
10 | margin: 0 auto;
11 |
12 | &:where([fluid]) {
13 | --wcag-gs--container--size: 100%;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-switch--s-act--color: ;
4 | --wcag-switch--s-act--background-color: ;
5 | */
6 |
7 | --wcag-switch--s-act--border-color: var(--wcag-c--neutral-600);
8 | }
9 |
10 | [is="wcag-switch"]:where(:active, [aria-pressed="true"]) {
11 | /*
12 | --wcag-switch--color: var(--wcag-switch--s-act--color);
13 | --wcag-switch--background-color: var(--wcag-switch--s-act--background-color);
14 | */
15 | --wcag-switch--border-color: var(--wcag-switch--s-act--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/states/_hover.css:
--------------------------------------------------------------------------------
1 | /*
2 | :root {
3 | --wcag-button--s-hov--color: ;
4 | --wcag-button--s-hov--background-color: ;
5 | --wcag-button--s-hov--border-color: ;
6 | }
7 | */
8 |
9 | [is="wcag-button"]:hover {
10 | --wcag-button--color: var(--wcag-button--s-hov--color);
11 | --wcag-button--background-color: var(--wcag-button--s-hov--background-color);
12 | --wcag-button--border-color: var(--wcag-button--s-hov--border-color);
13 |
14 | --wcag-button--text-decoration: var(--wcag-button--s-hov--text-decoration);
15 | }
16 |
--------------------------------------------------------------------------------
/packages/components/scroll-spy/lib/styles/_core.css:
--------------------------------------------------------------------------------
1 | [is="wcag-scroll-spy"] {
2 | align-self: flex-start;
3 |
4 | display: block;
5 | width: 250px;
6 |
7 | nav {
8 | ul {
9 | list-style: none;
10 | padding: 0;
11 |
12 | li {
13 | margin-bottom: 10px;
14 |
15 | a {
16 | text-decoration: none;
17 | color: #333;
18 | }
19 |
20 | &.active {
21 | a {
22 | font-weight: bold;
23 | color: #007bff;
24 | }
25 | }
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-checkbox--s-act--color: ;
4 | --wcag-checkbox--s-act--background-color: ;
5 | */
6 |
7 | --wcag-checkbox--s-act--border-color: var(--wcag-c--neutral-600);
8 | }
9 |
10 | [is="wcag-checkbox"]:where(:active, [aria-pressed="true"]) {
11 | /*
12 | --wcag-checkbox--color: var(--wcag-checkbox--s-act--color);
13 | --wcag-checkbox--background-color: var(--wcag-checkbox--s-act--background-color);
14 | */
15 | --wcag-checkbox--border-color: var(--wcag-checkbox--s-act--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-textarea--s-act--color: ;
4 | --wcag-textarea--s-act--background-color: ;
5 | */
6 |
7 | --wcag-textarea--s-act--border-color: var(--wcag-c--neutral-600);
8 | }
9 |
10 | [is="wcag-textarea"]:where(:active, [aria-pressed="true"]) {
11 | /*
12 | --wcag-textarea--color: var(--wcag-textarea--s-act--color);
13 | --wcag-textarea--background-color: var(--wcag-textarea--s-act--background-color);
14 | */
15 | --wcag-textarea--border-color: var(--wcag-textarea--s-act--border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/states/_active.css:
--------------------------------------------------------------------------------
1 | /*
2 | :root {
3 | --wcag-button--s-act--color: ;
4 | --wcag-button--s-act--background-color: ;
5 | --wcag-button--s-act--border-color: ;
6 | }
7 | */
8 |
9 | [is="wcag-button"]:where(:active, [aria-pressed="true"]) {
10 | --wcag-button--color: var(--wcag-button--s-act--color);
11 | --wcag-button--background-color: var(--wcag-button--s-act--background-color);
12 | --wcag-button--border-color: var(--wcag-button--s-act--border-color);
13 |
14 | --wcag-button--text-decoration: var(--wcag-button--s-act--text-decoration);
15 | }
16 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/grid-system.css:
--------------------------------------------------------------------------------
1 | @import "./_variables.css" layer(wcag-ui.foundations.grid-system.variables);
2 | @import "./_container.css" layer(wcag-ui.foundations.grid-system.container);
3 | @import "./_container-breakpoints.css" layer(wcag-ui.foundations.grid-system.container.breakpoints);
4 | @import "./_row.css" layer(wcag-ui.foundations.grid-system.row);
5 | @import "./_column.css" layer(wcag-ui.foundations.grid-system.column);
6 | @import "./_column-sizes.css" layer(wcag-ui.foundations.grid-system.column.sizes);
7 | @import "./_column-offsets.css" layer(wcag-ui.foundations.grid-system.column.offsets);
8 |
--------------------------------------------------------------------------------
/packages/js/core/lib/decorator/_buildExtendOptions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the `extends` option for Custom Elements when the component
3 | * targets a built-in element extension (e.g., `{ extends: 'button' }`).
4 | *
5 | * If `component.extendsElement` is falsy, returns `undefined`.
6 | *
7 | * @param {{ extendsElement?: string }} component - Component static metadata.
8 | * @returns {{ extends: string }|undefined} The extend options (or `undefined`).
9 | */
10 | export function buildExtendOptions(component) {
11 | return component.extendsElement ? { extends: component.extendsElement } : undefined;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components-accordion.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Accordion Docs Example
7 |
8 |
9 | Details group 1
10 | Details content 1
11 |
12 |
13 | Details group 2
14 | Details content 2
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # testing
9 | coverage
10 |
11 | # build
12 | dist
13 | *.min.css
14 | *.min.js
15 |
16 | # misc
17 | *.pem
18 |
19 | # cache
20 | .parcel-cache
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 | lerna-debug.log*
28 |
29 | #lock files
30 | package-lock.json
31 | yarn.lock
32 |
33 | # local env files
34 | .env.*
35 | *.env
36 |
37 | # OS/IDE files
38 | .DS_Store
39 | .idea
40 | .obsidian
41 |
42 |
--------------------------------------------------------------------------------
/packages/components/accordion/lib/styles/_core.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-accordion--display: flex;
3 | --wcag-accordion--flex-flow: column nowrap;
4 | --wcag-accordion--place-content: center space-between;
5 | --wcag-accordion--gap: var(--wcag-s--200);
6 |
7 | --wcag-accordion--border-radius: var(--wcag-r--s);
8 | }
9 |
10 | [is="wcag-accordion"] {
11 | display: var(--wcag-accordion--display);
12 | flex-flow: var(--wcag-accordion--flex-flow);
13 | place-content: var(--wcag-accordion--place-content);
14 | gap: var(--wcag-accordion--gap);
15 |
16 | border-radius: var(--wcag-accordion--border-radius);
17 | }
18 |
--------------------------------------------------------------------------------
/packages/js/core/lib/decorator/_generateIsAttribute.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Converts a component name (PascalCase or camelCase)
3 | * into the "wcag-kebab-case" format for the `is` attribute.
4 | *
5 | * @param {string} name - Component name (e.g., "TreeView", "Button", "ScrollSpy")
6 | * @returns {string} - Formatted name for `is` (e.g., "wcag-tree-view")
7 | */
8 | export function generateIsAttribute(name) {
9 | return `wcag-${name
10 | .replace(/([a-z0-9])([A-Z])/g, '$1-$2') // split camelCase/PascalCase
11 | .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2') // handle acronyms like HTMLParser
12 | .toLowerCase()}`;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/js/core/lib/decorator/_exposeComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Exposes the component constructor on the global namespace:
3 | * `self.wcagUI[ComponentName] = Component`.
4 | *
5 | * This allows programmatic usage like: `new wcagUI.Button()`.
6 | * The function is idempotent and merges with the existing `wcagUI` bag.
7 | *
8 | * @param {CustomElementConstructor & { name: string }} component - The component class to expose.
9 | * @returns {void}
10 | */
11 | export function exposeComponent(component) {
12 | Object.assign(self, { wcagUI: { ...self.wcagUI, [component.name]: component } });
13 | }
14 |
15 | // usage example: new wcagUI.Button();
16 |
--------------------------------------------------------------------------------
/packages/css/typography/lib/fonts/inter/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | src:
3 | url("./lib/fonts/inter/Inter.woff2") format("woff2 supports variations"),
4 | url("./lib/fonts/inter/Inter.woff2") format("woff2-variations");
5 | font-family: Inter;
6 | font-style: normal;
7 | font-weight: 100 900;
8 | font-display: block;
9 | }
10 |
11 | @font-face {
12 | src:
13 | url("./lib/fonts/inter/Inter-Italic.woff2") format("woff2 supports variations"),
14 | url("./lib/fonts/inter/Inter-Italic.woff2") format("woff2-variations");
15 | font-family: Inter;
16 | font-style: italic;
17 | font-weight: 100 900;
18 | font-display: block;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/css/foundations/lib/_reset.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | :where(menu, dir) {
6 | margin-inline: 0;
7 | padding-inline: 0;
8 | }
9 |
10 | :where(ul, ol, li, menu, dir) {
11 | margin-block: 0;
12 | padding-block: 0;
13 | }
14 |
15 | /* rem reset 1rem = 10px */
16 | html {
17 | font-size: 0.625em; /* 10px/16px */
18 | overscroll-behavior: none;
19 | }
20 |
21 | body {
22 | margin: 0;
23 | }
24 |
25 | hr {
26 | display: block;
27 |
28 | inline-size: 50%;
29 | block-size: 0;
30 |
31 | margin: 6em auto;
32 |
33 | border: 1px solid color-mix(in srgb, CanvasText, transparent 90%);
34 | border-radius: 1.5px;
35 | }
36 |
--------------------------------------------------------------------------------
/packages/js/core/lib/decorator/_assertMetaKey.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Asserts that a required static meta key exists on the component constructor.
3 | *
4 | * Throws a descriptive error if the key is missing.
5 | *
6 | * @param {Record} component - Component constructor (or its static bag).
7 | * @param {string} key - The required key to verify (e.g., 'events', 'attributes').
8 | * @returns {void}
9 | * @throws {Error} If the key is not present on the component.
10 | */
11 | export function assertMetaKey(component, key) {
12 | if (!component[key]) {
13 | throw new Error(`The meta ${key} is required for the wcagUI component: ${component}`);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_findNodes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * finds nodes in a given node by using the query parameter for querying the textContent
3 | *
4 | * @param {string} query - the namespace of the event
5 | * @param {Node} node - the given node
6 | * @return {Node[]}
7 | */
8 | export const findNodes = (query, node) => {
9 | if (!node.textContent?.toLowerCase().includes(query.toLowerCase())) {
10 | return [];
11 | }
12 |
13 | if (![...node.childNodes].length) {
14 | return [node];
15 | }
16 |
17 | const foundNodes = [];
18 |
19 | for (const child of [...node.childNodes]) {
20 | foundNodes.push(...findNodes(query, child));
21 | }
22 |
23 | return foundNodes;
24 | };
25 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-input--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-input--s-foc--outline-style: solid;
4 | --wcag-input--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-input--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-input"]:where(:focus, :focus-visible) {
9 | --wcag-input--outline-width: var(--wcag-input--s-foc--outline-width);
10 | --wcag-input--outline-style: var(--wcag-input--s-foc--outline-style);
11 | --wcag-input--outline-color: var(--wcag-input--s-foc--outline-color);
12 | --wcag-input--outline-offset: var(--wcag-input--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-radio--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-radio--s-foc--outline-style: solid;
4 | --wcag-radio--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-radio--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-radio"]:where(:focus, :focus-visible) {
9 | --wcag-radio--outline-width: var(--wcag-radio--s-foc--outline-width);
10 | --wcag-radio--outline-style: var(--wcag-radio--s-foc--outline-style);
11 | --wcag-radio--outline-color: var(--wcag-radio--s-foc--outline-color);
12 | --wcag-radio--outline-offset: var(--wcag-radio--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/src/foundations-elevations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | box-shadow: 0px 2px 40px -2px var(--ColorShadowS); hsla(248, 28%, 55%, 0.08)
9 | box-shadow: 0px 8px 40px -2px var(--ColorShadowM); hsla(248, 28%, 55%, 0.1)
10 | box-shadow: 0px 18px 60px 2px var(--ColorShadowM); hsla(248, 28%, 55%, 0.1)
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/foundations-typography.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Foundations
8 | Typography
9 |
10 |
11 | Type Scale
12 |
13 | Heading 1
14 | Heading 2
15 | Heading 3
16 | Heading 4
17 | Heading 5
18 | Heading 6
19 | Paragraph
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-button--s-foc--outline-style: solid;
4 | --wcag-button--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-button--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-button"]:where(:focus, :focus-visible) {
9 | --wcag-button--outline-width: var(--wcag-button--s-foc--outline-width);
10 | --wcag-button--outline-style: var(--wcag-button--s-foc--outline-style);
11 | --wcag-button--outline-color: var(--wcag-button--s-foc--outline-color);
12 | --wcag-button--outline-offset: var(--wcag-button--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-switch--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-switch--s-foc--outline-style: solid;
4 | --wcag-switch--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-switch--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-switch"]:where(:focus, :focus-visible) {
9 | --wcag-switch--outline-width: var(--wcag-switch--s-foc--outline-width);
10 | --wcag-switch--outline-style: var(--wcag-switch--s-foc--outline-style);
11 | --wcag-switch--outline-color: var(--wcag-switch--s-foc--outline-color);
12 | --wcag-switch--outline-offset: var(--wcag-switch--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/src/components-input.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Input Docs Example
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/components-radio.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Radio Docs Example
7 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/packages/js/core/lib/helpers/_debounce.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a debounced version of a callback that delays invocation
3 | * until after `threshold` milliseconds have elapsed since the last call.
4 | *
5 | * @template {(...args: any[]) => any} F
6 | * @param {F} callback - Function to debounce.
7 | * @param {number} [threshold=300] - Delay in milliseconds.
8 | * @returns {(this: ThisType, ...args: Parameters) => void} Debounced function.
9 | */
10 | export function debounce(callback, threshold = 300) {
11 | let debounce;
12 |
13 | return (...args) => {
14 | clearTimeout(debounce);
15 |
16 | debounce = setTimeout(() => {
17 | callback.apply(this, args);
18 | }, threshold);
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-checkbox--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-checkbox--s-foc--outline-style: solid;
4 | --wcag-checkbox--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-checkbox--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-checkbox"]:where(:focus, :focus-visible) {
9 | --wcag-checkbox--outline-width: var(--wcag-checkbox--s-foc--outline-width);
10 | --wcag-checkbox--outline-style: var(--wcag-checkbox--s-foc--outline-style);
11 | --wcag-checkbox--outline-color: var(--wcag-checkbox--s-foc--outline-color);
12 | --wcag-checkbox--outline-offset: var(--wcag-checkbox--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/states/_focus.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-textarea--s-foc--outline-width: var(--wcag-f--outline-width);
3 | --wcag-textarea--s-foc--outline-style: solid;
4 | --wcag-textarea--s-foc--outline-color: var(--wcag-f--outline-color);
5 | --wcag-textarea--s-foc--outline-offset: var(--wcag-f--outline-width);
6 | }
7 |
8 | [is="wcag-textarea"]:where(:focus, :focus-visible) {
9 | --wcag-textarea--outline-width: var(--wcag-textarea--s-foc--outline-width);
10 | --wcag-textarea--outline-style: var(--wcag-textarea--s-foc--outline-style);
11 | --wcag-textarea--outline-color: var(--wcag-textarea--s-foc--outline-color);
12 | --wcag-textarea--outline-offset: var(--wcag-textarea--s-foc--outline-offset);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /*
3 | --wcag-button--s-dis--color: ;
4 | --wcag-button--s-dis--background-color: ;
5 | --wcag-button--s-dis--border-color: ;
6 | */
7 |
8 | --wcag-button--s-dis--cursor: not-allowed;
9 | }
10 |
11 | [is="wcag-button"]:where([disabled], :disabled, [aria-disabled="true"]) {
12 | --wcag-button--color: var(--wcag-button--s-dis--color);
13 | --wcag-button--background-color: var(--wcag-button--s-dis--background-color);
14 | --wcag-button--border-color: var(--wcag-button--s-dis--border-color);
15 |
16 | --wcag-button--text-decoration: var(--wcag-button--s-dis--text-decoration);
17 |
18 | --wcag-button--cursor: var(--wcag-button--s-dis--cursor);
19 | }
20 |
--------------------------------------------------------------------------------
/packages/js/core/lib/helpers/_throttle.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a throttled function that only invokes `callback` at most once
3 | * every `threshold` milliseconds.
4 | *
5 | * @template {(...args: any[]) => any} F
6 | * @param {F} callback - Function to throttle.
7 | * @param {number} [threshold=300] - Minimum delay between calls.
8 | * @returns {(this: ThisType, ...args: Parameters) => void} Throttled function.
9 | */
10 | export function throttle(callback, threshold = 300) {
11 | let throttlePause;
12 |
13 | return (...args) => {
14 | if (throttlePause) return;
15 |
16 | throttlePause = true;
17 |
18 | setTimeout(() => {
19 | callback.apply(this, args);
20 | throttlePause = false;
21 | }, threshold);
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/src/common/breadcrumbs.html:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-input--s-dis--color: var(--wcag-c--neutral-50);
3 | --wcag-input--s-dis--background-color: var(--wcag-c--light);
4 | --wcag-input--s-dis--border-color: var(--wcag-c--neutral-100);
5 |
6 | --wcag-input--s-dis--cursor: not-allowed;
7 | }
8 |
9 | [is="wcag-input"]:where([disabled], :disabled, [aria-disabled="true"]) {
10 | --wcag-input--color: var(--wcag-input--s-dis--color);
11 | --wcag-input--background-color: var(--wcag-input--s-dis--background-color);
12 | --wcag-input--border-color: var(--wcag-input--s-dis--border-color);
13 |
14 | --wcag-input--text-decoration: var(--wcag-input--s-dis--text-decoration);
15 |
16 | --wcag-input--cursor: var(--wcag-input--s-dis--cursor);
17 | }
18 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-radio--s-dis--color: var(--wcag-c--neutral-50);
3 | --wcag-radio--s-dis--background-color: var(--wcag-c--light);
4 | --wcag-radio--s-dis--border-color: var(--wcag-c--neutral-100);
5 |
6 | --wcag-radio--s-dis--cursor: not-allowed;
7 | }
8 |
9 | [is="wcag-radio"]:where([disabled], :disabled, [aria-disabled="true"]) {
10 | --wcag-radio--color: var(--wcag-radio--s-dis--color);
11 | --wcag-radio--background-color: var(--wcag-radio--s-dis--background-color);
12 | --wcag-radio--border-color: var(--wcag-radio--s-dis--border-color);
13 |
14 | --wcag-radio--text-decoration: var(--wcag-radio--s-dis--text-decoration);
15 |
16 | --wcag-radio--cursor: var(--wcag-radio--s-dis--cursor);
17 | }
18 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[markdown]": {
3 | "editor.defaultFormatter": "esbenp.prettier-vscode"
4 | },
5 | "[yaml]": {
6 | "editor.defaultFormatter": "esbenp.prettier-vscode"
7 | },
8 | "[html]": {
9 | "editor.defaultFormatter": "esbenp.prettier-vscode"
10 | },
11 | "[css]": {
12 | "editor.defaultFormatter": "esbenp.prettier-vscode"
13 | },
14 | "[javascript]": {
15 | "editor.defaultFormatter": "esbenp.prettier-vscode"
16 | },
17 | "[json]": {
18 | "editor.defaultFormatter": "esbenp.prettier-vscode"
19 | },
20 | "[jsonc]": {
21 | "editor.defaultFormatter": "biomejs.biome"
22 | },
23 | "[svg]": {
24 | "editor.defaultFormatter": "jock.svg"
25 | },
26 | "files.exclude": {
27 | "**/.vscode": false
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_outerHTML.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the outer HTML of an element, with an option to exclude the element's content.
3 | *
4 | * @param {HTMLElement} element The target element from which to get the outer HTML.
5 | * @param {boolean} [excludeContent=false] A boolean flag indicating whether to exclude the content between the opening and closing tags.
6 | * If set to true, the content will be removed from the resulting HTML.
7 | * @return {string} The outer HTML of the element, optionally without its content.
8 | */
9 |
10 | export const outerHTML = (element, excludeContent = false) => {
11 | if (!excludeContent) {
12 | return element.outerHTML;
13 | }
14 |
15 | return element.outerHTML.replaceAll('\n', '').replace(/(?<=<.*?>).*(?=<\/.*>)/gm, '');
16 | };
17 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-switch--s-dis--color: var(--wcag-c--neutral-50);
3 | --wcag-switch--s-dis--background-color: var(--wcag-c--light);
4 | --wcag-switch--s-dis--border-color: var(--wcag-c--neutral-100);
5 |
6 | --wcag-switch--s-dis--cursor: not-allowed;
7 | }
8 |
9 | [is="wcag-switch"]:where([disabled], :disabled, [aria-disabled="true"]) {
10 | --wcag-switch--color: var(--wcag-switch--s-dis--color);
11 | --wcag-switch--background-color: var(--wcag-switch--s-dis--background-color);
12 | --wcag-switch--border-color: var(--wcag-switch--s-dis--border-color);
13 |
14 | --wcag-switch--text-decoration: var(--wcag-switch--s-dis--text-decoration);
15 |
16 | --wcag-switch--cursor: var(--wcag-switch--s-dis--cursor);
17 | }
18 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/linked-in.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/components/dialog/lib/dialog.js:
--------------------------------------------------------------------------------
1 | import { componentDecorator } from '@wcag-ui/core';
2 |
3 | import attributes from './dialog.attributes';
4 | import events from './dialog.events';
5 |
6 | /**
7 | * wcagUI Dialog class
8 | *
9 | * @export
10 | * @class Dialog
11 | * @extends {HTMLDialogElement}
12 | */
13 | export class Dialog extends HTMLDialogElement {
14 | static extendsElement = 'dialog';
15 | static attributes = attributes;
16 | static events = events;
17 |
18 | /**
19 | * static initialization
20 | *
21 | * @static
22 | * @memberof Dialog
23 | */
24 | static {
25 | componentDecorator(this);
26 | }
27 |
28 | constructor() {
29 | super();
30 |
31 | this.#init();
32 | }
33 |
34 | #init() {}
35 | }
36 |
37 | // import "@wcag-ui/dialog";
38 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/Read Me.txt:
--------------------------------------------------------------------------------
1 | Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures.
2 |
3 | To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/docs/#local-fonts
4 |
5 | You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects.
6 |
7 | You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection.
8 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-checkbox--s-dis--color: var(--wcag-c--neutral-50);
3 | --wcag-checkbox--s-dis--background-color: var(--wcag-c--light);
4 | --wcag-checkbox--s-dis--border-color: var(--wcag-c--neutral-100);
5 |
6 | --wcag-checkbox--s-dis--cursor: not-allowed;
7 | }
8 |
9 | [is="wcag-checkbox"]:where([disabled], :disabled, [aria-disabled="true"]) {
10 | --wcag-checkbox--color: var(--wcag-checkbox--s-dis--color);
11 | --wcag-checkbox--background-color: var(--wcag-checkbox--s-dis--background-color);
12 | --wcag-checkbox--border-color: var(--wcag-checkbox--s-dis--border-color);
13 |
14 | --wcag-checkbox--text-decoration: var(--wcag-checkbox--s-dis--text-decoration);
15 |
16 | --wcag-checkbox--cursor: var(--wcag-checkbox--s-dis--cursor);
17 | }
18 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/states/_disabled.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-textarea--s-dis--color: var(--wcag-c--neutral-50);
3 | --wcag-textarea--s-dis--background-color: var(--wcag-c--light);
4 | --wcag-textarea--s-dis--border-color: var(--wcag-c--neutral-100);
5 |
6 | --wcag-textarea--s-dis--cursor: not-allowed;
7 | }
8 |
9 | [is="wcag-textarea"]:where([disabled], :disabled, [aria-disabled="true"]) {
10 | --wcag-textarea--color: var(--wcag-textarea--s-dis--color);
11 | --wcag-textarea--background-color: var(--wcag-textarea--s-dis--background-color);
12 | --wcag-textarea--border-color: var(--wcag-textarea--s-dis--border-color);
13 |
14 | --wcag-textarea--text-decoration: var(--wcag-textarea--s-dis--text-decoration);
15 |
16 | --wcag-textarea--cursor: var(--wcag-textarea--s-dis--cursor);
17 | }
18 |
--------------------------------------------------------------------------------
/packages/js/core/lib/encoding/_jwt.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Minimal JWT helpers.
3 | */
4 | const jwt = {
5 | /**
6 | * Parses a JWT token string and returns the payload as an object.
7 | *
8 | * Note: This does not verify the signature. Intended for non-sensitive cases.
9 | *
10 | * @param {string} token - JWT in the form header.payload.signature
11 | * @returns {object}
12 | */
13 | parse: (token) => {
14 | var base64Url = token.split('.')[1];
15 | var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
16 | var jsonPayload = decodeURIComponent(
17 | atob(base64)
18 | .split('')
19 | .map((c) => `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`)
20 | .join(''),
21 | );
22 |
23 | return JSON.parse(jsonPayload);
24 | },
25 | };
26 |
27 | export { jwt };
28 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_ensureElement.js:
--------------------------------------------------------------------------------
1 | import { createElement } from './_createElement';
2 |
3 | /**
4 | * create an element and return it
5 | *
6 | * @param {Element|TElementOptions} elementOrOptions - instance of an element or options
7 | * @return {boolean} true, if the parameter is an Element
8 | */
9 | function isElement(elementOrOptions) {
10 | return elementOrOptions instanceof HTMLElement || elementOrOptions instanceof DocumentFragment;
11 | }
12 |
13 | /**
14 | * checks if the parameter is an element or creates it
15 | *
16 | * @param {Element|TElementOptions} elementOrOptions - the element or the options for building it
17 | * @return {Element}
18 | */
19 | export const ensureElement = (elementOrOptions) => {
20 | return isElement(elementOrOptions) ? elementOrOptions : createElement(elementOrOptions);
21 | };
22 |
--------------------------------------------------------------------------------
/packages/js/core/lib/decorator/_defineCustomElement.js:
--------------------------------------------------------------------------------
1 | import { buildExtendOptions } from './_buildExtendOptions';
2 |
3 | /**
4 | * Defines the component as a Custom Element if not already registered.
5 | *
6 | * - Skips definition if `customElements` is not available.
7 | * - Skips if the tag is already defined.
8 | * - Uses `extends` option when `component.extendsElement` is provided.
9 | *
10 | * @param {CustomElementConstructor & { extendsElement?: string }} component - Component class.
11 | * @param {string} isAttribute - Custom element tag to register (e.g., "wcag-tree-view").
12 | * @returns {void}
13 | */
14 | export function defineCustomElement(component, isAttribute) {
15 | !!customElements &&
16 | !customElements.get(isAttribute) &&
17 | customElements.define(isAttribute, component, buildExtendOptions(component));
18 | }
19 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-input--md--gap: 1.2rem;
3 |
4 | --wcag-input--md--height: 4.4rem;
5 | --wcag-input--md--padding-inline: 2rem;
6 | --wcag-input--md--padding-block: 0;
7 | --wcag-input--md--border-width: 1px;
8 | --wcag-input--md--border-radius: 0.4rem;
9 |
10 | --wcag-input--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-input"] {
14 | --wcag-input--gap: var(--wcag-input--md--gap);
15 |
16 | --wcag-input--height: var(--wcag-input--md--height);
17 | --wcag-input--padding-inline: var(--wcag-input--md--padding-inline);
18 | --wcag-input--padding-block: var(--wcag-input--md--padding-block);
19 | --wcag-input--border-width: var(--wcag-input--md--border-width);
20 | --wcag-input--border-radius: var(--wcag-input--md--border-radius);
21 |
22 | --wcag-input--font-size: var(--wcag-input--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-radio--md--gap: 1.2rem;
3 |
4 | --wcag-radio--md--height: 4.4rem;
5 | --wcag-radio--md--padding-inline: 2rem;
6 | --wcag-radio--md--padding-block: 0;
7 | --wcag-radio--md--border-width: 1px;
8 | --wcag-radio--md--border-radius: 0.4rem;
9 |
10 | --wcag-radio--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-radio"] {
14 | --wcag-radio--gap: var(--wcag-radio--md--gap);
15 |
16 | --wcag-radio--height: var(--wcag-radio--md--height);
17 | --wcag-radio--padding-inline: var(--wcag-radio--md--padding-inline);
18 | --wcag-radio--padding-block: var(--wcag-radio--md--padding-block);
19 | --wcag-radio--border-width: var(--wcag-radio--md--border-width);
20 | --wcag-radio--border-radius: var(--wcag-radio--md--border-radius);
21 |
22 | --wcag-radio--font-size: var(--wcag-radio--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/scheme-light.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_createElement.js:
--------------------------------------------------------------------------------
1 | import { sanitizeHTML } from './_sanitizeHTML';
2 |
3 | /**
4 | * create an element and return it
5 | *
6 | * @param {TElementOptions} options of the element to create
7 | * @return {Element}
8 | */
9 | export const createElement = (options) => {
10 | if (!options.tag) {
11 | throw new Error(`wcag-ui.core.createElement error: no tag provided`);
12 | }
13 |
14 | const element = document.createElement(options.tag);
15 |
16 | options.classes && element.classList.add(...options.classes);
17 |
18 | for (const [key, value] of Object.entries(options.attributes ?? {})) {
19 | element.setAttribute(key, value);
20 | }
21 |
22 | const fragment = document.createDocumentFragment();
23 | fragment.append(...sanitizeHTML(options.content, true));
24 |
25 | options.content && element.append(fragment);
26 |
27 | return element;
28 | };
29 |
--------------------------------------------------------------------------------
/.github/coding-styleguides/a11y.md:
--------------------------------------------------------------------------------
1 | # a11y-standards
2 |
3 | The place for all the A11y standards, best practices, naming conventions and other amenities
4 |
5 | A screen reader is a technology that helps people who have difficulty seeing access and interact with digital content, like websites or applications via audio or touch or keyboard. The main users of screen readers are people who are blind or have very limited vision.
6 |
7 | This is one of the most important websites for accessibility:
8 | https://www.w3.org/WAI/ARIA/apg/patterns/
9 | it has definitions of keyboard interactions, aria attributes and rules for properly implementing visual patterns for accessibility.
10 |
11 | Here are some other useful accessibility links:
12 | https://medium.com/weekly-webtips/10-accessibility-best-practices-cb66b666fa0f
13 | https://dev.to/brittneypostma/accessibility-best-practices-for-html-css-d51?s=09
14 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-input--lg--gap: 1.6rem;
3 |
4 | --wcag-input--lg--height: 5.6rem;
5 | --wcag-input--lg--padding-inline: 2rem;
6 | --wcag-input--lg--padding-block: 0;
7 | --wcag-input--lg--border-width: 1px;
8 | --wcag-input--lg--border-radius: 0.5rem;
9 |
10 | --wcag-input--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-input"][lg] {
14 | --wcag-input--gap: var(--wcag-input--lg--gap);
15 |
16 | --wcag-input--height: var(--wcag-input--lg--height);
17 | --wcag-input--padding-inline: var(--wcag-input--lg--padding-inline);
18 | --wcag-input--padding-block: var(--wcag-input--lg--padding-block);
19 | --wcag-input--border-width: var(--wcag-input--lg--border-width);
20 | --wcag-input--border-radius: var(--wcag-input--lg--border-radius);
21 |
22 | --wcag-input--font-size: var(--wcag-input--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/input/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-input--sm--gap: 0.8rem;
3 |
4 | --wcag-input--sm--height: 4rem;
5 | --wcag-input--sm--padding-inline: 1.2rem;
6 | --wcag-input--sm--padding-block: 0;
7 | --wcag-input--sm--border-width: 1px;
8 | --wcag-input--sm--border-radius: 0.35rem;
9 |
10 | --wcag-input--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-input"][sm] {
14 | --wcag-input--gap: var(--wcag-input--sm--gap);
15 |
16 | --wcag-input--height: var(--wcag-input--sm--height);
17 | --wcag-input--padding-inline: var(--wcag-input--sm--padding-inline);
18 | --wcag-input--padding-block: var(--wcag-input--sm--padding-block);
19 | --wcag-input--border-width: var(--wcag-input--sm--border-width);
20 | --wcag-input--border-radius: var(--wcag-input--sm--border-radius);
21 |
22 | --wcag-input--font-size: var(--wcag-input--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-radio--lg--gap: 1.6rem;
3 |
4 | --wcag-radio--lg--height: 5.6rem;
5 | --wcag-radio--lg--padding-inline: 2rem;
6 | --wcag-radio--lg--padding-block: 0;
7 | --wcag-radio--lg--border-width: 1px;
8 | --wcag-radio--lg--border-radius: 0.5rem;
9 |
10 | --wcag-radio--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-radio"][lg] {
14 | --wcag-radio--gap: var(--wcag-radio--lg--gap);
15 |
16 | --wcag-radio--height: var(--wcag-radio--lg--height);
17 | --wcag-radio--padding-inline: var(--wcag-radio--lg--padding-inline);
18 | --wcag-radio--padding-block: var(--wcag-radio--lg--padding-block);
19 | --wcag-radio--border-width: var(--wcag-radio--lg--border-width);
20 | --wcag-radio--border-radius: var(--wcag-radio--lg--border-radius);
21 |
22 | --wcag-radio--font-size: var(--wcag-radio--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-radio--sm--gap: 0.8rem;
3 |
4 | --wcag-radio--sm--height: 4rem;
5 | --wcag-radio--sm--padding-inline: 1.2rem;
6 | --wcag-radio--sm--padding-block: 0;
7 | --wcag-radio--sm--border-width: 1px;
8 | --wcag-radio--sm--border-radius: 0.35rem;
9 |
10 | --wcag-radio--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-radio"][sm] {
14 | --wcag-radio--gap: var(--wcag-radio--sm--gap);
15 |
16 | --wcag-radio--height: var(--wcag-radio--sm--height);
17 | --wcag-radio--padding-inline: var(--wcag-radio--sm--padding-inline);
18 | --wcag-radio--padding-block: var(--wcag-radio--sm--padding-block);
19 | --wcag-radio--border-width: var(--wcag-radio--sm--border-width);
20 | --wcag-radio--border-radius: var(--wcag-radio--sm--border-radius);
21 |
22 | --wcag-radio--font-size: var(--wcag-radio--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/tree-view/lib/tree-view.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { componentDecorator, helpers } from '@wcag-ui/core';
3 | import { DOM } from '@wcag-ui/dom';
4 |
5 | import attributes from './tree-view.attributes';
6 | import events from './tree-view.events';
7 |
8 | /**
9 | * wcagUI treeView class
10 | *
11 | * @export
12 | * @class treeView
13 | * @extends {HTMLElement}
14 | */
15 | export class TreeView extends HTMLElement {
16 | static extendsElement = 'section';
17 | static attributes = attributes;
18 | static events = events;
19 |
20 | /**
21 | * static initialization
22 | *
23 | * @static
24 | * @memberof treeView
25 | */
26 | static {
27 | componentDecorator(this);
28 | }
29 |
30 | constructor() {
31 | super();
32 |
33 | this.#init();
34 | }
35 |
36 | #init() {}
37 | }
38 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--md--gap: 1.2rem;
3 |
4 | --wcag-button--md--height: 4.4rem;
5 | --wcag-button--md--padding-inline: 2rem;
6 | --wcag-button--md--padding-block: 0;
7 | --wcag-button--md--border-width: 1px;
8 | --wcag-button--md--border-radius: 0.4rem;
9 |
10 | --wcag-button--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-button"] {
14 | --wcag-button--gap: var(--wcag-button--md--gap);
15 |
16 | --wcag-button--height: var(--wcag-button--md--height);
17 | --wcag-button--padding-inline: var(--wcag-button--md--padding-inline);
18 | --wcag-button--padding-block: var(--wcag-button--md--padding-block);
19 | --wcag-button--border-width: var(--wcag-button--md--border-width);
20 | --wcag-button--border-radius: var(--wcag-button--md--border-radius);
21 |
22 | --wcag-button--font-size: var(--wcag-button--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-switch--md--gap: 1.2rem;
3 |
4 | --wcag-switch--md--height: 4.4rem;
5 | --wcag-switch--md--padding-inline: 2rem;
6 | --wcag-switch--md--padding-block: 0;
7 | --wcag-switch--md--border-width: 1px;
8 | --wcag-switch--md--border-radius: 0.4rem;
9 |
10 | --wcag-switch--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-switch"] {
14 | --wcag-switch--gap: var(--wcag-switch--md--gap);
15 |
16 | --wcag-switch--height: var(--wcag-switch--md--height);
17 | --wcag-switch--padding-inline: var(--wcag-switch--md--padding-inline);
18 | --wcag-switch--padding-block: var(--wcag-switch--md--padding-block);
19 | --wcag-switch--border-width: var(--wcag-switch--md--border-width);
20 | --wcag-switch--border-radius: var(--wcag-switch--md--border-radius);
21 |
22 | --wcag-switch--font-size: var(--wcag-switch--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--lg--gap: 1.6rem;
3 |
4 | --wcag-button--lg--height: 5.6rem;
5 | --wcag-button--lg--padding-inline: 2rem;
6 | --wcag-button--lg--padding-block: 0;
7 | --wcag-button--lg--border-width: 1px;
8 | --wcag-button--lg--border-radius: 0.5rem;
9 |
10 | --wcag-button--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-button"][lg] {
14 | --wcag-button--gap: var(--wcag-button--lg--gap);
15 |
16 | --wcag-button--height: var(--wcag-button--lg--height);
17 | --wcag-button--padding-inline: var(--wcag-button--lg--padding-inline);
18 | --wcag-button--padding-block: var(--wcag-button--lg--padding-block);
19 | --wcag-button--border-width: var(--wcag-button--lg--border-width);
20 | --wcag-button--border-radius: var(--wcag-button--lg--border-radius);
21 |
22 | --wcag-button--font-size: var(--wcag-button--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/button/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-button--sm--gap: 0.8rem;
3 |
4 | --wcag-button--sm--height: 4rem;
5 | --wcag-button--sm--padding-inline: 1.2rem;
6 | --wcag-button--sm--padding-block: 0;
7 | --wcag-button--sm--border-width: 1px;
8 | --wcag-button--sm--border-radius: 0.35rem;
9 |
10 | --wcag-button--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-button"][sm] {
14 | --wcag-button--gap: var(--wcag-button--sm--gap);
15 |
16 | --wcag-button--height: var(--wcag-button--sm--height);
17 | --wcag-button--padding-inline: var(--wcag-button--sm--padding-inline);
18 | --wcag-button--padding-block: var(--wcag-button--sm--padding-block);
19 | --wcag-button--border-width: var(--wcag-button--sm--border-width);
20 | --wcag-button--border-radius: var(--wcag-button--sm--border-radius);
21 |
22 | --wcag-button--font-size: var(--wcag-button--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-switch--lg--gap: 1.6rem;
3 |
4 | --wcag-switch--lg--height: 5.6rem;
5 | --wcag-switch--lg--padding-inline: 2rem;
6 | --wcag-switch--lg--padding-block: 0;
7 | --wcag-switch--lg--border-width: 1px;
8 | --wcag-switch--lg--border-radius: 0.5rem;
9 |
10 | --wcag-switch--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-switch"][lg] {
14 | --wcag-switch--gap: var(--wcag-switch--lg--gap);
15 |
16 | --wcag-switch--height: var(--wcag-switch--lg--height);
17 | --wcag-switch--padding-inline: var(--wcag-switch--lg--padding-inline);
18 | --wcag-switch--padding-block: var(--wcag-switch--lg--padding-block);
19 | --wcag-switch--border-width: var(--wcag-switch--lg--border-width);
20 | --wcag-switch--border-radius: var(--wcag-switch--lg--border-radius);
21 |
22 | --wcag-switch--font-size: var(--wcag-switch--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-switch--sm--gap: 0.8rem;
3 |
4 | --wcag-switch--sm--height: 4rem;
5 | --wcag-switch--sm--padding-inline: 1.2rem;
6 | --wcag-switch--sm--padding-block: 0;
7 | --wcag-switch--sm--border-width: 1px;
8 | --wcag-switch--sm--border-radius: 0.35rem;
9 |
10 | --wcag-switch--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-switch"][sm] {
14 | --wcag-switch--gap: var(--wcag-switch--sm--gap);
15 |
16 | --wcag-switch--height: var(--wcag-switch--sm--height);
17 | --wcag-switch--padding-inline: var(--wcag-switch--sm--padding-inline);
18 | --wcag-switch--padding-block: var(--wcag-switch--sm--padding-block);
19 | --wcag-switch--border-width: var(--wcag-switch--sm--border-width);
20 | --wcag-switch--border-radius: var(--wcag-switch--sm--border-radius);
21 |
22 | --wcag-switch--font-size: var(--wcag-switch--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/js/core/lib/events/_dispatchComponentEvent.js:
--------------------------------------------------------------------------------
1 | import { dispatchCustomEvent } from './_dispatchCustomEvent';
2 |
3 | /**
4 | * Dispatches a namespaced custom event for a wcag-ui component instance.
5 | *
6 | * Uses `this.componentName` as the namespace and `${componentName}.${eventName}` as final event type.
7 | *
8 | * @param {string} eventName - Event name (e.g., "open", "close").
9 | * @param {object} details - Data to include in `event.detail`.
10 | * @param {Event} [originalEvent=undefined] - Optional originating DOM event.
11 | * @returns {void}
12 | */
13 | export const dispatchComponentEvent = function (eventName, details, originalEvent = undefined) {
14 | const componentName = this.componentName;
15 |
16 | dispatchCustomEvent.call(
17 | this,
18 | componentName,
19 | eventName,
20 | details,
21 | originalEvent ?? new Event(`${componentName}.${eventName}`)
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/scripts/templates/component/lib/component-name.js:
--------------------------------------------------------------------------------
1 | /** biome-ignore-all lint/correctness/noUnusedImports: */
2 | import { componentDecorator, helpers } from '@wcag-ui/core';
3 | import { DOM } from '@wcag-ui/dom';
4 |
5 | import attributes from './component-name.attributes';
6 | import events from './component-name.events';
7 |
8 | /**
9 | * wcagUI ComponentName class
10 | *
11 | * @export
12 | * @class ComponentName
13 | * @extends {HTMLElement}
14 | */
15 | export class ComponentName extends HTMLElement {
16 | static extendsElement = 'section';
17 | static attributes = attributes;
18 | static events = events;
19 |
20 | /**
21 | * static initialization
22 | *
23 | * @static
24 | * @memberof ComponentName
25 | */
26 | static {
27 | componentDecorator(this);
28 | }
29 |
30 | constructor() {
31 | super();
32 |
33 | this.#init();
34 | }
35 |
36 | #init() {}
37 | }
38 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-checkbox--md--gap: 1.2rem;
3 |
4 | --wcag-checkbox--md--height: 4.4rem;
5 | --wcag-checkbox--md--padding-inline: 2rem;
6 | --wcag-checkbox--md--padding-block: 0;
7 | --wcag-checkbox--md--border-width: 1px;
8 | --wcag-checkbox--md--border-radius: 0.4rem;
9 |
10 | --wcag-checkbox--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-checkbox"] {
14 | --wcag-checkbox--gap: var(--wcag-checkbox--md--gap);
15 |
16 | --wcag-checkbox--height: var(--wcag-checkbox--md--height);
17 | --wcag-checkbox--padding-inline: var(--wcag-checkbox--md--padding-inline);
18 | --wcag-checkbox--padding-block: var(--wcag-checkbox--md--padding-block);
19 | --wcag-checkbox--border-width: var(--wcag-checkbox--md--border-width);
20 | --wcag-checkbox--border-radius: var(--wcag-checkbox--md--border-radius);
21 |
22 | --wcag-checkbox--font-size: var(--wcag-checkbox--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/dimensions/_medium.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-textarea--md--gap: 1.2rem;
3 |
4 | --wcag-textarea--md--height: 4.4rem;
5 | --wcag-textarea--md--padding-inline: 2rem;
6 | --wcag-textarea--md--padding-block: 0;
7 | --wcag-textarea--md--border-width: 1px;
8 | --wcag-textarea--md--border-radius: 0.4rem;
9 |
10 | --wcag-textarea--md--font-size: 1.6rem;
11 | }
12 |
13 | [is="wcag-textarea"] {
14 | --wcag-textarea--gap: var(--wcag-textarea--md--gap);
15 |
16 | --wcag-textarea--height: var(--wcag-textarea--md--height);
17 | --wcag-textarea--padding-inline: var(--wcag-textarea--md--padding-inline);
18 | --wcag-textarea--padding-block: var(--wcag-textarea--md--padding-block);
19 | --wcag-textarea--border-width: var(--wcag-textarea--md--border-width);
20 | --wcag-textarea--border-radius: var(--wcag-textarea--md--border-radius);
21 |
22 | --wcag-textarea--font-size: var(--wcag-textarea--md--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-checkbox--lg--gap: 1.6rem;
3 |
4 | --wcag-checkbox--lg--height: 5.6rem;
5 | --wcag-checkbox--lg--padding-inline: 2rem;
6 | --wcag-checkbox--lg--padding-block: 0;
7 | --wcag-checkbox--lg--border-width: 1px;
8 | --wcag-checkbox--lg--border-radius: 0.5rem;
9 |
10 | --wcag-checkbox--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-checkbox"][lg] {
14 | --wcag-checkbox--gap: var(--wcag-checkbox--lg--gap);
15 |
16 | --wcag-checkbox--height: var(--wcag-checkbox--lg--height);
17 | --wcag-checkbox--padding-inline: var(--wcag-checkbox--lg--padding-inline);
18 | --wcag-checkbox--padding-block: var(--wcag-checkbox--lg--padding-block);
19 | --wcag-checkbox--border-width: var(--wcag-checkbox--lg--border-width);
20 | --wcag-checkbox--border-radius: var(--wcag-checkbox--lg--border-radius);
21 |
22 | --wcag-checkbox--font-size: var(--wcag-checkbox--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-checkbox--sm--gap: 0.8rem;
3 |
4 | --wcag-checkbox--sm--height: 4rem;
5 | --wcag-checkbox--sm--padding-inline: 1.2rem;
6 | --wcag-checkbox--sm--padding-block: 0;
7 | --wcag-checkbox--sm--border-width: 1px;
8 | --wcag-checkbox--sm--border-radius: 0.35rem;
9 |
10 | --wcag-checkbox--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-checkbox"][sm] {
14 | --wcag-checkbox--gap: var(--wcag-checkbox--sm--gap);
15 |
16 | --wcag-checkbox--height: var(--wcag-checkbox--sm--height);
17 | --wcag-checkbox--padding-inline: var(--wcag-checkbox--sm--padding-inline);
18 | --wcag-checkbox--padding-block: var(--wcag-checkbox--sm--padding-block);
19 | --wcag-checkbox--border-width: var(--wcag-checkbox--sm--border-width);
20 | --wcag-checkbox--border-radius: var(--wcag-checkbox--sm--border-radius);
21 |
22 | --wcag-checkbox--font-size: var(--wcag-checkbox--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/dimensions/_large.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-textarea--lg--gap: 1.6rem;
3 |
4 | --wcag-textarea--lg--height: 5.6rem;
5 | --wcag-textarea--lg--padding-inline: 2rem;
6 | --wcag-textarea--lg--padding-block: 0;
7 | --wcag-textarea--lg--border-width: 1px;
8 | --wcag-textarea--lg--border-radius: 0.5rem;
9 |
10 | --wcag-textarea--lg--font-size: 1.8rem;
11 | }
12 |
13 | [is="wcag-textarea"][lg] {
14 | --wcag-textarea--gap: var(--wcag-textarea--lg--gap);
15 |
16 | --wcag-textarea--height: var(--wcag-textarea--lg--height);
17 | --wcag-textarea--padding-inline: var(--wcag-textarea--lg--padding-inline);
18 | --wcag-textarea--padding-block: var(--wcag-textarea--lg--padding-block);
19 | --wcag-textarea--border-width: var(--wcag-textarea--lg--border-width);
20 | --wcag-textarea--border-radius: var(--wcag-textarea--lg--border-radius);
21 |
22 | --wcag-textarea--font-size: var(--wcag-textarea--lg--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/styles/dimensions/_small.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --wcag-textarea--sm--gap: 0.8rem;
3 |
4 | --wcag-textarea--sm--height: 4rem;
5 | --wcag-textarea--sm--padding-inline: 1.2rem;
6 | --wcag-textarea--sm--padding-block: 0;
7 | --wcag-textarea--sm--border-width: 1px;
8 | --wcag-textarea--sm--border-radius: 0.35rem;
9 |
10 | --wcag-textarea--sm--font-size: 1.4rem;
11 | }
12 |
13 | [is="wcag-textarea"][sm] {
14 | --wcag-textarea--gap: var(--wcag-textarea--sm--gap);
15 |
16 | --wcag-textarea--height: var(--wcag-textarea--sm--height);
17 | --wcag-textarea--padding-inline: var(--wcag-textarea--sm--padding-inline);
18 | --wcag-textarea--padding-block: var(--wcag-textarea--sm--padding-block);
19 | --wcag-textarea--border-width: var(--wcag-textarea--sm--border-width);
20 | --wcag-textarea--border-radius: var(--wcag-textarea--sm--border-radius);
21 |
22 | --wcag-textarea--font-size: var(--wcag-textarea--sm--font-size);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_insertElement.js:
--------------------------------------------------------------------------------
1 | import { ensureElement } from './_ensureElement';
2 |
3 | /**
4 | * @typedef TInsertPositions
5 | * @type {'before'|'prepend'|'append'|'after'}
6 | */
7 |
8 | export const EInsertPositions = Object.freeze({
9 | before: 'beforebegin',
10 | prepend: 'afterbegin',
11 | append: 'beforeend',
12 | after: 'afterend',
13 | });
14 |
15 | /**
16 | * insert an element in a certain position respect to another element
17 | *
18 | * @param {Element|TElementOptions} elementOrOptions - the element to insert or the options of it
19 | * @param {Element} target - the target element
20 | * @param {TInsertPositions} position - where insert the element
21 | * @return {Element} the element
22 | */
23 | export const insertElement = (elementOrOptions, target, position) => {
24 | const element = ensureElement(elementOrOptions);
25 |
26 | target.insertAdjacentElement(EInsertPositions[position], element);
27 |
28 | return element;
29 | };
30 |
--------------------------------------------------------------------------------
/packages/css/grid-system/lib/_container-breakpoints.css:
--------------------------------------------------------------------------------
1 |
2 | /* iphone max */
3 | @media screen and (width >= 414px) {
4 | :root {
5 | --wcag-gs--container--size: 375px;
6 | }
7 | }
8 |
9 | /* xs */
10 | @media screen and (width >= 576px) {
11 | :root {
12 | --wcag-gs--container--size: 540px;
13 | }
14 | }
15 |
16 | /* sm */
17 | @media screen and (width >= 768px) {
18 | :root {
19 | --wcag-gs--container--size: 720px;
20 | }
21 | }
22 |
23 | /* md */
24 | @media screen and (width >= 1024px) {
25 | :root {
26 | --wcag-gs--container--size: 960px;
27 | }
28 | }
29 |
30 | /* lg */
31 | @media screen and (width >= 1366px) {
32 | :root {
33 | --wcag-gs--container--size: 1200px;
34 | }
35 | }
36 |
37 | /* xl */
38 | @media screen and (width >= 1600px) {
39 | :root {
40 | --wcag-gs--container--size: 1366px;
41 | }
42 | }
43 |
44 | /* xxl */
45 | @media screen and (width >= 1920px) {
46 | :root {
47 | --wcag-gs--container--size: 1600px;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/packages/js/core/lib/helpers/_files.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Normalizes an array of File or a FileList into a FileList instance.
3 | *
4 | * @param {File[] | FileList} fileArrayOrList
5 | * @returns {FileList}
6 | */
7 | const buildFileList = (fileArrayOrList) => {
8 | if (fileArrayOrList instanceof FileList) {
9 | return fileArrayOrList;
10 | }
11 |
12 | const dataTransfer = new DataTransfer();
13 |
14 | for (const file of fileArrayOrList) {
15 | dataTransfer.items.add(file);
16 | }
17 |
18 | return dataTransfer.files;
19 | };
20 |
21 | /**
22 | * Normalizes an array of File or a FileList into a File[] array.
23 | *
24 | * @param {File[] | FileList} fileArrayOrList
25 | * @returns {File[]}
26 | */
27 | const buildFileArray = (fileArrayOrList) => {
28 | if (Array.isArray(fileArrayOrList)) {
29 | return fileArrayOrList;
30 | }
31 |
32 | return Array.from(fileArrayOrList);
33 | };
34 |
35 | const files = {
36 | buildFileList,
37 | buildFileArray,
38 | };
39 |
40 | export { files };
41 |
--------------------------------------------------------------------------------
/scripts/_cli-utils.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * Parses command line arguments in the format --key=value or --key.
3 | * Returns an object with key-value pairs.
4 | *
5 | * @example Parse CLI arguments
6 | * const args = parseArgs(process.argv);
7 | * // args = { foo: 'bar', dryRun: true }
8 | *
9 | * @export
10 | * @param {string[]} argv - Array of CLI arguments (usually process.argv)
11 | * @returns {Object} Parsed arguments as key-value pairs
12 | */
13 | export function parseArgs(argv) {
14 | const args = {};
15 |
16 | // Iterate over CLI arguments, skipping the first two (node and script path)
17 | for (const token of argv.slice(2)) {
18 | // Match --key or --key=value
19 | const m = token.match(/^--([^=\s]+)(?:=(.*))?$/);
20 |
21 | if (!m) {
22 | continue;
23 | }
24 |
25 | const key = m[1];
26 | // If no value is provided, treat as boolean true
27 | const val = m[2] === undefined ? true : m[2];
28 | args[key] = val;
29 | }
30 |
31 | return args;
32 | }
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_wrapElement.js:
--------------------------------------------------------------------------------
1 | import { ensureElement } from './_ensureElement';
2 | import { insertElement } from './_insertElement';
3 | /**
4 | * insert an element in a certain position respect to another element
5 | *
6 | * @param {Element|TElementOptions} elementOrOptions - the element to be wrapped or the options to build it
7 | * @param {Element|TElementOptions} wrapperElementOrOptions - the wrapperElement or the options to build it
8 | * @return {Element} the wrapper element
9 | */
10 | export const wrapElement = (elementOrOptions, wrapperElementOrOptions) => {
11 | const element = ensureElement(elementOrOptions);
12 | const wrapperElement = ensureElement(wrapperElementOrOptions);
13 |
14 | // checks if the wrapperElement isConnected or not to the DOM,
15 | // if not the wrapperElement will be put before begin the element
16 | !wrapperElement.isConnected && insertElement(wrapperElement, element, 'before');
17 |
18 | insertElement(element, wrapperElement, 'append');
19 |
20 | return wrapperElement;
21 | };
22 |
--------------------------------------------------------------------------------
/src/common/header.html:
--------------------------------------------------------------------------------
1 |
33 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/js/core/lib/events/_cancelEvent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cancels a DOM event by optionally calling preventDefault, stopPropagation,
3 | * and stopImmediatePropagation.
4 | *
5 | * Returns `false` for ergonomic usage inside handlers (e.g., `return cancelEvent(e)`).
6 | * If no event is provided, returns `undefined`.
7 | *
8 | * @param {Event} e - The DOM event to cancel.
9 | * @param {boolean} [preventDefault=true] - Whether to call `e.preventDefault()`.
10 | * @param {boolean} [stopPropagation=true] - Whether to call `e.stopPropagation()`.
11 | * @param {boolean} [stopImmediatePropagation=true] - Whether to call `e.stopImmediatePropagation()`.
12 | * @returns {false|undefined}
13 | */
14 | export const cancelEvent = (
15 | e,
16 | preventDefault = true,
17 | stopPropagation = true,
18 | stopImmediatePropagation = true
19 | ) => {
20 | if (!e) {
21 | return;
22 | }
23 |
24 | !!preventDefault && e.preventDefault();
25 | !!stopPropagation && e.stopPropagation();
26 | !!stopImmediatePropagation && e.stopImmediatePropagation();
27 |
28 | return false;
29 | };
30 |
--------------------------------------------------------------------------------
/src/assets/background-image.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/packages/js/core/lib/core.js:
--------------------------------------------------------------------------------
1 | import './polyfills';
2 |
3 | import { componentDecorator } from './decorator';
4 | import { encoding } from './encoding';
5 | import { events } from './events';
6 | import { helpers } from './helpers';
7 |
8 | /**
9 | * Core global stylesheet used to declare CSS cascade layers for wcag-ui.
10 | *
11 | * Declares three layers in order: `wcag-ui.core`, `wcag-ui.foundations`, `wcag-ui.components`.
12 | * Consumers can import their own CSS within these layers to control precedence.
13 | */
14 | export const coreStyleSheet = new CSSStyleSheet();
15 | coreStyleSheet.replaceSync('@layer wcag-ui.core, wcag-ui.foundations, wcag-ui.components;');
16 |
17 | // Attach the stylesheet using Constructable Stylesheets API.
18 | // Note: add a feature detection or fallback if you need to support older browsers.
19 | // Example:
20 | // if ('adoptedStyleSheets' in Document.prototype) { document.adoptedStyleSheets.push(coreStyleSheet); }
21 | document.adoptedStyleSheets.push(coreStyleSheet);
22 |
23 | // Public surface of the core package
24 | export { componentDecorator, encoding, events, helpers };
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024-2025 Dev Dojo IT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/demo-files/demo.js:
--------------------------------------------------------------------------------
1 | if (!('boxShadow' in document.body.style)) {
2 | document.body.setAttribute('class', 'noBoxShadow');
3 | }
4 |
5 | document.body.addEventListener("click", (e) => {
6 | var target = e.target;
7 | if (target.tagName === "INPUT" &&
8 | target.getAttribute('class').indexOf('liga') === -1) {
9 | target.select();
10 | }
11 | });
12 |
13 | ((() => {
14 | var fontSize = document.getElementById('fontSize'),
15 | testDrive = document.getElementById('testDrive'),
16 | testText = document.getElementById('testText');
17 | function updateTest() {
18 | testDrive.innerHTML = testText.value || String.fromCharCode(160);
19 | if (window.icomoonLiga) {
20 | window.icomoonLiga(testDrive);
21 | }
22 | }
23 | function updateSize() {
24 | testDrive.style.fontSize = fontSize.value + 'px';
25 | }
26 | fontSize.addEventListener('change', updateSize, false);
27 | testText.addEventListener('input', updateTest, false);
28 | testText.addEventListener('change', updateTest, false);
29 | updateSize();
30 | })());
31 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/dev-dojo.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/components/input/lib/input.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | input: function (e) {
5 | console.log('input emitted input', this.ariaLabel);
6 |
7 | // style :user-invalid or :user-valid
8 |
9 | events.dispatchComponentEvent.call(this, 'input', { value: this.value }, e);
10 | },
11 | change: function (e) {
12 | console.log('input emitted change', this.ariaLabel);
13 |
14 | // style :user-invalid or :user-valid
15 |
16 | events.dispatchComponentEvent.call(this, 'change', { value: this.value }, e);
17 | },
18 | focus: function (e) {
19 | console.log('input emitted focus', this.ariaLabel);
20 |
21 | events.dispatchComponentEvent.call(this, 'focus', { value: this.value }, e);
22 | },
23 | blur: function (e) {
24 | console.log('input emitted blur', this.ariaLabel);
25 |
26 | events.dispatchComponentEvent.call(this, 'blur', { value: this.value }, e);
27 | },
28 | invalid: function (e) {
29 | console.log('input emitted invalid', this.ariaLabel);
30 |
31 | // style :user-invalid or :user-valid
32 |
33 | events.dispatchComponentEvent.call(this, 'invalid', { value: this.value }, e);
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/packages/components/radio/lib/radio.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | input: function (e) {
5 | console.log('radio emitted input', this.ariaLabel);
6 |
7 | // style :user-invalid or :user-valid
8 |
9 | events.dispatchComponentEvent.call(this, 'input', { value: this.value }, e);
10 | },
11 | change: function (e) {
12 | console.log('radio emitted change', this.ariaLabel);
13 |
14 | // style :user-invalid or :user-valid
15 |
16 | events.dispatchComponentEvent.call(this, 'change', { value: this.value }, e);
17 | },
18 | focus: function (e) {
19 | console.log('radio emitted focus', this.ariaLabel);
20 |
21 | events.dispatchComponentEvent.call(this, 'focus', { value: this.value }, e);
22 | },
23 | blur: function (e) {
24 | console.log('radio emitted blur', this.ariaLabel);
25 |
26 | events.dispatchComponentEvent.call(this, 'blur', { value: this.value }, e);
27 | },
28 | invalid: function (e) {
29 | console.log('radio emitted invalid', this.ariaLabel);
30 |
31 | // style :user-invalid or :user-valid
32 |
33 | events.dispatchComponentEvent.call(this, 'invalid', { value: this.value }, e);
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/packages/css/iconography/lib/fonts/wcag-icons/SVG/figma.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/packages/components/switch/lib/switch.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | input: function (e) {
5 | console.log('switch emitted input', this.ariaLabel);
6 |
7 | // style :user-invalid or :user-valid
8 |
9 | events.dispatchComponentEvent.call(this, 'input', { value: this.value }, e);
10 | },
11 | change: function (e) {
12 | console.log('switch emitted change', this.ariaLabel);
13 |
14 | // style :user-invalid or :user-valid
15 |
16 | events.dispatchComponentEvent.call(this, 'change', { value: this.value }, e);
17 | },
18 | focus: function (e) {
19 | console.log('switch emitted focus', this.ariaLabel);
20 |
21 | events.dispatchComponentEvent.call(this, 'focus', { value: this.value }, e);
22 | },
23 | blur: function (e) {
24 | console.log('switch emitted blur', this.ariaLabel);
25 |
26 | events.dispatchComponentEvent.call(this, 'blur', { value: this.value }, e);
27 | },
28 | invalid: function (e) {
29 | console.log('switch emitted invalid', this.ariaLabel);
30 |
31 | // style :user-invalid or :user-valid
32 |
33 | events.dispatchComponentEvent.call(this, 'invalid', { value: this.value }, e);
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/packages/components/checkbox/lib/checkbox.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | input: function (e) {
5 | console.log('checkbox emitted input', this.ariaLabel);
6 |
7 | // style :user-invalid or :user-valid
8 |
9 | events.dispatchComponentEvent.call(this, 'input', { value: this.value }, e);
10 | },
11 | change: function (e) {
12 | console.log('checkbox emitted change', this.ariaLabel);
13 |
14 | // style :user-invalid or :user-valid
15 |
16 | events.dispatchComponentEvent.call(this, 'change', { value: this.value }, e);
17 | },
18 | focus: function (e) {
19 | console.log('checkbox emitted focus', this.ariaLabel);
20 |
21 | events.dispatchComponentEvent.call(this, 'focus', { value: this.value }, e);
22 | },
23 | blur: function (e) {
24 | console.log('checkbox emitted blur', this.ariaLabel);
25 |
26 | events.dispatchComponentEvent.call(this, 'blur', { value: this.value }, e);
27 | },
28 | invalid: function (e) {
29 | console.log('checkbox emitted invalid', this.ariaLabel);
30 |
31 | // style :user-invalid or :user-valid
32 |
33 | events.dispatchComponentEvent.call(this, 'invalid', { value: this.value }, e);
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/packages/components/textarea/lib/textarea.events.js:
--------------------------------------------------------------------------------
1 | import { events } from '@wcag-ui/core';
2 |
3 | export default {
4 | input: function (e) {
5 | console.log('textarea emitted input', this.ariaLabel);
6 |
7 | // style :user-invalid or :user-valid
8 |
9 | events.dispatchComponentEvent.call(this, 'input', { value: this.value }, e);
10 | },
11 | change: function (e) {
12 | console.log('textarea emitted change', this.ariaLabel);
13 |
14 | // style :user-invalid or :user-valid
15 |
16 | events.dispatchComponentEvent.call(this, 'change', { value: this.value }, e);
17 | },
18 | focus: function (e) {
19 | console.log('textarea emitted focus', this.ariaLabel);
20 |
21 | events.dispatchComponentEvent.call(this, 'focus', { value: this.value }, e);
22 | },
23 | blur: function (e) {
24 | console.log('textarea emitted blur', this.ariaLabel);
25 |
26 | events.dispatchComponentEvent.call(this, 'blur', { value: this.value }, e);
27 | },
28 | invalid: function (e) {
29 | console.log('textarea emitted invalid', this.ariaLabel);
30 |
31 | // style :user-invalid or :user-valid
32 |
33 | events.dispatchComponentEvent.call(this, 'invalid', { value: this.value }, e);
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/packages/js/core/lib/events/_dispatchCustomEvent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dispatches a namespaced CustomEvent.
3 | *
4 | * Event name format: `${eventNamespace}.${eventName}` (bubbling, cancelable).
5 | *
6 | * @param {string} eventNamespace - Namespace (e.g., component name/tag).
7 | * @param {string} eventName - Event name (e.g., "open", "close").
8 | * @param {object} [detail={}] - Data to pass in `event.detail`.
9 | * @param {Event} [originalEvent=undefined] - Original DOM event to include in detail.
10 | * @param {EventTarget} [dispatcher=undefined] - Optional custom dispatcher (defaults to `this` or `self`).
11 | * @returns {void}
12 | */
13 | export const dispatchCustomEvent = function (
14 | eventNamespace,
15 | eventName,
16 | detail = {},
17 | originalEvent = undefined,
18 | dispatcher = undefined
19 | ) {
20 | dispatcher = dispatcher ?? this ?? self;
21 |
22 | const event = new CustomEvent(`${eventNamespace}.${eventName}`, {
23 | bubbles: true,
24 | cancelable: true,
25 | detail: {
26 | ...detail,
27 | ...(originalEvent && { originalEvent }),
28 | },
29 | });
30 |
31 | // Optional: instrument here if you need debug logs for emitted events.
32 |
33 | dispatcher.dispatchEvent(event);
34 | };
35 |
--------------------------------------------------------------------------------
/src/styles/layout/_header.css:
--------------------------------------------------------------------------------
1 | body > header {
2 | --wcag-t--font-size: var(--docs--header--font-size);
3 |
4 | grid-area: header;
5 |
6 | position: sticky;
7 | inset-block-start: 0;
8 | z-index: 3;
9 |
10 | display: flex;
11 | place-content: space-between;
12 | place-items: center;
13 | gap: 2rem;
14 | flex-flow: column nowrap;
15 |
16 | color: var(--docs--header--color);
17 | background-color: var(--docs--header--background-color);
18 | box-shadow: var(--docs--header--box-shadow);
19 |
20 | min-block-size: var(--docs--header--min-height);
21 | padding-inline: var(--docs--header--padding-inline);
22 | padding-block: 0 1.5rem;
23 |
24 | @media screen and (width >= 1024px) {
25 | flex-flow: row nowrap;
26 |
27 | padding-block: 0;
28 | }
29 |
30 | a {
31 | --wcag-t--text-decoration: none;
32 |
33 | &[logo] {
34 | --wcag-t--font-size: var(--docs--header--logo--height);
35 |
36 | display: inline-block;
37 | inline-size: 14.6rem;
38 | block-size: 6.5rem;
39 |
40 | padding-inline: 0.5rem;
41 | border-radius: var(--docs--header--menu--border-radius);
42 |
43 | color: var(--docs--header--logo--color);
44 | }
45 | }
46 |
47 | i {
48 | display: inline-block;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/scripts/unpublish.mjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import { execSync } from 'node:child_process';
3 | import fs from 'node:fs';
4 | import path from 'node:path';
5 | import { collectPackageJson } from './_package-utils.mjs';
6 |
7 | const root = process.cwd();
8 |
9 | /**
10 | * Unpublishes all local packages found in the packages directory.
11 | * Uses npm unpublish with --force for each package and logs the result.
12 | *
13 | * @example Unpublish all local packages
14 | * // Run this script from the project root
15 | */
16 | const packageJsonPaths = collectPackageJson(path.join(root, 'packages'));
17 |
18 | for (const file of packageJsonPaths) {
19 | const { name, version } = JSON.parse(fs.readFileSync(file, 'utf8'));
20 | try {
21 | console.log(`\u23F4 Unpublish ${name}@${version}`);
22 | execSync(`npm unpublish ${name}@${version} --force`, { stdio: 'inherit' });
23 | } catch (err) {
24 | console.error(`⚠️ Impossible to unpublish ${name}@${version}:`, err.message);
25 | }
26 | }
27 |
28 | // Optionally, remove associated git tag for the version just unpublished:
29 | // const tag = `v${JSON.parse(fs.readFileSync(packageJsonPaths[0], 'utf8')).version}`;
30 | // execSync(`git tag -d ${tag}`);
31 | // execSync(`git push origin :refs/tags/${tag}`);
32 |
--------------------------------------------------------------------------------
/packages/js/dom/lib/_insertHTML.js:
--------------------------------------------------------------------------------
1 | import { sanitizeHTML } from './_sanitizeHTML';
2 |
3 | /**
4 | * Inserts a sanitized HTML code in a certain position relative to another element.
5 | *
6 | * @param {string} html - the HTML code to be inserted in the targetElement
7 | * @param {HTMLElement} targetElement - the target element where the insertion will happen
8 | * @param {TInsertPositions} position - the position where to insert the element (before='beforebegin', prepend='afterbegin', append='beforeend', after='afterend')
9 | * @param {boolean} [emptyTarget=false] - specifies if the targetElement should be emptied before insertion
10 | * @return {NodeList} The inserted elements NodeList
11 | */
12 | export const insertHTML = (html, targetElement, position, emptyTarget = false) => {
13 | emptyTarget && (targetElement.innerHTML = '');
14 |
15 | const sanitizedDOM = sanitizeHTML(html, true);
16 |
17 | const fragment = document.createDocumentFragment();
18 | fragment.append(...sanitizedDOM);
19 |
20 | // position === 'beforebegin' && target.before(fragment);
21 | // position === 'afterbegin' && target.prepend(fragment);
22 | // position === 'beforeend' && target.append(fragment);
23 | // position === 'afterend' && target.after(fragment);
24 | targetElement[position ?? 'append'](fragment);
25 |
26 | return sanitizedDOM;
27 | };
28 |
--------------------------------------------------------------------------------
/src/styles/layout/_core.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: "InterVariable", sans-serif;
3 | font-optical-sizing: auto;
4 | font-weight: var(--wcag-t--variant--weight);
5 | font-variation-settings:
6 | "opsz" var(--wcag-t--variant--opsz),
7 | "wght" var(--wcag-t--variant--weight);
8 | }
9 |
10 | html {
11 | inline-size: 100vw;
12 | min-block-size: 100vh;
13 | }
14 |
15 | body {
16 | display: grid;
17 | grid-template-columns: var(--docs--aside--width) 1fr var(--docs--scroll-spy--width);
18 | grid-template-rows: auto 1fr auto;
19 | grid-template-areas:
20 | "header header header"
21 | "aside main -"
22 | "footer footer footer";
23 |
24 | background-color: var(--docs--background-color);
25 | background-image: url("../../assets/background-image.svg");
26 | background-size: 100vw auto;
27 | background-repeat: repeat-y;
28 |
29 | inline-size: 100vw;
30 | min-block-size: 100vh;
31 | }
32 |
33 | @media screen and (width >= 1366px) {
34 | body {
35 | grid-template-rows: var(--docs--header--min-height) 1fr var(--docs--footer--min-height);
36 |
37 | grid-template-areas:
38 | "header header header"
39 | "aside main scroll-spy"
40 | "footer footer footer";
41 | }
42 | }
43 |
44 | a {
45 | --wcag-f--outline-offset: calc(var(--wcag-f--outline-width) * 2);
46 |
47 | border-radius: 0.4rem;
48 | }
49 |
--------------------------------------------------------------------------------
/src/_layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | wcagUI - {{title}}
8 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/packages/components/button/lib/button.js:
--------------------------------------------------------------------------------
1 | import { componentDecorator } from '@wcag-ui/core';
2 |
3 | import attributes from './button.attributes';
4 | import events from './button.events';
5 |
6 | /**
7 | * wcagUI Button class
8 | *
9 | * @export
10 | * @class Button
11 | * @extends {HTMLButtonElement}
12 | */
13 | export class Button extends HTMLButtonElement {
14 | static extendsElement = 'button';
15 | static attributes = attributes;
16 | static events = events;
17 |
18 | /**
19 | * static initialization block
20 | *
21 | * @static
22 | * @memberof Button
23 | */
24 | static {
25 | componentDecorator(this);
26 | }
27 |
28 | constructor() {
29 | super();
30 |
31 | this.#init();
32 | }
33 |
34 | #init() {
35 | !this.hasAttribute('type') && this.setAttribute('type', 'button');
36 | // !this.hasAttribute("role") && this.setAttribute("role", "button");
37 | }
38 | }
39 |
40 | //
48 | //
49 |
50 | // import '@wcag-ui/button';
51 | // import '@wcag-ui/button/button.css';
52 |
53 | // before: