Skip to content

Commit

Permalink
Merge pull request #413 from ghiscoding/feat/aria-label
Browse files Browse the repository at this point in the history
feat(aria): add aria-label to all Editors/Filters & other html templates
  • Loading branch information
AnnetteZhang authored Jul 15, 2021
2 parents 2abe803 + 72471df commit f34a84f
Show file tree
Hide file tree
Showing 39 changed files with 244 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ describe('InputPasswordEditor', () => {
expect(editor.inputType).toBe('password');
});

it('should have an aria-label when creating the editor', () => {
editor = new InputPasswordEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-text.editor-title') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Title Input Editor');
});

it('should initialize the editor and focus on the element after a small delay', () => {
editor = new InputPasswordEditor(editorArguments);
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-title').length;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/checkboxEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ describe('CheckboxEditor', () => {
expect(editorCount).toBe(1);
});

it('should have an aria-label when creating the editor', () => {
editor = new CheckboxEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-checkbox') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Is Active Checkbox Editor');
});

it('should initialize the editor even when user define his own editor options', () => {
(mockColumn.internalColumnEditor as ColumnEditor).editorOptions = { minLength: 3 } as AutocompleteOption;
editor = new CheckboxEditor(editorArguments);
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/dualInputEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ describe('DualInputEditor', () => {
expect(editorCount).toBe(2);
});

it('should have an aria-label when creating the editor', () => {
editor = new DualInputEditor(editorArguments);
const editorElm = divContainer.querySelector('input.dual-editor-text.editor-range.left') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Range Input Editor');
});

it('should have a placeholder on the left input when defined in its column definition', () => {
const testValue = 'test placeholder';
(mockColumn.internalColumnEditor as ColumnEditor).params.leftInput.placeholder = testValue;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/floatEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ describe('FloatEditor', () => {
expect(editor.inputType).toBe('number');
});

it('should have an aria-label when creating the editor', () => {
editor = new FloatEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-text.editor-price') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Price Number Editor');
});

it('should initialize the editor and focus on the element after a small delay', () => {
editor = new FloatEditor(editorArguments);
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-price').length;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/inputEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ describe('InputEditor (TextEditor)', () => {
expect(editor.inputType).toBe('text');
});

it('should have an aria-label when creating the editor', () => {
editor = new InputEditor(editorArguments, 'text');
const editorElm = divContainer.querySelector('input.editor-text.editor-title') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Title Input Editor');
});

it('should initialize the editor and focus on the element after a small delay', () => {
editor = new InputEditor(editorArguments, 'text');
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-title').length;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/integerEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ describe('IntegerEditor', () => {
expect(editor.inputType).toBe('number');
});

it('should have an aria-label when creating the editor', () => {
editor = new IntegerEditor(editorArguments);
const editorElm = divContainer.querySelector('input.editor-text.editor-price') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Price Slider Editor');
});

it('should initialize the editor and focus on the element after a small delay', () => {
editor = new IntegerEditor(editorArguments);
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-price').length;
Expand Down
8 changes: 8 additions & 0 deletions packages/common/src/editors/__tests__/longTextEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ describe('LongTextEditor', () => {
expect(buttonSaveElm.textContent).toBe('Sauvegarder');
});

it('should have an aria-label when creating the editor', () => {
gridOptionMock.translater = undefined as any;
editor = new LongTextEditor(editorArguments);
const editorElm = document.body.querySelector('.slick-large-editor-text.editor-title textarea') as HTMLTextAreaElement;

expect(editorElm.getAttribute('aria-label')).toBe('Title Text Editor');
});

it('should initialize the editor with default constant text when translate service is not provided', () => {
gridOptionMock.translater = undefined as any;
editor = new LongTextEditor(editorArguments);
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/editors/__tests__/sliderEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ describe('SliderEditor', () => {
expect(editorCount).toBe(1);
});

it('should have an aria-label when creating the editor', () => {
editor = new SliderEditor(editorArguments);
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;

expect(editorElm.getAttribute('aria-label')).toBe('Price Slider Editor');
});

it('should have a title (tooltip) when defined in its column definition', () => {
const testValue = 'test title';
(mockColumn.internalColumnEditor as ColumnEditor).title = testValue;
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/checkboxEditor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Constants } from './../constants';
import { Column, ColumnEditor, CompositeEditorOption, Editor, EditorArguments, EditorValidator, EditorValidationResult, GridOption, SlickGrid, SlickNamespace } from './../interfaces/index';
import { getDescendantProperty, setDeepValue } from '../services/utilities';
import { getDescendantProperty, setDeepValue, toSentenceCase } from '../services/utilities';
import { BindingEventService } from '../services/bindingEvent.service';

// using external non-typed js libraries
Expand Down Expand Up @@ -78,6 +78,7 @@ export class CheckboxEditor implements Editor {
this._input.title = title;
this._input.type = 'checkbox';
this._input.value = 'true';
this._input.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Checkbox Editor`);

const cellContainer = this.args?.container;
if (cellContainer && typeof cellContainer.appendChild === 'function') {
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/dualInputEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
SlickGrid,
SlickNamespace,
} from '../interfaces/index';
import { getDescendantProperty, setDeepValue } from '../services/utilities';
import { getDescendantProperty, setDeepValue, toSentenceCase } from '../services/utilities';
import { floatValidator, integerValidator, textValidator } from '../editorValidators';
import { BindingEventService } from '../services/bindingEvent.service';

Expand Down Expand Up @@ -199,6 +199,7 @@ export class DualInputEditor implements Editor {
}
input.type = fieldType || 'text';
input.setAttribute('role', 'presentation');
input.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Input Editor`);
input.autocomplete = 'off';
input.placeholder = editorSideParams.placeholder || '';
input.title = editorSideParams.title || '';
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/floatEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KeyCode } from '../enums/index';
import { EditorArguments, EditorValidationResult } from '../interfaces/index';
import { floatValidator } from '../editorValidators/floatValidator';
import { InputEditor } from './inputEditor';
import { getDescendantProperty } from '../services/utilities';
import { getDescendantProperty, toSentenceCase } from '../services/utilities';

const DEFAULT_DECIMAL_PLACES = 0;

Expand All @@ -28,6 +28,7 @@ export class FloatEditor extends InputEditor {
this._input.placeholder = placeholder;
this._input.title = title;
this._input.step = `${inputStep}`;
this._input.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Number Editor`);
const cellContainer = this.args.container;
if (cellContainer && typeof cellContainer.appendChild === 'function') {
cellContainer.appendChild(this._input);
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/inputEditor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { KeyCode } from '../enums/keyCode.enum';
import { Column, ColumnEditor, CompositeEditorOption, Editor, EditorArguments, EditorValidator, EditorValidationResult, GridOption, SlickGrid, SlickNamespace, } from '../interfaces/index';
import { getDescendantProperty, setDeepValue } from '../services/utilities';
import { getDescendantProperty, setDeepValue, toSentenceCase } from '../services/utilities';
import { textValidator } from '../editorValidators/textValidator';
import { BindingEventService } from '../services/bindingEvent.service';

Expand Down Expand Up @@ -92,6 +92,7 @@ export class InputEditor implements Editor {
this._input.autocomplete = 'off';
this._input.placeholder = placeholder;
this._input.title = title;
this._input.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Input Editor`);
const cellContainer = this.args.container;
if (cellContainer && typeof cellContainer.appendChild === 'function') {
cellContainer.appendChild(this._input);
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/integerEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KeyCode } from '../enums/index';
import { EditorArguments, EditorValidationResult } from '../interfaces/index';
import { integerValidator } from '../editorValidators/integerValidator';
import { InputEditor } from './inputEditor';
import { getDescendantProperty } from '../services/utilities';
import { getDescendantProperty, toSentenceCase } from '../services/utilities';

export class IntegerEditor extends InputEditor {
constructor(protected readonly args: EditorArguments) {
Expand All @@ -26,6 +26,7 @@ export class IntegerEditor extends InputEditor {
this._input.placeholder = placeholder;
this._input.title = title;
this._input.step = `${inputStep}`;
this._input.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Slider Editor`);
const cellContainer = this.args.container;
if (cellContainer && typeof cellContainer.appendChild === 'function') {
cellContainer.appendChild(this._input);
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/longTextEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
SlickGrid,
SlickNamespace,
} from '../interfaces/index';
import { getDescendantProperty, getHtmlElementOffset, getTranslationPrefix, setDeepValue, } from '../services/utilities';
import { getDescendantProperty, getHtmlElementOffset, getTranslationPrefix, setDeepValue, toSentenceCase, } from '../services/utilities';
import { BindingEventService } from '../services/bindingEvent.service';
import { TranslaterService } from '../services/translater.service';
import { textValidator } from '../editorValidators/textValidator';
Expand Down Expand Up @@ -135,6 +135,7 @@ export class LongTextEditor implements Editor {
this._textareaElm.rows = (compositeEditorOptions && textAreaRows > 3) ? 3 : textAreaRows;
this._textareaElm.placeholder = placeholder;
this._textareaElm.title = title;
this._textareaElm.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Text Editor`);
this._wrapperElm.appendChild(this._textareaElm);

const editorFooterElm = document.createElement('div');
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/editors/sliderEditor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Column, ColumnEditor, CompositeEditorOption, Editor, EditorArguments, EditorValidator, EditorValidationResult, GridOption, SlickGrid, SlickNamespace } from '../interfaces/index';
import { getDescendantProperty, setDeepValue } from '../services/utilities';
import { getDescendantProperty, setDeepValue, toSentenceCase } from '../services/utilities';
import { sliderValidator } from '../editorValidators/sliderValidator';
import { BindingEventService } from '../services/bindingEvent.service';

Expand Down Expand Up @@ -318,6 +318,7 @@ export class SliderEditor implements Editor {
inputElm.max = `${maxValue}`;
inputElm.step = `${step}`;
inputElm.className = `form-control slider-editor-input editor-${columnId} range ${this._elementRangeInputId}`;
inputElm.setAttribute('aria-label', this.columnEditor?.ariaLabel ?? `${toSentenceCase(columnId + '')} Slider Editor`);

const divContainerElm = document.createElement('div');
divContainerElm.className = 'slider-container slider-editor';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ describe('CompoundInputFilter', () => {
expect(filter.inputType).toBe('text');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should have a placeholder when defined in its column definition', () => {
const testValue = 'test placeholder';
mockColumn.filter!.placeholder = testValue;
Expand All @@ -75,6 +82,7 @@ describe('CompoundInputFilter', () => {
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

expect(filterInputElm.placeholder).toBe(testValue);
expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should call "setValues" and expect that value to be in the callback when triggered', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ describe('CompoundInputNumberFilter', () => {
expect(() => filter.init(null as any)).toThrowError('[Slickgrid-Universal] A filter must always have an "init()" with valid arguments.');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should initialize the filter and expect an input of type number', () => {
filter.init(filterArguments);
const filterCount = divContainer.querySelectorAll('.search-filter.filter-duration').length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ describe('CompoundInputPasswordFilter', () => {
expect(() => filter.init(null as any)).toThrowError('[Slickgrid-Universal] A filter must always have an "init()" with valid arguments.');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.filter-duration input') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should initialize the filter and expect an input of type password', () => {
filter.init(filterArguments);
const filterCount = divContainer.querySelectorAll('.search-filter.filter-duration').length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ describe('CompoundSliderFilter', () => {
expect(filterCount).toBe(1);
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.input-group.search-filter.filter-duration input') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should call "setValues" with "operator" set in the filter arguments and expect that value to be in the callback when triggered', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
const filterArgs = { ...filterArguments, operator: '>' } as FilterArguments;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/filters/__tests__/inputFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ describe('InputFilter', () => {
expect(filter.inputType).toBe('text');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('input.filter-duration') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should have a placeholder when defined in its column definition', () => {
const testValue = 'test placeholder';
mockColumn.filter!.placeholder = testValue;
Expand Down
8 changes: 8 additions & 0 deletions packages/common/src/filters/__tests__/inputMaskFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ describe('InputMaskFilter', () => {
expect(filter.inputMask).toBe('000-000-0000');
});

it('should have an aria-label when creating the filter', () => {
mockColumn.filter!.params = { mask: '000-000-0000' };
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('input.filter-mask') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Mask Search Filter');
});

it('should initialize the filter and define the mask in the column definition instead and get the same output', () => {
mockColumn.params = { mask: '000-000-0000' };
filter.init(filterArguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ describe('InputNumberFilter', () => {
expect(() => filter.init(null as any)).toThrowError('[Slickgrid-Universal] A filter must always have an "init()" with valid arguments.');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('input.filter-number') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Number Search Filter');
});

it('should initialize the filter and expect an input of type number', () => {
filter.init(filterArguments);
const filterCount = divContainer.querySelectorAll('input.filter-number').length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('InputPasswordFilter', () => {
document.body.appendChild(divContainer);
spyGetHeaderRow = jest.spyOn(gridStub, 'getHeaderRowColumn').mockReturnValue(divContainer);

mockColumn = { id: 'password', field: 'password', filterable: true, filter: { model: Filters.inputPassword } };
mockColumn = { id: 'passwordField', field: 'password', filterable: true, filter: { model: Filters.inputPassword } };
filterArguments = {
grid: gridStub,
columnDef: mockColumn,
Expand All @@ -50,9 +50,16 @@ describe('InputPasswordFilter', () => {
expect(() => filter.init(null as any)).toThrowError('[Slickgrid-Universal] A filter must always have an "init()" with valid arguments.');
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('input.filter-passwordField') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Password Field Search Filter');
});

it('should initialize the filter and expect an input of type password', () => {
filter.init(filterArguments);
const filterCount = divContainer.querySelectorAll('input.filter-password').length;
const filterCount = divContainer.querySelectorAll('input.filter-passwordField').length;

expect(spyGetHeaderRow).toHaveBeenCalled();
expect(filterCount).toBe(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ describe('NativeSelectFilter', () => {
expect(filterCount).toBe(1);
});

it('should have an aria-label when creating the filter', () => {
mockColumn.filter!.collection = [{ value: 'male', label: 'male' }, { value: 'female', label: 'female' }];
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('select.form-control.search-filter.filter-gender') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Gender Search Filter');
});

it('should trigger select change event and expect the callback to be called with the search terms we select from dropdown list', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');
mockColumn.filter!.collection = [{ value: 'male', label: 'male' }, { value: 'female', label: 'female' }];
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/filters/__tests__/sliderFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ describe('SliderFilter', () => {
expect(filterCount).toBe(1);
});

it('should have an aria-label when creating the filter', () => {
filter.init(filterArguments);
const filterInputElm = divContainer.querySelector('.search-filter.slider-container.filter-duration input') as HTMLInputElement;

expect(filterInputElm.getAttribute('aria-label')).toBe('Duration Search Filter');
});

it('should call "setValues" and expect that value to be in the callback when triggered', () => {
const spyCallback = jest.spyOn(filterArguments, 'callback');

Expand Down
Loading

0 comments on commit f34a84f

Please sign in to comment.