Skip to content

Commit

Permalink
[Release] HdIcon accessibility and HdInput improvements #485
Browse files Browse the repository at this point in the history
# Changelog

## Minor
- ✨ Support title and description in HdIcon (#481)
- ✨ Forward attributes from HdInput to <input> (#483)

## Patch
- ⬆️ Bump lodash from 4.17.15 to 4.17.19 (#484)
- ⬆️ Node v10.22.0
  • Loading branch information
viniciuskneves authored Jul 22, 2020
2 parents d12d52d + 8f97dfd commit c2be29f
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 169 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v10.21.0
v10.22.0
457 changes: 296 additions & 161 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "homeday-blocks",
"version": "12.0.0",
"version": "12.1.0",
"description": "A Vue component library built by Homeday's frontend team.",
"main": "main.js",
"repository": {
Expand Down Expand Up @@ -37,7 +37,7 @@
},
"dependencies": {
"body-scroll-lock": "2.6.4",
"lodash": "4.17.15",
"lodash": "4.17.19",
"natural-scroll": "0.2.2",
"vue": "2.6.11",
"vue-flickity": "1.2.1",
Expand Down
33 changes: 33 additions & 0 deletions src/components/HdIcon.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<inline-svg
:src="src"
:id="id"
:transform-source="transform"
v-bind="$attrs"
/>
Expand All @@ -21,6 +22,15 @@ export default {
type: String,
required: true,
},
title: {
type: String,
},
id: {
type: String,
},
description: {
type: String,
},
// to set a fill based on the path's class
fillFromClass: {
type: Object,
Expand All @@ -34,6 +44,8 @@ export default {
},
methods: {
transform(svg) {
this.addAccessibilityTags(svg);
if (!this.fillFromClass && !this.classFromFill) {
return svg;
}
Expand All @@ -53,6 +65,27 @@ export default {
return svg;
},
addAccessibilityTags(svg) {
const randId = Math.floor(Math.random() * 1000);
if (this.title) this.addTitleTag(svg, randId);
if (this.description) this.addDescTag(svg, randId);
},
addTitleTag(svg, randId) {
const titleId = `${this.id || randId}-title`;
const titleTag = document.createElementNS('http://www.w3.org/2000/svg', 'title');
titleTag.textContent = this.title;
titleTag.id = titleId;
svg.insertBefore(titleTag, svg.firstChild);
svg.setAttribute('aria-labelledby', titleId);
},
addDescTag(svg, randId) {
const descId = `${this.id || randId}-desc`;
const descTag = document.createElementNS('http://www.w3.org/2000/svg', 'desc');
descTag.id = descId;
descTag.textContent = this.description;
svg.appendChild(descTag);
svg.setAttribute('aria-describedby', descId);
},
getFillFromClassNames(classNames) {
if (!classNames || !this.fillFromClass) {
return null;
Expand Down
7 changes: 2 additions & 5 deletions src/components/form/HdInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
class="field__icon"
>
<input
v-bind="$attrs"
:autocomplete="autocomplete"
:value="value"
:type="currentType"
:id="name"
:name="name"
:placeholder="isActive && placeholder !== undefined ? placeholder : ''"
:required="required"
:autofocus="autofocus"
:disabled="disabled"
class="field__input"
ref="input"
Expand Down Expand Up @@ -58,6 +58,7 @@ import {
export default {
name: 'HdInput',
inheritAttrs: false,
props: {
label: {
type: String,
Expand Down Expand Up @@ -87,10 +88,6 @@ export default {
type: String,
default: 'on',
},
autofocus: {
type: Boolean,
default: false,
},
min: {
type: Number,
default: undefined,
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/components/HdIcon.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,36 @@ describe('HdIcon', () => {
expect(targetedPaths.length).toBeGreaterThan(0);
expect(targetedPaths.is(`.${TEST_CLASS}`)).toBe(true);
});

it('adds title and desc tag to the svg', async () => {
const wrapper = wrapperBuilder({
props: {
src: 'fake/icon4.svg',
title: 'This make me accessible.',
description: 'Some description.',
id: 'icon-id',
},
});

await wrapper.vm.$nextTick();

expect(wrapper.html()).toMatchSnapshot();
});

it("generates the title and desc id if it's not provided", async () => {
const wrapper = wrapperBuilder({
props: {
src: 'fake/icon5.svg',
title: 'This make me accessible.',
description: 'Some description.',
},
});

await wrapper.vm.$nextTick();

const titleTag = wrapper.find('title');
const descTag = wrapper.find('desc');
expect(titleTag.element.id).toMatch(/\d+-title/);
expect(descTag.element.id).toMatch(/\d+-desc/);
});
});
9 changes: 9 additions & 0 deletions tests/unit/components/__snapshots__/HdIcon.spec.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`HdIcon adds title and desc tag to the svg 1`] = `
<svg aria-describedby="icon-id-desc" aria-labelledby="icon-id-title" height="50" width="50" viewBox="222 126 53 53" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="icon-id">
<title id="icon-id-title">This make me accessible.</title>
<path class="color1" d="M272.48 137.62L258.61 150.5L244.75 141.58L254.65 126.73L272.48 137.62Z" fill="#1895FF"></path>
<path class="color2" d="M242.22 176.24L222.97 160.68L230.47 145.1L243.56 155.68L242.22 176.24Z" fill="#1C3553"></path>
<desc id="icon-id-desc">Some description.</desc>
</svg>
`;

exports[`HdIcon renders as expected 1`] = `
<svg height="50" width="50" viewBox="222 126 53 53" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<path class="color1" d="M272.48 137.62L258.61 150.5L244.75 141.58L254.65 126.73L272.48 137.62Z" fill="#1895FF"></path>
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/components/form/HdInput.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,14 @@ describe('HdInput', () => {

expect(wrapper.find(ERROR_SELECTOR).text()).toBe(errorMsg);
});

it('forwards attributes to <input>', () => {
const wrapper = wrapperBuilder({
props: {
readonly: true,
},
});

expect(wrapper.find('input').attributes().readonly).toBe('readonly');
});
});

0 comments on commit c2be29f

Please sign in to comment.