Skip to content

Commit

Permalink
Add pattern and autocomplete properties (#601)
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanforbes authored Oct 10, 2018
1 parent c1a55b5 commit c07301a
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/enhanced-text-input/tests/unit/EnhancedTextInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const expected = (options: ExpectedOptions = {}) => {
const children = [
v('input', {
'aria-invalid': invalid ? 'true' : null,
autocomplete: undefined,
classes: css.input,
disabled,
id: '',
Expand All @@ -52,6 +53,7 @@ const expected = (options: ExpectedOptions = {}) => {
minlength: null,
name: undefined,
placeholder: undefined,
pattern: undefined,
readOnly,
'aria-readonly': readOnly ? 'true' : null,
required,
Expand Down
41 changes: 38 additions & 3 deletions src/text-input/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WidgetBase } from '@dojo/framework/widget-core/WidgetBase';
import { DNode } from '@dojo/framework/widget-core/interfaces';
import { DNode, PropertyChangeRecord } from '@dojo/framework/widget-core/interfaces';
import { ThemedMixin, ThemedProperties, theme } from '@dojo/framework/widget-core/mixins/Themed';
import { v, w } from '@dojo/framework/widget-core/d';
import Focus from '@dojo/framework/widget-core/meta/Focus';
Expand All @@ -10,6 +10,7 @@ import { formatAriaProperties } from '../common/util';
import { uuid } from '@dojo/framework/core/util';
import * as css from '../theme/text-input.m.css';
import { customElement } from '@dojo/framework/widget-core/decorators/customElement';
import diffProperty from '@dojo/framework/widget-core/decorators/diffProperty';

export type TextInputType = 'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url';

Expand All @@ -33,11 +34,28 @@ export interface TextInputProperties extends ThemedProperties, InputProperties,
minLength?: number | string;
placeholder?: string;
value?: string;
pattern?: string | RegExp;
autocomplete?: boolean | string;
onClick?(value: string): void;
}

export const ThemedBase = ThemedMixin(FocusMixin(WidgetBase));

function formatAutocomplete(autocomplete: string | boolean | undefined): string | undefined {
if (typeof autocomplete === 'boolean') {
return autocomplete ? 'on' : 'off';
}
return autocomplete;
}

function patternDiffer(previousProperty: string | undefined, newProperty: string | RegExp | undefined): PropertyChangeRecord {
const value = newProperty instanceof RegExp ? newProperty.source : newProperty;
return {
changed: previousProperty !== value,
value
};
}

@theme(css)
@customElement<TextInputProperties>({
tag: 'dojo-text-input',
Expand All @@ -51,7 +69,19 @@ export const ThemedBase = ThemedMixin(FocusMixin(WidgetBase));
'labelAfter',
'labelHidden'
],
attributes: [ 'widgetId', 'label', 'placeholder', 'controls', 'type', 'minLength', 'maxLength', 'value', 'name' ],
attributes: [
'widgetId',
'label',
'placeholder',
'controls',
'type',
'minLength',
'maxLength',
'value',
'name',
'pattern',
'autocomplete'
],
events: [
'onBlur',
'onChange',
Expand All @@ -68,6 +98,7 @@ export const ThemedBase = ThemedMixin(FocusMixin(WidgetBase));
'onTouchStart'
]
})
@diffProperty('pattern', patternDiffer)
export class TextInputBase<P extends TextInputProperties = TextInputProperties> extends ThemedBase<P, null> {
private _onBlur (event: FocusEvent) {
this.properties.onBlur && this.properties.onBlur((event.target as HTMLInputElement).value);
Expand Down Expand Up @@ -159,12 +190,15 @@ export class TextInputBase<P extends TextInputProperties = TextInputProperties>
readOnly,
required,
type = 'text',
value
value,
pattern,
autocomplete
} = this.properties;

return v('input', {
...formatAriaProperties(aria),
'aria-invalid': invalid ? 'true' : null,
autocomplete: formatAutocomplete(autocomplete),
classes: this.theme(css.input),
disabled,
id: widgetId,
Expand All @@ -173,6 +207,7 @@ export class TextInputBase<P extends TextInputProperties = TextInputProperties>
maxlength: maxLength ? `${maxLength}` : null,
minlength: minLength ? `${minLength}` : null,
name,
pattern,
placeholder,
readOnly,
'aria-readonly': readOnly ? 'true' : null,
Expand Down
66 changes: 66 additions & 0 deletions src/text-input/tests/unit/TextInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const expected = function(label = false, inputOverrides = {}, states: States = {
id: '',
disabled,
'aria-invalid': invalid ? 'true' : null,
autocomplete: undefined,
maxlength: null,
minlength: null,
name: undefined,
Expand All @@ -54,6 +55,7 @@ const expected = function(label = false, inputOverrides = {}, states: States = {
type: 'text',
value: undefined,
focus: noop,
pattern: undefined,
onblur: noop,
onchange: noop,
onclick: noop,
Expand Down Expand Up @@ -116,6 +118,70 @@ registerSuite('TextInput', {
h.expect(() => expected(true));
},

'pattern': {
'string'() {
const h = harness(() => w(TextInput, {
pattern: '^foo|bar$'
}));

h.expect(() => expected(false, {
pattern: '^foo|bar$'
}));
},
'regexp'() {
const properties = {
pattern: /^foo|bar$/
};
const h = harness(() => w(TextInput, properties));

h.expect(() => expected(false, {
pattern: '^foo|bar$'
}));

(properties.pattern.compile as any)('^bar|baz$');

h.expect(() => expected(false, {
pattern: '^bar|baz$'
}));

properties.pattern = /^ham|spam$/;

h.expect(() => expected(false, {
pattern: '^ham|spam$'
}));
}
},

'autocomplete': {
'true'() {
const h = harness(() => w(TextInput, {
autocomplete: true
}));

h.expect(() => expected(false, {
autocomplete: 'on'
}));
},
'false'() {
const h = harness(() => w(TextInput, {
autocomplete: false
}));

h.expect(() => expected(false, {
autocomplete: 'off'
}));
},
'string'() {
const h = harness(() => w(TextInput, {
autocomplete: 'name'
}));

h.expect(() => expected(false, {
autocomplete: 'name'
}));
}
},

'state classes'() {
let properties = {
invalid: true,
Expand Down

0 comments on commit c07301a

Please sign in to comment.