Existing components
MediaWiki community:
External libraries:
- Vuetify: Checkbox
- Buefy: Checkbox, CheckboxRadioMixin
Wikimedia Design Style Guide links:
Potential implementations
Indeterminate state
According to the design style guide, Checkboxes can have a third visual state, indeterminate, which usually represents a partially on state.
Existing implementations:
- OOUI: whether or not a checkbox is selected is stored separately from whether or not it is indeterminate, and a change in one of these attributes results in a change in the other (e.g. if you set selected to something, indeterminate will be set to false)
- Vuetify: similar, active/indeterminate state are stored separately but interact as described above
- Buefy: indeterminate prop informs the corresponding attributes on the input element, and an attribute selector is used to add the special styles for this state. Indeterminate doesn't interact with the value at all.
Ensure, that screenreaders expose indeterminate state appropriately with mixed. Equal output as through aria-checked="mixed".
How should input groups be handled?
There are a few things to think about:
- How are data and events handled?
- How are field elements like field-level labels, required indicators, and validation error messages included?
- If using a group component, how are child components added (via data passed in as a prop or sub-components passed in as a slot)?
Existing implementations:
- Wikit and Termbox have standalone Checkbox components
- MediaSearch and Buefy use standalone components and rely on the developer using v-model to handle data (a single value for a single checkbox and an array for a group of checkboxes). The developer can use v-for to generate multiple input components.
- Vuetify has a standalone Checkbox component
How should the custom-styled input be built?
Existing implementations:
- Wikit and termbox: the label has a styled ::before pseudo-element
- MediaSearch, ContentTranslation, and Buefy: a separate <span> is styled (similar to OOUI)
- Vuetify: a separate <div> is styled
How should the input-level label be handled?
Connecting input and label:
- Wikit, termbox, Wikibase vuejs components, ContentTranslation: separate label with for attribute set to input's unique ID
- MediaSearch and Buefy: label element wraps input
Passing label into input component:
- Wikit, termbox, Wikibase vuejs components: named slot (also includes slot for description)
- ContentTranslation, Vuetify: string prop
- MediaSearch, Buefy: main slot