Skip to content

Commit 3cc8020

Browse files
authored
Merge pull request #669 from HelixDesignSystem/surf-1711-1980-hx-email-control
feat(email control): added email control component
2 parents c265a5d + 2880c7d commit 3cc8020

File tree

13 files changed

+980
-0
lines changed

13 files changed

+980
-0
lines changed

docs/_data/nav.json5

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
{ label: 'Choice Tile', path: 'choice-tile' },
2525
{ label: 'Drawer', path: 'drawer' },
2626
{ label: 'Dropdown Select', path: 'dropdown-select' },
27+
{ label: 'Email Input', path: 'email' },
2728
{ label: 'File', path: 'file' },
2829
{ label: 'Grid', path: 'grid' },
2930
{ label: 'Icon', path: 'icon' },
@@ -77,6 +78,7 @@
7778
{ label: '<hx-drop-fence>', path: 'hx-drop-fence' },
7879
{ label: '<hx-drop-zone>', path: 'hx-drop-zone' },
7980
{ label: '<hx-error>', path: 'hx-error' },
81+
{ label: '<hx-email-control>', path: 'hx-email-control' },
8082
{ label: '<hx-file-icon>', path: 'hx-file-icon' },
8183
{ label: '<hx-file-input>', path: 'hx-file-input' },
8284
{ label: '<hx-file-tile>', path: 'hx-file-tile' },

docs/components/_index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@import "checkbox/spec";
88
@import "choice-tile/spec";
99
@import "dropdown-select/spec";
10+
@import "email/spec";
1011
@import "file/spec";
1112
@import "menu/spec";
1213
@import "popover/spec";

