Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/volto/news/8033.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Accessibility issues in form fields fixed. Announce errors via aria-live and expose required/invalid state on text inputs @Wagner3UB
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ exports[`Aliases > renders an aliases control component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -185,6 +189,10 @@ exports[`Aliases > renders an aliases control component 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ const FormFieldWrapper = ({
<>
{children}

{map(error, (message) => (
<Label key={message} basic color="red" className="form-error-label">
{message}
</Label>
))}
<div aria-live="polite" aria-atomic="true">
{map(error, (message) => (
<Label key={message} basic color="red" className="form-error-label">
{message}
</Label>
))}
</div>
</>
);

Expand Down
4 changes: 4 additions & 0 deletions packages/volto/src/components/manage/Widgets/TextWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const TextWidget = (props) => {
placeholder,
isDisabled,
focus,
required,
error,
} = props;

const ref = useRef();
Expand Down Expand Up @@ -49,6 +51,8 @@ const TextWidget = (props) => {
onClick={() => onClick()}
minLength={minLength || null}
maxLength={maxLength || null}
aria-required={required ? 'true' : undefined}
aria-invalid={error?.length > 0 ? 'true' : undefined}
/>
{icon && iconAction && (
<button className={`field-${id}-action-button`} onClick={iconAction}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ exports[`AlignWidget > renders with custom actions 1`] = `
</svg>
</label>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -306,6 +310,10 @@ exports[`AlignWidget > renders with default actions 1`] = `
</svg>
</label>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ exports[`No 'No value' option when default value is 0 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -320,6 +324,10 @@ exports[`renders an array widget component 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ exports[`ButtonsWidget > renders actions info provided via props 1`] = `
</svg>
</label>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -282,6 +286,10 @@ exports[`ButtonsWidget > renders string-based actions 1`] = `
</svg>
</label>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ exports[`renders a checkbox group widget component 1`] = `
</div>
<div
class="eight wide column"
/>
>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ exports[`CheckboxWidget > renders a checkbox widget component 1`] = `
</label>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -80,6 +84,10 @@ exports[`CheckboxWidget > renders a checkbox widget component checked 1`] = `
</label>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ exports[`datetime widget converts UTC date and adapts to local datetime 1`] = `
</svg>
</button>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -211,6 +215,10 @@ exports[`renders a datetime widget component 1`] = `
</svg>
</button>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ exports[`renders an email widget component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ exports[`IdWidget > renders an empty id widget component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -83,6 +87,10 @@ exports[`IdWidget > renders an id widget with a valid dot character 1`] = `
value="test-id"
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -128,6 +136,10 @@ exports[`IdWidget > renders an id widget with a valid value 1`] = `
value="test-id"
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -174,9 +186,14 @@ exports[`IdWidget > renders an id widget with an reserved name 1`] = `
/>
</div>
<div
class="ui red basic label form-error-label"
aria-atomic="true"
aria-live="polite"
>
This is a reserved name and can't be used
<div
class="ui red basic label form-error-label"
>
This is a reserved name and can't be used
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -224,9 +241,14 @@ exports[`IdWidget > renders an id widget with invalid characters 1`] = `
/>
</div>
<div
class="ui red basic label form-error-label"
aria-atomic="true"
aria-live="polite"
>
Only 7-bit bytes characters are allowed. Cannot contain uppercase letters, special characters: &lt;, &gt;, &, #, /, ?, or others that are illegal in URLs. Cannot start with: _, aq_, @@, ++. Cannot end with __. Cannot be: request,contributors, ., .., "". Cannot contain new lines.
<div
class="ui red basic label form-error-label"
>
Only 7-bit bytes characters are allowed. Cannot contain uppercase letters, special characters: &lt;, &gt;, &, #, /, ?, or others that are illegal in URLs. Cannot start with: _, aq_, @@, ++. Cannot end with __. Cannot be: request,contributors, ., .., "". Cannot contain new lines.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed this. Does the ampersand render to the screen, or does it need to be encoded?

Copy link
Copy Markdown
Contributor

@pnicolli pnicolli Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This good question got me curious and I checked, since this is a snapshot test result and should (theoretically) represent the result of rendering.
This is the actual string that is being render, the &lt; was converted while the & was not, so I think it's safe to assume this is fine, at least for the sake of this PR.

https://github.com/plone/volto/blob/main/packages/volto/src/components/manage/Widgets/IdWidget.jsx#L30
https://github.com/plone/volto/blob/main/packages/volto/locales/en/LC_MESSAGES/volto.po#L2675

</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ exports[`renders an image sizes widget component 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ exports[`renders a number widget component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ exports[`renders a objectBrowser widget component 1`] = `
</svg>
</button>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ exports[`renders an object list widget component 1`] = `
 Add Link
</button>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ exports[`renders a password widget component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ exports[`renders a radio group widget component 1`] = `
</div>
<div
class="eight wide column"
/>
>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ exports[`renders an array widget component 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ exports[`RegistryImageWidget > renders a file widget component with value 1`] =
</svg>
</button>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -146,6 +150,10 @@ exports[`RegistryImageWidget > renders an empty file widget component 1`] = `
<div
class="field-file-name"
/>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ exports[`renders a select widget component 1`] = `
</div>
</div>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ exports[`No 'No value' option when default value is 0 1`] = `
value="0"
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -304,6 +308,10 @@ exports[`renders a select widget component 1`] = `
value=""
/>
</div>
<div
aria-atomic="true"
aria-live="polite"
/>
</div>
</div>
</div>
Expand Down
Loading
Loading