Skip to content
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

fix(va-radio): incorrect rendering and accessibility improvement #3586

Merged
merged 4 commits into from
Jul 8, 2023
Merged
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
6 changes: 4 additions & 2 deletions packages/docs/modules/vuestic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ export default defineNuxtModule<VuesticOptions>({
},

setup (options, nuxt) {
// Fix CSS variables made by v-bind in component: they're not rendered in cjs (SSG).
addVitePlugin(componentVBindFix({ sourcemap: false }))
if (!nuxt.options.dev) {
// Fix CSS variables made by v-bind in component: they're not rendered in cjs (SSG).
addVitePlugin(componentVBindFix({ sourcemap: false }))
}

nuxt.options.alias['@vuestic/ag-grid-theme'] = resolve(__dirname, '../../ag-grid-theme/src/styles/index.scss');
nuxt.options.alias['vuestic-ui/styles/typography.css'] = resolve(__dirname, '../../ui/src/styles/typography/typography.scss');
Expand Down
3 changes: 3 additions & 0 deletions packages/docs/page-config/navigationRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ export const navigationRoutes: NavigationRoute[] = [
{
name: "radio",
displayName: "Radio",
meta: {
badge : navigationBadge.updated('1.7.0'),
}
},
{
name: "option-list",
Expand Down
12 changes: 11 additions & 1 deletion packages/docs/page-config/ui-elements/radio/api-description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ export default defineApiDescription({
props: {
value: "Model of the component",
option: "Option value that model is updated to when an option is selected",
tabindex: "Sets a custom tabindex"
options: "Array of options to be rendered",
tabindex: "Sets a custom tabindex",
textBy: "This prop is used to get the text of the option if option is an object",
trackBy: "In case there are options with the same value, to distinguish them you can use this prop",
valueBy: "This prop is used to get the value of the option if option is an object. If not provided, the option itself will be used as a value",
disabledBy: "This prop is used to get the disabled state of the option if option is an object",
ariaLabel: "Sets aria-label attribute",
},
slots: {
default: "Use this slot to pass a custom content as text to the component.",
icon: "Use this slot to pass a custom icon to the component.",
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
:option="options[0]"
color="warning"
label="warning"
name="color-radio-group"
/>
<va-radio
v-model="selectedOption"
:option="options[1]"
color="danger"
label="danger"
name="color-radio-group"
/>
<va-radio
v-model="selectedOption"
:option="options[2]"
color="info"
label="info"
name="color-radio-group"
/>
</template>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<va-radio
v-model="value"
:options="[
{
text: 'I\'m 18 or older',
value: true,
},
{
text: 'I\'m under 18',
value: false,
},
]"
value-by="value"
/>

Value: {{ value }}
</template>

<script>
export default {
data() {
return {
value: null,
};
},
};
</script>
17 changes: 12 additions & 5 deletions packages/docs/page-config/ui-elements/radio/examples/Default.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
<template>
<va-radio
v-for="(option, index) in options"
:key="index"
v-model="selectedOption"
:option="option"
option="One"
name="radio-group"
/>
<va-radio
v-model="selectedOption"
option="Two"
name="radio-group"
/>
<va-radio
v-model="selectedOption"
option="Three"
name="radio-group"
/>
<div>Selected: {{ selectedOption }}</div>
</template>

<script>
export default {
data() {
return {
options: ["one", "two", "three"],
selectedOption: "one",
};
},
Expand Down
16 changes: 16 additions & 0 deletions packages/docs/page-config/ui-elements/radio/examples/Options.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<va-radio
v-model="value"
:options="['One', 'Two', 'Three']"
/>
</template>

<script>
export default {
data() {
return {
value: 'one',
};
},
};
</script>
31 changes: 31 additions & 0 deletions packages/docs/page-config/ui-elements/radio/examples/Slot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<va-radio
v-model="value"
:options="['One', 'Two', 'Three']"
>
<template #icon="{ value }">
<va-icon
class="custom-icon"
:name="value ? 'check_circle' : 'radio_button_unchecked'"
:color="value ? 'primary': 'secondary'"
/>
</template>
<va-badge>Text</va-badge>
</va-radio>
</template>

<script>
export default {
data() {
return {
value: 'one',
};
},
};
</script>

<style lang="scss">
.va-radio__input:focus-visible + .custom-icon {
outline: 1px solid var(--va-primary);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<va-radio
v-model="value"
:rules="[
(v) => v !== null || 'Required',
(v) => !!v || 'You must be 18 or older',
]"
:options="[
{
text: 'I\'m 18 or older',
value: true,
},
{
text: 'I\'m under 18',
value: false,
},
]"
value-by="value"
/>
</template>

<script>
export default {
data() {
return {
value: null,
};
},
};
</script>
32 changes: 31 additions & 1 deletion packages/docs/page-config/ui-elements/radio/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,20 @@ export default definePageConfig({

block.example("Default", {
title: "Default",
description: "Default usage of the `va-radio` component."
description: "Default usage of the `va-radio` component. Make sure to add a `name` prop to group them together."
}),

block.example("Options", {
title: "Multiple Options",
description: "You can use `options` prop to pass an array of options to the component. Then multiple components will be rendered.`"
}),
block.example("ComplexOptions", {
description: "You can use more complex options with `textBy` and `valueBy` props if needed."
}),
block.example("Validation", {
description: "Passing multiple `options` at the same time allows you to use validation `rules`.",
}),

block.example("Color", {
title: "Colors",
description: "With `color` prop you can change the color of the component."
Expand All @@ -24,6 +36,24 @@ export default definePageConfig({
title: "Disabled",
description: "With `disabled` prop you can disable a user interaction with `va-radio` component."
}),
block.example("Slot", {
title: "Slot",
description: "You can use `default` slot to pass a custom content as text to the component. You can also change icon appearance with `icon` slot."
}),

block.subtitle('Accessibility'),
block.paragraph(`
Each option has [radio](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/radio_role)[[target=_blank]] role attribute.
If \`options\` prop is used the component has a [radiogroup](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/radiogroup_role)[[target=_blank]] role attribute,
otherwise you need to add \`role="radiogroup"\` on parent element manually.

[aria-checked](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-checked)[[target=_blank]] is applied on option automatically.

Always set \`name\` prop on the component to group options together for correct keyboard navigation.

Set [aria-label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label)[[target=_blank]] or [aria-labelledby](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby)[[target=_blank]] attribute on the component to provide a label for screen readers for radio-group if needed.
By default radio element labeled by text from option.
`.trim()),

block.subtitle("API"),
block.api("VaRadio", apiDescription, apiOptions),
Expand Down
11 changes: 7 additions & 4 deletions packages/ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
* @notice this exports used in `vuestic-ui` package. Make sure add component to vuestic-plugin as well.
*/

// Components used in other components
export * from './va-input'
export * from './va-fallback'
export * from './va-collapse'
export * from './va-card'
export * from './va-button'

// Other components
export * from './va-accordion'
export * from './va-affix'
export * from './va-alert'
Expand All @@ -23,12 +30,9 @@ export * from './va-breadcrumbs'
export * from './va-button-dropdown'
export * from './va-button-group'
export * from './va-button-toggle'
export * from './va-button'
export * from './va-card'
export * from './va-carousel'
export * from './va-checkbox'
export * from './va-chip'
export * from './va-collapse'
export * from './va-color-indicator'
export * from './va-color-input'
export * from './va-color-palette'
Expand All @@ -46,7 +50,6 @@ export * from './va-icon'
export * from './va-image'
export * from './va-infinite-scroll'
export * from './va-inner-loading'
export * from './va-input'
export * from './va-list'
export * from './va-modal'
export * from './va-navbar'
Expand Down
Loading