Skip to content

Commit 4478017

Browse files
authored
Showcase: convert Form > Text Input page to gts (#3246)
1 parent 9f5ea9d commit 4478017

File tree

8 files changed

+639
-469
lines changed

8 files changed

+639
-469
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import Component from '@glimmer/component';
2+
import { on } from '@ember/modifier';
3+
import { tracked } from '@glimmer/tracking';
4+
import type Owner from '@ember/owner';
5+
import { hash } from '@ember/helper';
6+
7+
import { HdsFormTextInputField } from '@hashicorp/design-system-components/components';
8+
9+
export interface CodeFragmentWithCharacterCountSignature {
10+
Args: {
11+
maxLength: number;
12+
value: string;
13+
hasValidation?: boolean;
14+
hasHelperText?: boolean;
15+
};
16+
Blocks: {
17+
characterCount: [
18+
{
19+
currentLength?: number;
20+
maxLength?: number;
21+
},
22+
];
23+
};
24+
}
25+
26+
export default class CodeFragmentWithCharacterCount extends Component<CodeFragmentWithCharacterCountSignature> {
27+
@tracked value = '';
28+
@tracked isInvalid = false;
29+
30+
constructor(
31+
owner: Owner,
32+
args: CodeFragmentWithCharacterCountSignature['Args'],
33+
) {
34+
super(owner, args);
35+
this.value = args.value ?? '';
36+
this.validateValue();
37+
}
38+
39+
updateValue = (event: Event) => {
40+
const { value } = event.target as HTMLTextAreaElement;
41+
this.value = value;
42+
43+
this.validateValue();
44+
};
45+
46+
validateValue = () => {
47+
if (this.args.hasValidation) {
48+
this.isInvalid = this.value.length > this.args.maxLength;
49+
}
50+
};
51+
52+
<template>
53+
<HdsFormTextInputField
54+
@value={{this.value}}
55+
{{on "input" this.updateValue}}
56+
as |F|
57+
>
58+
<F.Label>This is the label text</F.Label>
59+
{{#if @hasHelperText}}
60+
<F.HelperText>This is the helper text</F.HelperText>
61+
{{/if}}
62+
{{#if (has-block "characterCount")}}
63+
<F.CharacterCount @maxLength={{@maxLength}} as |CC|>
64+
{{yield
65+
(hash currentLength=CC.currentLength maxLength=CC.maxLength)
66+
to="characterCount"
67+
}}
68+
</F.CharacterCount>
69+
{{else}}
70+
<F.CharacterCount @maxLength={{@maxLength}} />
71+
{{/if}}
72+
{{#if this.isInvalid}}
73+
<F.Error>Maximum numbers of characters exceeded</F.Error>
74+
{{/if}}
75+
</HdsFormTextInputField>
76+
</template>
77+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
import type { TemplateOnlyComponent } from '@ember/component/template-only';
6+
import { pageTitle } from 'ember-page-title';
7+
8+
import ShwTextH1 from 'showcase/components/shw/text/h1';
9+
10+
import SubSectionBaseElement from 'showcase/components/page-components/form/text-input/sub-sections/base-element';
11+
import SubSectionFieldElement from 'showcase/components/page-components/form/text-input/sub-sections/field-element';
12+
13+
const FormTextInputIndex: TemplateOnlyComponent = <template>
14+
{{pageTitle "TextInput Component"}}
15+
16+
<ShwTextH1>TextInput</ShwTextH1>
17+
18+
<section data-test-percy>
19+
<SubSectionBaseElement />
20+
<SubSectionFieldElement />
21+
</section>
22+
</template>;
23+
24+
export default FormTextInputIndex;
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
import type { TemplateOnlyComponent } from '@ember/component/template-only';
6+
import { capitalize } from '@ember/string';
7+
import { array } from '@ember/helper';
8+
import style from 'ember-style-modifier';
9+
import { eq, and } from 'ember-truth-helpers';
10+
11+
import ShwTextH2 from 'showcase/components/shw/text/h2';
12+
import ShwTextH3 from 'showcase/components/shw/text/h3';
13+
import ShwFlex from 'showcase/components/shw/flex';
14+
import ShwGrid from 'showcase/components/shw/grid';
15+
import ShwDivider from 'showcase/components/shw/divider';
16+
17+
import { HdsFormTextInputBase } from '@hashicorp/design-system-components/components';
18+
import { TYPES } from '@hashicorp/design-system-components/components/hds/form/text-input/base';
19+
20+
const STATES = ['default', 'hover', 'focus'];
21+
22+
const SubSectionBaseElement: TemplateOnlyComponent = <template>
23+
<ShwTextH2>"Base" control</ShwTextH2>
24+
25+
<ShwTextH3>Interaction status</ShwTextH3>
26+
27+
<ShwFlex as |SF|>
28+
<SF.Item @label="Default">
29+
<HdsFormTextInputBase aria-label="default input example" />
30+
</SF.Item>
31+
<SF.Item @label="With placeholder">
32+
<HdsFormTextInputBase placeholder="Lorem ipsum dolor" />
33+
</SF.Item>
34+
<SF.Item @label="With value">
35+
<HdsFormTextInputBase
36+
@value="Lorem ipsum dolor"
37+
aria-label="text input example with value"
38+
/>
39+
</SF.Item>
40+
</ShwFlex>
41+
42+
<ShwDivider @level={{2}} />
43+
44+
<ShwTextH3>Types (native)</ShwTextH3>
45+
46+
<ShwGrid @columns={{4}} as |SG|>
47+
{{#each TYPES as |type|}}
48+
<SG.Item @label={{capitalize type}}>
49+
<HdsFormTextInputBase
50+
@type={{type}}
51+
@value={{type}}
52+
aria-label="text input example for {{type}}"
53+
/>
54+
</SG.Item>
55+
{{/each}}
56+
<SG.Item @label="Search (loading state)">
57+
<HdsFormTextInputBase
58+
@type="search"
59+
@value="search"
60+
@isLoading={{true}}
61+
aria-label="example of textinput with search/loading state"
62+
/>
63+
</SG.Item>
64+
</ShwGrid>
65+
66+
<ShwDivider @level={{2}} />
67+
68+
<ShwTextH3>States</ShwTextH3>
69+
70+
{{#let (array "base" "invalid" "readonly" "disabled") as |variants|}}
71+
{{#each variants as |variant|}}
72+
<ShwGrid @columns={{3}} as |SG|>
73+
{{#each STATES as |state|}}
74+
{{#let
75+
(and (eq variant "disabled") (eq state "focus"))
76+
as |isInvalidState|
77+
}}
78+
{{#unless isInvalidState}}
79+
<SG.Item
80+
@label="{{capitalize variant}} / {{capitalize state}}"
81+
mock-state-value={{state}}
82+
mock-state-selector="input"
83+
>
84+
<ShwFlex @direction="column" as |SF|>
85+
<SF.Item>
86+
<HdsFormTextInputBase
87+
aria-label="text input example as {{state}}"
88+
disabled={{if (eq variant "disabled") "disabled"}}
89+
readonly={{if (eq variant "readonly") "readonly"}}
90+
@isInvalid={{if (eq variant "invalid") true}}
91+
/>
92+
</SF.Item>
93+
<SF.Item>
94+
<HdsFormTextInputBase
95+
aria-label="text input example as {{state}}"
96+
placeholder="Placeholder"
97+
disabled={{if (eq variant "disabled") "disabled"}}
98+
readonly={{if (eq variant "readonly") "readonly"}}
99+
@isInvalid={{if (eq variant "invalid") true}}
100+
/>
101+
</SF.Item>
102+
<SF.Item>
103+
<HdsFormTextInputBase
104+
aria-label="text input example as {{state}}"
105+
@value="Lorem ipsum dolor"
106+
disabled={{if (eq variant "disabled") "disabled"}}
107+
readonly={{if (eq variant "readonly") "readonly"}}
108+
@isInvalid={{if (eq variant "invalid") true}}
109+
/>
110+
</SF.Item>
111+
<SF.Item>
112+
<HdsFormTextInputBase
113+
aria-label="text input example as {{state}}"
114+
@type="password"
115+
@value="Lorem ipsum dolor"
116+
disabled={{if (eq variant "disabled") "disabled"}}
117+
readonly={{if (eq variant "readonly") "readonly"}}
118+
@isInvalid={{if (eq variant "invalid") true}}
119+
/>
120+
</SF.Item>
121+
<SF.Item>
122+
<HdsFormTextInputBase
123+
aria-label="text input example as {{state}}"
124+
@type="search"
125+
@value="Lorem ipsum dolor"
126+
disabled={{if (eq variant "disabled") "disabled"}}
127+
readonly={{if (eq variant "readonly") "readonly"}}
128+
@isInvalid={{if (eq variant "invalid") true}}
129+
/>
130+
</SF.Item>
131+
<SF.Item>
132+
<HdsFormTextInputBase
133+
aria-label="text input example as {{state}}"
134+
@type="date"
135+
@value="Lorem ipsum dolor"
136+
disabled={{if (eq variant "disabled") "disabled"}}
137+
readonly={{if (eq variant "readonly") "readonly"}}
138+
@isInvalid={{if (eq variant "invalid") true}}
139+
/>
140+
</SF.Item>
141+
<SF.Item>
142+
<HdsFormTextInputBase
143+
aria-label="text input example as {{state}}"
144+
@type="time"
145+
@value="Lorem ipsum dolor"
146+
disabled={{if (eq variant "disabled") "disabled"}}
147+
readonly={{if (eq variant "readonly") "readonly"}}
148+
@isInvalid={{if (eq variant "invalid") true}}
149+
/>
150+
</SF.Item>
151+
<SF.Item>
152+
<HdsFormTextInputBase
153+
aria-label="text input example as {{state}}"
154+
@type="datetime-local"
155+
@value="Lorem ipsum dolor"
156+
disabled={{if (eq variant "disabled") "disabled"}}
157+
readonly={{if (eq variant "readonly") "readonly"}}
158+
@isInvalid={{if (eq variant "invalid") true}}
159+
/>
160+
</SF.Item>
161+
<SF.Item>
162+
<HdsFormTextInputBase
163+
aria-label="text input example as {{state}}"
164+
@type="month"
165+
disabled={{if (eq variant "disabled") "disabled"}}
166+
readonly={{if (eq variant "readonly") "readonly"}}
167+
@isInvalid={{if (eq variant "invalid") true}}
168+
/>
169+
</SF.Item>
170+
<SF.Item>
171+
<HdsFormTextInputBase
172+
aria-label="text input example as {{state}}"
173+
@type="week"
174+
disabled={{if (eq variant "disabled") "disabled"}}
175+
readonly={{if (eq variant "readonly") "readonly"}}
176+
@isInvalid={{if (eq variant "invalid") true}}
177+
/>
178+
</SF.Item>
179+
<SF.Item>
180+
<HdsFormTextInputBase
181+
aria-label="text input example as {{state}}"
182+
@type="tel"
183+
@value="1234567890"
184+
disabled={{if (eq variant "disabled") "disabled"}}
185+
readonly={{if (eq variant "readonly") "readonly"}}
186+
@isInvalid={{if (eq variant "invalid") true}}
187+
/>
188+
</SF.Item>
189+
</ShwFlex>
190+
</SG.Item>
191+
{{/unless}}
192+
{{/let}}
193+
{{/each}}
194+
</ShwGrid>
195+
{{/each}}
196+
{{/let}}
197+
198+
<ShwDivider @level={{2}} />
199+
200+
<ShwTextH3>Custom layout</ShwTextH3>
201+
202+
<ShwFlex as |SF|>
203+
<SF.Item @label="With custom layout">
204+
<div class="shw-component-form-textinput-base-custom-layout">
205+
<label for="my-custom-text-input-example">Custom label</label>
206+
<HdsFormTextInputBase
207+
id="my-custom-text-input-example"
208+
@value="Lorem ipsum dolor"
209+
/>
210+
<span
211+
class="shw-component-form-textinput-base-custom-layout__append-text"
212+
>Some content</span>
213+
</div>
214+
</SF.Item>
215+
</ShwFlex>
216+
217+
<ShwDivider @level={{2}} />
218+
219+
<ShwTextH3>Containers</ShwTextH3>
220+
221+
<ShwGrid @columns={{3}} as |SG|>
222+
{{#let (array "block" "flex" "grid") as |displays|}}
223+
{{#each displays as |display|}}
224+
<SG.Item as |SGI|>
225+
<SGI.Label>Parent with
226+
<code>display: {{display}}</code></SGI.Label>
227+
<ShwFlex @direction="column" as |SF|>
228+
<SF.Item {{style display=display}}>
229+
<HdsFormTextInputBase
230+
@value="Default width"
231+
aria-label="text input example as {{display}}"
232+
/>
233+
</SF.Item>
234+
<SF.Item {{style display=display}}>
235+
<HdsFormTextInputBase
236+
@value="Custom width"
237+
@width="248px"
238+
aria-label="text input example as {{display}}"
239+
/>
240+
</SF.Item>
241+
<SF.Item {{style display=display}}>
242+
<HdsFormTextInputBase
243+
aria-label="text input example as {{display}}"
244+
@type="date"
245+
/>
246+
</SF.Item>
247+
<SF.Item {{style display=display}}>
248+
<HdsFormTextInputBase
249+
aria-label="text input example as {{display}}"
250+
@type="time"
251+
/>
252+
</SF.Item>
253+
<SF.Item {{style display=display}}>
254+
<HdsFormTextInputBase
255+
aria-label="text input example as {{display}}"
256+
@type="datetime-local"
257+
/>
258+
</SF.Item>
259+
</ShwFlex>
260+
</SG.Item>
261+
{{/each}}
262+
{{/let}}
263+
</ShwGrid>
264+
265+
<ShwDivider />
266+
</template>;
267+
268+
export default SubSectionBaseElement;

0 commit comments

Comments
 (0)