Repository navigation
Releases: Accesserty/UI-Kit
Release list
v3.0.2
v3.0.2 — Screen reader fixes for forms
This patch changes how form controls report their invalid state and documents what each form control exposes to assistive technology. Tags, attributes, events and styles are unchanged.
Fixed
- Safari with VoiceOver no longer announces empty required fields as "invalid data" as soon as a page loads.
au-input,au-textarea,au-checkbox,au-switchandau-radio-group(the group and every radio) now give their inner controlsaria-invalid="false"unless you setaria-invalidon the component, asau-file-uploadalready did. Setaria-invalid="true"when you show an error and remove it when the error is fixed. A failed browser-validated submit still announces the browser's validation message.
Documentation
llms.txthas a new section, "Accessibility presentation of form controls": the role, accessible-name source, forwarded attributes andfocus()target of each form control.llms.txtnow listsau-radio-group'srequired,aria-describedbyandaria-invalid, the accordion item's slots, and how to show an error message next to a field.- New demo:
demo/form-registration.html, a complete registration form with an error summary, inline errors, a success message and reset. It states what native HTML, UI Kit and your own code each handle, and includes a verification record (automated runs and Safari+VoiceOver results, known issues, untested environments).
Known issue
- The component host keeps the
aria-describedbyandaria-invalidyou set, so the host is also exposed with the same description. Safari with VoiceOver reads the description twice forau-textareaandau-checkbox.
Verification
- 490 unit tests passed.
- Documentation, build-output and toolchain contracts passed; SSR stream and framework fixtures passed.
- All Chrome browser runners passed, including the new
form-registrationrunner. - All 13 Safari WebDriver runners passed on macOS.
- Safari+VoiceOver behavior of the registration case was checked by driving VoiceOver with AppleScript.
v3.0.1
v3.0.1 — Toolchain refresh
This patch updates the development and build tools. Component APIs, styles, and accessibility behavior are unchanged.
Updated
- Aligned local development and CI on Node.js 26.12.1 and npm 11.
- Upgraded to Vite 8 and Open WC Testing 5.
- Updated Vue, React, Nuxt, Next.js, and browser-testing dependencies.
- Updated TypeScript to 6.0.3, retaining compiler API compatibility.
Build and testing
- Preserved ES2022 output, classic-script bundles, standalone component files, and framework integration entries.
- Added regression checks for toolchain consistency, version banners, and build output.
- Made the Dropdown demo test independent of external font loading.
- Rebuilt distribution files with the v3.0.1 version banner.
Verification
- 485 unit tests passed.
- 16 Chrome test groups passed.
- All 12 Firefox groups passed across the initial run and an isolated rerun after one browser-startup failure.
- All 12 Safari groups passed without retries.
- SSR, hydration, type, documentation, and build-contract checks passed.
These checks do not establish complete accessibility conformance or screen-reader compatibility. Remote CI results are separate from this local verification.
Known limitations
Upstream development-dependency advisories affecting braces and node-forge remain unresolved. These dependencies are not included in the distributed component bundles.
Upgrading
No application-code changes are required when upgrading from v3.0.0. Replace the distribution files you use, keeping related framework integration files together.
Plain HTML usage still requires no Node.js installation, npm packages, or build step. Components retain zero runtime package dependencies.
v3.0.0
Accesserty UI Kit 3.0.0
3.0.0 is a major release. Vue, Nuxt, React and Next.js can now bind the form
components the way they bind native fields, and accordion, tabs and breadcrumbs
can render their Shadow DOM on the server. The component tags, attributes and
properties are unchanged, but custom events are renamed and a few other
details change. Read "What breaks" and "How to upgrade" below before you
replace your copy of the kit.
Plain HTML pages keep working the same way: copy a file, add a <script> tag,
use the <au-*> elements.
Highlights
v-modelin Vue and Nuxt onau-input,au-textarea,au-checkbox,
au-switch,au-radio-group,au-ratingandau-file-upload, following
Vue's own rules for native fields. A group of checkboxes can share one array
orSet,true-value/false-valuework,type="number"inputs give
numbers, and<au-radio :value="2">gives2. Server rendering supports it too.- A Nuxt module. Add one line to
modulesin place of a client plugin, the
isCustomElementsetting and<ClientOnly>wrappers. - React components for React 19 and Next.js:
AuInput,AuTextarea,
AuCheckbox,AuSwitch,AuRadioGroup,AuRatingandAuFileUpload. They
takevalue/checked,defaultValue/defaultChecked,onChangeand a
ref to the element.e.targetbehaves like a native field, withvalue,
checked,valueAsNumberandvalueAsDate. - Server rendering of Shadow DOM (Declarative Shadow DOM) for accordion,
tabs and breadcrumbs. They have their final look and layout before any
JavaScript runs, so the page doesn't jump when the script loads or fails.- Nuxt: on by default.
- Self-hosted Next.js: one wrapper,
withDeclarativeShadow. It doesn't work on
Vercel. - Any other Node server:
injectDeclarativeShadow.
- Native form API on every form component:
setCustomValidity()and
form, alongsidevalidity,checkValidity()andreportValidity().
au-inputalso getsvalueAsNumberandvalueAsDate. Pressing Enter in an
au-inputstill does not submit the form, on purpose. - Single-component files in
dist/components/. All 15 components are there,
each as a self-contained file plus a minified copy (tabs.min.js: 13 KB
instead of 21 KB). - TypeScript declarations.
accesserty-ui-kit.d.tstypes every element, for
exampledocument.querySelector('au-tabs').selectedIndex. The React file adds
everyau-*tag to JSX with typed event details. Vue typesv-modelin
templates. - One disabled look. Every component and native button dims to opacity 0.6,
which keeps dark text at about 5:1 on white. Each component has a
--au-…-disabled-opacityvariable to change it.
What breaks
| 2.0.10 | 3.0.0 | What to do | |
|---|---|---|---|
au-tabs event |
tab-change |
au-tab-change |
Rename the listener |
au-carousel event |
slide-change |
au-slide-change |
Rename the listener |
au-pagination events |
page-change, page-size-change |
au-page-change, au-page-size-change |
Rename the listeners |
au-dropdown-item event |
selected |
au-select |
Rename the listener |
au-file-upload event |
remove-file |
au-remove-file |
Rename the listener |
Cascade layer of au-style.css |
components |
accesserty |
Rename it in your @layer order, if you declared one |
| Copying one component | src/components/<name>.js |
dist/components/<name>.js or <name>.min.js |
Copy from dist/components/; the files in src/ are ES modules now |
au-accordion-item with open in the markup |
Sends au-toggle when the script loads |
Sends nothing, because nothing changed | Read item.open for the initial state |
| Ids inside accordion and tabs Shadow DOM | Random | Fixed (title, region, tab-1…) |
Only matters if your code read them |
The old event names are no longer sent; there is no transition period. These
events keep their names: au-toggle, the native change and input on form
components, and au-tree's change.
In React, ontab-change becomes onau-tab-change. In Vue, @tab-change
becomes @au-tab-change.
Compared with 2.0.10
All fixes from 2.0.8, 2.0.9 and 2.0.10 are included.
| 2.0.10 | 3.0.0 | |
|---|---|---|
| Vue / Nuxt forms | :value + @input, :checked + @change |
v-model (the old bindings still work) |
| Nuxt setup | Client plugin, isCustomElement, <ClientOnly> |
One module |
| React / Next forms | <au-input> tags with on… props (React 19), or a ref and addEventListener (React 18) |
AuInput… with value / onChange (React 19); the tags still work |
| Server-rendered Shadow DOM | — | accordion, tabs, breadcrumbs |
setCustomValidity(), form |
— | All 7 form components |
valueAsNumber, valueAsDate on au-input |
— | Yes |
Validity API on au-rating, au-file-upload |
Missing | Same as the other form components |
| Disabled opacity | 0.35–0.65; au-input had no disabled look |
0.6 everywhere, one variable per component |
| Event names | Mixed | All start with au- (except tree's change) |
| Single-component files | src/components/*.js |
dist/components/*.js and *.min.js |
| TypeScript | — | Elements, events, JSX tags, Vue v-model |
accesserty-ui-kit.js / .min.js |
260 KB / 197 KB | 252 KB / 190 KB |
Integration files in dist/ |
— | Vue, React, Nuxt, SSR (ES modules, each with .d.ts) |
package.json exports |
., ./min |
Also ./vue, ./react, ./nuxt, ./ssr, each with types |
| Unit tests | 456 | 485 |
| Browser suites (Chrome, Firefox, Safari) | 10 | 12 (adds server rendering and single files) |
| Framework checks | Next, Nuxt | Also Nuxt v-model, Vue SPA, Next React, server-rendered Shadow DOM, TypeScript |
How to upgrade
The full guide is in UPGRADING.md.
-
Replace the kit. Copy the whole new
dist/folder over your copy. The
integration files import each other by relative path. If you copied single
components, copy them fromdist/components/instead ofsrc/components/. -
Rename event listeners using the table above. Searching your code for
tab-change,slide-change,page-change,page-size-change,selected
andremove-filefinds them. -
CSS: if you use
au-style.css, copy the newsrc/css/folder. Rename
anycomponentslayer that you ordered for the kit toaccesserty:@layer base, accesserty, components, utilities;
-
Vue: use the kit's
isCustomElementinstead of
tag => tag.startsWith('au-'), and install the plugin:import { AccessertyVue, isCustomElement } from './vendor/accesserty/accesserty-ui-kit-vue.js' createApp(App).use(AccessertyVue).mount('#app') // vite.config.js: vue({ template: { compilerOptions: { isCustomElement } } })
Your
:value/@inputbindings keep working. Switch tov-modelwhen you
like. -
Nuxt: remove your client plugin, the
isCustomElementsetting and any
<ClientOnly>you added for the kit, then add the module:export default defineNuxtConfig({ modules: ['./vendor/accesserty/accesserty-ui-kit-nuxt.js'] })
-
React / Next.js (optional): switch form fields to the React components,
and calldefineElements()once in a client effect:import { AuInput, defineElements } from './vendor/accesserty/accesserty-ui-kit-react.js' useEffect(() => { defineElements() }, []) <AuInput label="Email" value={email} onChange={e => setEmail(e.target.value)} />
For server-rendered accordion, tabs and breadcrumbs, run a custom server
withwithDeclarativeShadow. -
Check disabled fields if your design depends on their old opacity. Set
--au-<component>-disabled-opacity(--au-btn-disabled-opacityfor native
buttons and pagination) to keep the previous value.
Support for 2.x
2.x gets bug fixes only. New features land in 3.x.
v2.0.10
Accesserty UI Kit v2.0.10
This release covers 2.0.8, 2.0.9 and 2.0.10 (the previous GitHub release was
v2.0.7). No API changes: replace accesserty-ui-kit.min.js (or
accesserty-ui-kit.js) and, if you use it, the src/css/ stylesheets with the
new files. Please read Behavior changes if your pages use right-to-left
text or count carousel events.
Fixed
- A paused smooth scroll no longer makes
<au-carousel>report extra
slides. The carousel reads the current slide once scrolling settles. On a
busy device, a smooth scroll could pause long enough to look settled, so the
carousel reported the slide it was passing and then the real one. That sent
two extraslide-changeevents, and screen readers announced both slides.
The carousel now remembers where its own scroll is heading and reports
nothing until it gets there. Pointer, wheel or touch input hands control back
to the user, and after one second the normal reading resumes either way. - An untitled carousel slide is announced once. A slide without a
data-titleor heading was announced as "Item 2 of 3, item 2 of 3". It is
now "Item 2 of 3", which matches its dot. - Left and right arrows in
<au-radio-group>follow the reading
direction. In right-to-left text, the Right Arrow moved to the option on
the left. Left and right now point the way they move, as in<au-tabs>and
<au-rating>, and every arrow still wraps around. accesserty-ui-kit.jsno longer adds globals to your page. Since 2.0.0
the bundle defined__defProp,__defNormalPropand__publicFieldon
window. It no longer does, and the file is about 5 KB smaller. Browser
support does not change: the components already needed the same JavaScript
level.
Documentation and demos
- These CSS variables already worked, and the demo pages now list them: the
dropdown arrow icons (--au-dropdown-arrow-down-icon,
--au-dropdown-arrow-up-icon), the arrow icons that select and dropdown
share (--au-control-arrow-down-icon,--au-control-arrow-up-icon),
--au-file-upload-delete-active-border-color,
--au-file-upload-delete-tap-highlight-color,
--au-textarea-container-padding-horizontal,
--au-tree-node-checkbox-input-indeterminate-symbol, and pagination's
--au-btn-current-bg,--au-btn-current-text-color,
--au-btn-current-border-colorand--au-pagination-focus-color. - Font-family variables now state their fallback as
inherit. That is what an
unset variable already did, so text looks the same. - On narrow screens, demo tables scroll inside their own focusable, named area,
and long code wraps. No demo page scrolls sideways at 320px any more.
Duplicate landmark names and an empty table header in the demos are fixed.
Behavior changes
- Right-to-left radio groups: the Right Arrow now selects the previous
option and the Left Arrow the next one. Up and down are unchanged. - Carousel events: a smooth scroll that pauses no longer sends extra
slide-changeevents. If you counted events, you may now receive fewer. - Untitled carousel slides: the live region text changed from
"Item 2 of 3, item 2 of 3" to "Item 2 of 3". If you set
data-live-template, slides with a title still use it.
v2.0.7
Accesserty UI Kit v2.0.7
A bug fix for <au-carousel>. No API changes: replace
accesserty-ui-kit.min.js (or accesserty-ui-kit.js) with the new file.
Fixed
- A carousel told to start on a later slide now shows that slide.
If your page setscurrentbefore the kit's script loads, the carousel
opens on that slide. Before, the carousel moved there with a smooth scroll,
which Safari sometimes skipped during page load. The dots and screen readers
then reported the chosen slide while the first slide stayed in view. The
starting slide is now set without animation, because it is where the page
starts, not a move by the user. Previous/next buttons, dots, arrow keys and
swipes still scroll smoothly. Reduced-motion settings still turn scrolling
animation off.
v2.0.6
Accesserty UI Kit v2.0.6
This release covers 2.0.4, 2.0.5 and 2.0.6 (the previous GitHub release was
v2.0.3). No breaking changes to component APIs: replace
accesserty-ui-kit.min.js (or accesserty-ui-kit.js) and au-style.css with
the new files. Please read Behavior changes if you override the popover
animation or style the accordion's collapsed region.
Added
- Find-in-page and links now open collapsed
<au-accordion-item>panels.
Where the browser supportshidden="until-found", collapsed panels stay
searchable: Ctrl+F / ⌘F, text-fragment links (#:~:text=) and#idlinks
into collapsed slotted content open the item, including every enclosing item
of a nested accordion. Opening emits the usualau-toggleevent, so framework
bindings andexclusivegroups stay in sync. Until revealed, collapsed
content stays out of the Tab order and the accessibility tree. Browsers
without support keep collapsed panelshiddenandinert, as before. - Find-in-page expands collapsed
<au-tree>branches. A match in a
collapsed node expands every ancestor branch without moving focus. Collapsed
nodes stay out of the Tab order, arrow-key order and accessibility tree.
Node labels live in Shadow DOM, which Safari's text-fragment links do not
search; Chrome's and Firefox's do.
Fixed
<au-rating>with Vuev-modelno longer reverts the user's choice.
The inner radio's nativeinputevent reached host listeners whilevalue
still held the previous rating, sov-modelread the old value and wrote it
back. The value now updates first;changestill carriesdetail.value.- Popovers fade in, and keep their layout while fading out. The shared
stylesheet's fade-in never ran, and the fade-out forceddisplay: blockon
closing popovers for 0.5s, breaking grid or flex layouts. Popovers now fade
both ways using CSS transitions only. A closing popover is already treated as
closed: it takes no clicks or focus and is not announced. Reduced-motion
preferences still remove the fade.
Behavior changes
@keyframes popover-fade-outis removed from the shared stylesheet. If your
CSS referenced it, use the transition-based fade (seeau-style.css).- In supporting browsers, a collapsed accordion region and a collapsed tree
group now carryhidden="until-found"instead ofhidden+inert.
Selectors such as[hidden]still match; code that checksregion.inert
should not rely on it.
Removed
- Angular is no longer a tested or documented integration. The Angular
fixtures and Angular guidance are removed. The components are unchanged
standard custom elements, so they still work in any framework that renders
custom elements. Vue/Nuxt and React/Next remain the tested integrations.
Documentation
- New README section, "Reserving space before registration": copyable
:not(:defined)CSS that reserves the registered height ofau-input,
au-textarea,au-file-uploadandau-tree, to avoid layout shift while
the script loads. Text lines are reserved inlh, so the reservation holds
in any font, including Traditional Chinese ones. On the demo pages, under
simulated Slow 4G, cumulative layout shift fell from 0.296 to 0.023 (input)
and 0.318 to 0.010 (form). - Rebuilt popover and dialog demos:
- Popover: auto, manual and hint types; Invoker Commands;
interestfor
tooltips; anchor positioning with fallbacks. - Dialog:
closedby;request-closewith an unsaved-changes prompt; nested
and non-modal dialogs.
- Popover: auto, manual and hint types; Invoker Commands;
Verified
- Chrome: 453 unit tests, browser checks, and SSR in Next and Nuxt
- Firefox: WebDriver browser checks, including the accordion and tree reveal
- Safari 27: WebDriver browser checks for accordion, tree and rating
- Find-in-page checked by hand in Chrome, Firefox and Safari
These checks do not establish screen-reader speech or full WCAG conformance.
Verify your assembled pages, including with assistive technologies.
Full changelog: v2.0.3...v2.0.6
v2.0.3
Accesserty UI Kit v2.0.3
A patch release with one accessibility fix. No breaking changes: replace
accesserty-ui-kit.min.js (or accesserty-ui-kit.js) with the new file.
Fixed
<au-accordion>no longer announces an instruction that does not apply.
Every accordion carried the visually hidden text "Only one section may be
expanded at a time.", even without theexclusiveattribute. Screen readers
read it as page content, so users heard about a restriction that did not
exist. The instruction now appears only whileexclusiveis set.- When
exclusiveis switched on at runtime, the instruction uses the current
data-text-exclusive-hintvalue, including any change made while
exclusivewas off. Switching it off removes the instruction again.
Documentation
- The README links the official overview and the online playground.
Verified
- Chrome: 447 unit tests, browser checks, SSR (Next, Nuxt, Angular) and an
Angular AOT consumer build - Firefox: WebDriver browser checks on CI
- Safari: WebDriver browser checks before tagging
These checks do not establish screen-reader speech or full WCAG conformance.
Verify your assembled pages, including with assistive technologies.
Full changelog: v2.0.2...v2.0.3
v2.0.2
v2.0.1
au-input copied every host attribute onto its inner input at upgrade, so
hidden, inert, style and inline handlers stayed on the field after the host
changed and handlers ran twice. It now forwards only its documented
attributes. Below 768px the field wraps prefix/affix instead of shrinking to
32px, and colour inputs keep a usable swatch instead of 6px.
au-file-upload's default trigger drew its focus outline with the system
Highlight colour outside forced-colors mode (1.49:1 in Chrome); it now uses
a 7.6:1 default with --au-file-upload-trigger-focus-outline-* variables.
au-breadcrumbs lost its focus indicator in forced-colors mode because the
override was outranked by the nested outline: none.
The accordion, card, carousel, file-upload and breadcrumbs-html browser
checks now run in both CI configurations; breadcrumbs-html accepts a
browser argument, and file-upload subscribes to file choosers early to
avoid a Playwright race. Demo themes meet their own contrast guidance.
The bundle banner no longer embeds the build date, so rebuilds are
reproducible; package.json is private since the kit is not distributed
through npm. Docs require Node 22 and note file-upload's msg- prefix.