docs/components/email/_spec.scss

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@import "components/form/mixins/textControl";
2+
3+
.email-input-spec {
4+
hx-email-control {
5+
/* ----- Pristine --------------- */
6+
> input[type="email"].mock-focus {
7+
@include hxTextControl($focused: true);
8+
}
9+
10+
/* ----- Disabled --------------- */
11+
> input[type="email"]:disabled.mock-focus {
12+
@include hxTextControl(disabled, $focused: true);
13+
}
14+
15+
/* ----- Changed / Touched --------------- */
16+
&[hx-dirty] {
17+
> input[type="email"]:invalid.mock-focus {
18+
@include hxTextControl(invalid, $focused: true);
19+
}
20+
}
21+
22+
/* ----- Styled Invalid --------------- */
23+
&.hxInvalid > input[type="email"]:enabled.mock-focus {
24+
@include hxTextControl(invalid, $focused: true);
25+
}
26+
}
27+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import Util from '../../_util';
2+
3+
if (document.getElementById('vue-emailInputDemo')) {
4+
new Vue({
5+
el: '#vue-emailInputDemo',
6+
data: {
7+
hasHelpText: false,
8+
hasErrorText: false,
9+
isDisabled: false,
10+
isRequired: false,
11+
label: 'Email',
12+
labelState: '',
13+
helpText: '[email protected]',
14+
errorText: 'Please enter a valid email',
15+
errorTextToDisplay: false,
16+
helpTextToDisplay: false,
17+
},
18+
computed: {
19+
attrDisabled: function () {
20+
return (this.isDisabled ? 'disabled' : '');
21+
},
22+
attrRequired: function () {
23+
return (this.isRequired ? 'required' : '');
24+
},
25+
lblClasses: function () {
26+
let classes = [];
27+
28+
if (this.labelState === 'hxRequired') {
29+
classes.push('hxRequired');
30+
}
31+
32+
if (this.labelState === 'hxOptional') {
33+
classes.push('hxOptional');
34+
}
35+
36+
let classNames = classes.join(' ');
37+
38+
return (classNames === '' ? '' : `class="${classNames}"`);
39+
},
40+
isHelpTextHidden: function () {
41+
return (this.helpTextToDisplay ? '' : 'hidden');
42+
},
43+
isErrorTextHidden: function () {
44+
return (this.errorTextToDisplay ? '' : 'hidden');
45+
},
46+
snippet: function () {
47+
return Util.snippet(`
48+
<hx-email-control>
49+
<input
50+
id="emailDemo"
51+
type="email"
52+
${this.attrDisabled}
53+
${this.attrRequired}
54+
/>
55+
<label
56+
for="emailDemo"
57+
${this.lblClasses}
58+
>
59+
${this.label}
60+
</label>
61+
<p class="hxHelpText" ${this.isHelpTextHidden}>
62+
${this.helpText}
63+
</p>
64+
<p class="hxErrorText" ${this.isErrorTextHidden}>
65+
<hx-error>
66+
${this.errorText}
67+
</hx-error>
68+
</p>
69+
</hx-email-control>
70+
`);
71+
},
72+
},
73+
});
74+
}

docs/components/email/index.html

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: Email Input
3+
minver: 0.20.0
4+
also:
5+
components/email/test.html: Testing - Email Input
6+
elements/hx-email-control/index.html: <hx-email-control>
7+
---
8+
{% extends 'component.njk' %}
9+
10+
{% block page_header %}
11+
<p>
12+
The {{page.title}} component provides supplmental markup to define
13+
and style an email address input control.
14+
</p>
15+
{% endblock %}
16+
17+
{% block content %}
18+
<section>
19+
<header>
20+
<h2 id="basic-email-input">Basic Email Input</h2>
21+
{# TODO: add section description #}
22+
</header>
23+
24+
<div class="example" id="vue-emailInputDemo" v-cloak>
25+
<header>
26+
<form class="beta-hxForm">
27+
<fieldset>
28+
<legend class="beta-hxFieldName">Label Annotation</legend>
29+
<hx-radio-set>
30+
<hx-radio-control>
31+
<input
32+
id="radHasAsterisk"
33+
name="radReqOp"
34+
type="radio"
35+
value="hxRequired"
36+
v-model="labelState"
37+
/>
38+
<label for="radHasAsterisk">
39+
<hx-radio></hx-radio>
40+
Required
41+
</label>
42+
</hx-radio-control>
43+
<hx-radio-control>
44+
<input
45+
id="radHasOptional"
46+
name="radReqOp"
47+
type="radio"
48+
value="hxOptional"
49+
v-model="labelState"
50+
/>
51+
<label for="radHasOptional">
52+
<hx-radio></hx-radio>
53+
Optional
54+
</label>
55+
</hx-radio-control>
56+
</hx-radio-set>
57+
</fieldset>
58+
59+
<fieldset>
60+
<legend class="beta-hxFieldName">Control Options</legend>
61+
<hx-checkbox-control>
62+
<input id="chkDisabled" type="checkbox" v-model="isDisabled" />
63+
<label for="chkDisabled">
64+
<hx-checkbox></hx-checkbox>
65+
Disabled
66+
</label>
67+
</hx-checkbox-control>
68+
69+
<hx-checkbox-control>
70+
<input id="chkRequired" type="checkbox" v-model="isRequired" />
71+
<label for="chkRequired">
72+
<hx-checkbox></hx-checkbox>
73+
Required
74+
</label>
75+
<p>
76+
(Invalid styling applied <i>after</i> user interaction.)
77+
</p>
78+
</hx-checkbox-control>
79+
</fieldset>
80+
81+
<fieldset>
82+
<legend class="beta-hxFieldName">Optional Text</legend>
83+
<hx-checkbox-control>
84+
<input
85+
id="chkHasHelpText"
86+
type="checkbox"
87+
v-model="helpTextToDisplay"
88+
/>
89+
<label for="chkHasHelpText">
90+
<hx-checkbox></hx-checkbox>
91+
Help Text
92+
</label>
93+
</hx-checkbox-control>
94+
<hx-checkbox-control>
95+
<input
96+
id="chkHasErrorText"
97+
type="checkbox"
98+
v-model="errorTextToDisplay"
99+
/>
100+
<label for="chkHasErrorText">
101+
<hx-checkbox></hx-checkbox>
102+
Error Text
103+
</label>
104+
</hx-checkbox-control>
105+
<hx-text-control>
106+
<input
107+
id="txtHelpText"
108+
type="text"
109+
v-model="helpText"
110+
:disabled="!helpTextToDisplay"
111+
/>
112+
<label for="txtHelpText">
113+
Help Text
114+
</label>
115+
</hx-text-control>
116+
<hx-text-control>
117+
<input
118+
id="txtErrorText"
119+
type="text"
120+
v-model="errorText"
121+
:disabled="!errorTextToDisplay"
122+
/>
123+
<label for="txtErrorText">
124+
Error Text
125+
</label>
126+
</hx-text-control>
127+
</fieldset>
128+
</form>
129+
</header>
130+
131+
<div>
132+
<hx-email-control>
133+
<input
134+
id="emailInputDemo"
135+
type="email"
136+
placeholder="Please enter your email"
137+
:disabled="isDisabled"
138+
:required="isRequired"
139+
/>
140+
<label
141+
for="emailInputDemo"
142+
:class="labelState"
143+
>
144+
{% raw %}{{label}}{% endraw %}
145+
</label>
146+
<p class="hxHelpText" :hidden="!helpTextToDisplay">
147+
{% raw %}{{helpText}} {% endraw %}
148+
</p>
149+
<p class="hxErrorText" :hidden="!errorTextToDisplay">
150+
<hx-error>
151+
{% raw %}{{errorText}} {% endraw %}
152+
</hx-error>
153+
</p>
154+
</hx-email-control>
155+
</div>
156+
157+
<footer>
158+
<pre><code v-text="snippet"></code></pre>
159+
</footer>
160+
</div>
161+
162+
<footer>
163+
<p class="hxSubBody hxSubdued">
164+
<hx-icon type="exclamation-triangle"></hx-icon>
165+
The <code>&lt;input&gt;</code> element <i>must</i> have the
166+
<code>type="email"</code> attribute, in order for CSS styles
167+
to apply.
168+
</p>
169+
</footer>
170+
</section>
171+
172+
{% endblock %}

0 commit comments

Comments
 (0)