Skip to content

[OUDS] Add readonly on control item components #2951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: ouds/main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .bundlewatch.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"files": [
{
"path": "./dist/css/ouds-web-bootstrap.css",
"maxSize": "64.75 kB"
"maxSize": "65.0 kB"
},
{
"path": "./dist/css/ouds-web-bootstrap.min.css",
"maxSize": "61.5 kB"
"maxSize": "62.0 kB"
},
{
"path": "./dist/css/ouds-web-grid.css",
Expand Down
5 changes: 4 additions & 1 deletion build/vnu-jar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ execFile('java', ['-version'], (error, stdout, stderr) => {
// NOT RECOMMENDED, but it's still valid - we explain in the docs that it's not ideal,
// and offer more robust alternatives, but also need to show a less-than-ideal example
'An “aria-disabled” attribute whose value is “true” should not be specified on an “a” element that has an “href” attribute.',
'.*Consider using the “h1” element as a top-level heading only.*'
'.*Consider using the “h1” element as a top-level heading only.*',
// Poor aria-readonly handling see https://github.com/validator/validator/issues/1199
'Attribute “aria-readonly” not allowed on element “span” at this point.',
'Attribute “aria-readonly” not allowed on element “div” at this point.'
// End mod
].join('|')

Expand Down
56 changes: 46 additions & 10 deletions scss/forms/_control-item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
box-shadow: none;
}

&:has([aria-readonly="true"]),
[role="radiogroup"][aria-readonly="true"] & {
pointer-events: none;
}

// Handle disabled
&:has(input:disabled) {
pointer-events: none;
Expand Down Expand Up @@ -157,15 +162,19 @@
--#{$prefix}control-item-indicator-color: #{$ouds-color-action-selected};
}

&[type="checkbox"] {
&[type="checkbox"],
&[role="checkbox"][aria-readonly="true"] {
@include border-radius($form-check-input-border-radius);
}

&[type="radio"] {
// stylelint-disable selector-max-attribute
&[type="radio"],
[role="radiogroup"][aria-readonly="true"] &[role="radio"] {
@include border-radius($form-check-radio-border-radius);
}

&:indeterminate[type="checkbox"] {
&:indeterminate[type="checkbox"],
&[role="checkbox"][aria-readonly].control-item-readonly-indeterminate {
--#{$prefix}control-item-indicator-border-width: #{px-to-rem($ouds-checkbox-border-width-selected)};

&::before {
Expand All @@ -174,6 +183,22 @@
}
}

&[role="checkbox"][aria-checked="true"] {
--#{$prefix}control-item-indicator-border: #{$ouds-checkbox-border-width-selected};
&::before {
background-color: currentcolor;
mask-image: escape-svg($form-check-input-checked-bg-image);
}
}

[role="radiogroup"][aria-readonly="true"] &[role="radio"][aria-checked="true"] {
--#{$prefix}control-item-indicator-border: #{$ouds-radio-button-border-width-selected};
&::before {
background-color: currentcolor;
mask-image: escape-svg($form-check-radio-checked-bg-image);
}
}

&:checked {
&::before {
background-color: currentcolor;
Expand Down Expand Up @@ -204,11 +229,13 @@
}

&:focus-visible {
&[type="checkbox"] {
&[type="checkbox"],
&[role="checkbox"][aria-readonly] {
--#{$prefix}control-item-indicator-border-width: #{px-to-rem($ouds-checkbox-border-width-selected-focus)};
}

&[type="radio"] {
&[type="radio"],
[role="radiogroup"][aria-readonly="true"] &[role="radio"]{
--#{$prefix}control-item-indicator-border-width: #{px-to-rem($ouds-radio-button-border-width-selected-focus)};
}
}
Expand Down Expand Up @@ -259,10 +286,13 @@
}
}

&:disabled {
&:disabled,
&[aria-readonly][role="checkbox"],
[role="radiogroup"][aria-readonly="true"] &[role="radio"] {
--#{$prefix}control-item-indicator-color: #{$ouds-color-action-disabled};
pointer-events: none;
}
// stylelint-enable selector-max-attribute
}


Expand Down Expand Up @@ -301,7 +331,8 @@
border: 0;
@include border-radius($ouds-switch-border-radius, $ouds-switch-border-radius);

&[type="checkbox"]::before {
&[type="checkbox"]::before,
&[aria-readonly="true"]::before {
position: absolute;
top: 50%;
left: $ouds-switch-space-padding-inline-unselected;
Expand All @@ -327,11 +358,14 @@
width: $ouds-switch-size-width-cursor-unselected-pressed;
}

&:disabled {
&:disabled,
&[aria-readonly="true"] {
background-color: $ouds-color-action-disabled;
}

&:checked {
// stylelint-disable selector-max-attribute
&:checked,
&[aria-readonly="true"][aria-checked="true"] {
background-color: $ouds-switch-color-track-selected;

&::before {
Expand Down Expand Up @@ -370,13 +404,15 @@
width: $ouds-switch-size-width-cursor-selected-pressed;
}

&:disabled {
&:disabled,
&[aria-readonly="true"] {
background-color: $ouds-color-action-disabled;

&::after {
background-color: $ouds-color-action-disabled;
}
}
// stylelint-enable selector-max-attribute
}
}

Expand Down
31 changes: 30 additions & 1 deletion site/content/docs/0.4/forms/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,36 @@ Add the `disabled` attribute and the associated `<label>` are automatically styl
{{< /example >}}
{{< /bootstrap-compatibility >}}

<!-- TODO: Introduce Readonly ? -->
### Read only

To create a read only checkbox the input should be replaced by a `span` element with `role="checkbox"`, `aria-readonly` and `aria-disabled` attributes. The Checkbox will be accessible to keyboard navigation and assistive technologies thanks to `aria-labelledby` and `tabindex` but other interactions will be prevented.

{{< example class="bd-example-indeterminate" stackblitz_add_js="true" >}}
<div class="checkbox-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="checkbox" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="false" aria-labelledby="checkboxReadonlyLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="checkboxReadonlyLabel">Label</label>
</div>
</div>
<div class="checkbox-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="checkbox" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="true" aria-labelledby="checkboxReadonlyCheckedLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="checkboxReadonlyCheckedLabel">Label</label>
</div>
</div>
<div class="checkbox-item">
<div class="control-item-assets-container">
<span class="control-item-indicator control-item-readonly-indeterminate" role="checkbox" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="true" aria-labelledby="checkboxReadonlyIndeterminate"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="checkboxReadonlyIndeterminate">Label</label>
</div>
</div>
{{< /example >}}

### Invalid

Expand Down
27 changes: 25 additions & 2 deletions site/content/docs/0.4/forms/radio-button.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,30 @@ Add the `disabled` attribute and the associated `<label>` are automatically styl
{{< /example >}}
{{< /bootstrap-compatibility >}}

<!-- TODO: Introduce Readonly ? -->
### Read only

To create a read only radio button the input should be replaced by a `span` element with `role="radio"` and `aria-disabled` attributes. All the radio buttons in the group must be surrounded by a container with `role="radiogroup"` and `aria-readonly="true"` attributes. The radio button will be accessible to keyboard navigation and assistive technologies thanks to `aria-labelledby` and `tabindex` but other interactions will be prevented.

{{< example stackblitz_add_js="true" >}}
<div role="radiogroup" aria-readonly="true">
<div class="radio-button-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="radio" aria-disabled="true" tabindex="0" aria-checked="false" aria-labelledby="radioReadonlyLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="radioReadonlyLabel">Label</label>
</div>
</div>
<div class="radio-button-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="radio" aria-disabled="true" tabindex="0" aria-checked="true" aria-labelledby="radioReadonlyCheckedLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="radioReadonlyCheckedLabel">Label</label>
</div>
</div>
</div>
{{< /example >}}

### Invalid

Expand All @@ -302,7 +325,7 @@ Add the `disabled` attribute and the associated `<label>` are automatically styl
{{< /example >}}

{{< bootstrap-compatibility false >}}
{{< example class="bd-example-indeterminate" stackblitz_add_js="true" >}}
{{< example stackblitz_add_js="true" >}}
<div class="form-check">
<input class="form-check-input is-invalid" type="radio" value="" id="radioInvalidBootstrap">
<label class="form-check-label" for="radioInvalidBootstrap">
Expand Down
23 changes: 22 additions & 1 deletion site/content/docs/0.4/forms/switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,28 @@ Add the `disabled` attribute and the associated `<label>` are automatically styl
{{< /example >}}
{{< /bootstrap-compatibility >}}

<!-- TODO: Introduce Readonly ? -->
### Read only

To create a read only switches the input should be replaced by a `span` element with `role="switch"`, `aria-readonly` and `aria-disabled` attributes. The switch will be accessible to keyboard navigation and assistive technologies thanks to `aria-labelledby` and `tabindex` but other interactions will be prevented.

{{< example stackblitz_add_js="true" >}}
<div class="switch-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="switch" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="false" aria-labelledby="switchReadonlyLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="switchReadonlyLabel">Label</label>
</div>
</div>
<div class="switch-item">
<div class="control-item-assets-container">
<span class="control-item-indicator" role="switch" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="true" aria-labelledby="switchReadonlyCheckedLabel"></span>
</div>
<div class="control-item-text-container">
<label class="control-item-label" id="switchReadonlyCheckedLabel">Label</label>
</div>
</div>
{{< /example >}}

### Invalid

Expand Down