-
Notifications
You must be signed in to change notification settings - Fork 62
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
a11y support for tri-state #124
Comments
We've had an in depth discussion about this on this thread as to why this shouldn't be a property of the checkbox, but a separate element in itself: #33 The feature request for a checkable node element is here: PolymerElements/paper-elements#24 |
Re-opening, since this is an a11y issue, not about the tri-state UI. |
I don't think there's any mandate that checkboxes support a mixed state. In fact, there's explicit mention of a dual-state checkbox in the WAI-ARIA Authoring Practices document. That being said, I don't understand the opposition to adding a mixed state to paper-checkbox. There might not be a mixed state for checkboxes in the current Material Design spec but are we really going to land that far off if we add one ourselves? It's a rectangle. |
Any chance of getting work towards this in the near future? If there's a design plan I might be able to get some time to contribute a start on it. |
Here some hints, based on paper-checkbox (1.3.0, not last but...) (copy it to your component and make these changes): NOTE: I use this element as a selector not as a checkbox input, so I don't need the invalid property, in fact, I only use it in table headers to change context toolbar for selected rows (delete selected row for example). That being said, the invalid property is ignored. @notwaldorf maybe this can help you ;)... Modify aria-checked hostAttribute to be a string instead a boolean and add a property called checked : hostAttributes: {
role: 'checkbox',
'aria-checked': 'false',
tabindex: 0
},
...
properties {
...
/**
* Gets or sets the state, `true` is checked, `false` is unchecked, `mixed` for partially checked.
*/
checked: {
type: String,
value: 'false',
reflectToAttribute: true,
notify: true,
observer: '_checkedChanged'
}
} Add _checkedChanged method and change _computeCheckboxClass (REMOVE invalid parameter). Also override _activeChanged and _buttonStateChanged methods: _activeChanged: function(active, ariaActiveAttribute) {
this._changedButtonState();
},
/**
* Synchronizes the element's `active` and `checked` state.
*/
_buttonStateChanged: function() {
},
_computeCheckboxClass: function (checked) {
var className = null;
if (checked === 'true') {
className = 'checked';
} else if (checked === 'mixed') {
className = 'mixed';
}
return className;
},
/**
* Fire `iron-change` when the checked state changes.
*/
_checkedChanged: function() {
this.active = this.checked === 'true' || this.checked === 'mixed';
if (this.checked == 'true') {
this.setAttribute(this.ariaActiveAttribute, 'true');
} else if (this.checked == 'mixed') {
this.setAttribute(this.ariaActiveAttribute, 'mixed');
} else {
this.removeAttribute(this.ariaActiveAttribute);
}
if (this.hasRipple()) {
if (this.checked === 'true' || this.checked === 'mixed') {
this._ripple.setAttribute('checked', '');
} else {
this._ripple.removeAttribute('checked');
}
}
this.fire('iron-change');
}, Now component styles: OLD CODE: #checkbox.checked #checkmark {
-webkit-animation: checkmark-expand 140ms ease-out forwards;
animation: checkmark-expand 140ms ease-out forwards;
}
#checkmark {
position: absolute;
width: 36%;
height: 70%;
border-style: solid;
border-top: none;
border-left: none;
border-right-width: calc(2/15 * var(--calculated-paper-checkbox-size));
border-bottom-width: calc(2/15 * var(--calculated-paper-checkbox-size));
border-color: var(--paper-checkbox-checkmark-color, white);
-webkit-transform-origin: 97% 86%;
transform-origin: 97% 86%;
box-sizing: content-box; /* protect against page-level box-sizing */
} NEW CODE: :host(:not([aria-checked=mixed])) #checkbox.checked #checkmark {
-webkit-animation: checkmark-expand 140ms ease-out forwards;
animation: checkmark-expand 140ms ease-out forwards;
}
:host(:not([aria-checked=mixed])) #checkmark {
position: absolute;
width: 36%;
height: 70%;
border-style: solid;
border-top: none;
border-left: none;
border-right-width: calc(2 / 15 * var(--calculated-paper-checkbox-size));
border-bottom-width: calc(2 / 15 * var(--calculated-paper-checkbox-size));
border-color: var(--paper-checkbox-checkmark-color, white);
-webkit-transform-origin: 97% 86%;
transform-origin: 97% 86%;
box-sizing: content-box; /* protect against page-level box-sizing */
} Add these new styles for mixed box: :host([aria-checked=mixed]) #checkmark {
border-bottom: 2px solid var(--primary-text-color);
width: 60%;
height: 45%;
margin-left: 3px;
-webkit-animation: mixed-expand 140ms ease-out forwards;
animation: mixed-expand 140ms ease-out forwards;
}
@-webkit-keyframes mixed-expand {
0% {
-webkit-transform: scale(0, 0);
}
100% {
-webkit-transform: scale(1, 1);
}
}
@keyframes mixed-expand {
0% {
transform: scale(0, 1);
}
100% {
transform: scale(1, 1);
}
} And finally adjust html, comment invalid arg in _computeCheckboxClass call: <div id="checkboxContainer">
<div id="checkbox" class$="[[_computeCheckboxClass(checked/*, invalid*/)]]">
<div id="checkmark" class$="[[_computeCheckmarkClass(checked)]]"></div>
</div>
</div> |
+1 for a tri-state checkbox. In our case of legal questions there must be a specific indication of yes or no so there is a case for an unanswered state. |
I rescind aspects of my opinion on #33 that say that this should not be implemented, seeing as it is part of WCAG. However, I still feel that, following good UX principles, a tri-state checkbox is not the best choice for most applications. I would suggest, @MMJM, using a dropdown with something along the lines of "Unanswered," "Yes," and "No," because it would be much more explicit to the user, and would make exactly what they're answering much clearer. With a tri-state checkbox, the third state, while natural in the context of @userquin's example above, or in the context of a tree, I believe would be unnatural in the context of answering a question where there are really three "answers." @notwaldorf, when you say this is about a11y, but not about the UI, what do you mean exactly? If we were to implement a mixed state, that would have to reflect in the UI, no? |
+1 |
Provide tri-state support, not only true or false checked value, allow mixed:
https://www.w3.org/TR/wai-aria/roles#checkbox
https://www.w3.org/TR/wai-aria/#checkbox
The text was updated successfully, but these errors were encountered: