Skip to content

Commit 05d1e35

Browse files
authored
feat: implement style api for input component (#3992)
1 parent d42724b commit 05d1e35

File tree

11 files changed

+863
-56
lines changed

11 files changed

+863
-56
lines changed

build-tools/utils/custom-css-properties.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,21 @@ const customCssPropertiesList = [
9595
'styleBoxShadowDefault',
9696
'styleBoxShadowDisabled',
9797
'styleBoxShadowHover',
98+
// Readonly state
99+
'styleBackgroundReadonly',
100+
'styleBorderColorReadonly',
101+
'styleBoxShadowReadonly',
102+
'styleColorReadonly',
103+
// Focus state
104+
'styleBackgroundFocus',
105+
'styleBorderColorFocus',
106+
'styleBoxShadowFocus',
107+
'styleColorFocus',
108+
// Placeholder style properties
109+
'stylePlaceholderColor',
110+
'stylePlaceholderFontSize',
111+
'stylePlaceholderFontStyle',
112+
'stylePlaceholderFontWeight',
98113
// Alert focus ring properties
99114
'alertFocusRingBorderColor',
100115
'alertFocusRingBorderRadius',

pages/input/input-integ.page.tsx

Lines changed: 104 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,111 @@ export default function Page() {
99
const [submitStatus, setSubmitStatus] = useState(false);
1010
const [isKeyboardSubmittingDisabled, setDisableKeyboardSubmitting] = useState(false);
1111

12+
// State for styleable input
13+
const [styleableValue, setStyleableValue] = useState('Test value');
14+
const [isInvalid, setIsInvalid] = useState(false);
15+
const [isDisabled, setIsDisabled] = useState(false);
16+
const [isReadOnly, setIsReadOnly] = useState(false);
17+
const [isWarning, setIsWarning] = useState(false);
18+
1219
return (
13-
<div id="test">
14-
<h1>Input submit check</h1>
15-
{submitStatus ? <div id="submit-success">Submitted</div> : null}
16-
<form
17-
onSubmit={event => {
18-
console.log('submitted');
19-
event.preventDefault();
20-
setSubmitStatus(true);
21-
}}
22-
>
23-
<Input
24-
ariaLabel="test input"
25-
type="number"
26-
step={0.2}
27-
value={value}
28-
onChange={event => setValue(event.detail.value)}
29-
onKeyDown={event => {
30-
if (isKeyboardSubmittingDisabled) {
31-
console.log('prevent!');
32-
event.preventDefault();
33-
event.stopPropagation();
34-
}
20+
<>
21+
<div id="test">
22+
<h1>Input submit check</h1>
23+
{submitStatus ? <div id="submit-success">Submitted</div> : null}
24+
<form
25+
onSubmit={event => {
26+
console.log('submitted');
27+
event.preventDefault();
28+
setSubmitStatus(true);
3529
}}
36-
/>
37-
<button id="disable-form-submitting" onClick={() => setDisableKeyboardSubmitting(true)} type="button">
38-
Disable keyboard form submitting
39-
</button>
40-
</form>
41-
</div>
30+
>
31+
<Input
32+
ariaLabel="test input"
33+
type="number"
34+
step={0.2}
35+
value={value}
36+
onChange={event => setValue(event.detail.value)}
37+
onKeyDown={event => {
38+
if (isKeyboardSubmittingDisabled) {
39+
console.log('prevent!');
40+
event.preventDefault();
41+
event.stopPropagation();
42+
}
43+
}}
44+
/>
45+
<button id="disable-form-submitting" onClick={() => setDisableKeyboardSubmitting(true)} type="button">
46+
Disable keyboard form submitting
47+
</button>
48+
</form>
49+
</div>
50+
51+
<div id="styleable-input-test">
52+
<h1>Input Style API with State Toggles</h1>
53+
<div style={{ marginBottom: '20px' }}>
54+
<Input
55+
ariaLabel="Styleable test input"
56+
value={styleableValue}
57+
onChange={event => setStyleableValue(event.detail.value)}
58+
invalid={isInvalid}
59+
disabled={isDisabled}
60+
readOnly={isReadOnly}
61+
warning={isWarning}
62+
placeholder="Enter text"
63+
data-testid="styleable-input"
64+
style={{
65+
root: {
66+
borderColor: {
67+
default: '#3b82f6',
68+
hover: '#2563eb',
69+
focus: '#1d4ed8',
70+
disabled: '#93c5fd',
71+
readonly: '#60a5fa',
72+
},
73+
borderWidth: '2px',
74+
borderRadius: '8px',
75+
backgroundColor: {
76+
default: '#dbeafe',
77+
hover: '#bfdbfe',
78+
focus: '#bfdbfe',
79+
disabled: '#eff6ff',
80+
readonly: '#f0f9ff',
81+
},
82+
color: {
83+
default: '#1e40af',
84+
hover: '#1e40af',
85+
focus: '#1e3a8a',
86+
disabled: '#93c5fd',
87+
readonly: '#3b82f6',
88+
},
89+
fontSize: '16px',
90+
fontWeight: '500',
91+
paddingBlock: '10px',
92+
paddingInline: '14px',
93+
},
94+
placeholder: {
95+
color: '#60a5fa',
96+
fontSize: '14px',
97+
fontStyle: 'italic',
98+
},
99+
}}
100+
/>
101+
</div>
102+
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
103+
<button id="toggle-invalid" onClick={() => setIsInvalid(!isInvalid)} type="button">
104+
Toggle Invalid ({isInvalid ? 'ON' : 'OFF'})
105+
</button>
106+
<button id="toggle-disabled" onClick={() => setIsDisabled(!isDisabled)} type="button">
107+
Toggle Disabled ({isDisabled ? 'ON' : 'OFF'})
108+
</button>
109+
<button id="toggle-readonly" onClick={() => setIsReadOnly(!isReadOnly)} type="button">
110+
Toggle ReadOnly ({isReadOnly ? 'ON' : 'OFF'})
111+
</button>
112+
<button id="toggle-warning" onClick={() => setIsWarning(!isWarning)} type="button">
113+
Toggle Warning ({isWarning ? 'ON' : 'OFF'})
114+
</button>
115+
</div>
116+
</div>
117+
</>
42118
);
43119
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import Input, { InputProps } from '~components/input';
6+
7+
import createPermutations from '../utils/permutations';
8+
import PermutationsView from '../utils/permutations-view';
9+
import ScreenshotArea from '../utils/screenshot-area';
10+
11+
const permutations = createPermutations<InputProps>([
12+
{
13+
value: ['This is an example value'],
14+
placeholder: [''],
15+
disabled: [false, true],
16+
readOnly: [false, true],
17+
onChange: [() => {}],
18+
style: [
19+
{
20+
root: {
21+
borderColor: {
22+
default: '#14b8a6',
23+
hover: '#0f766e',
24+
focus: '#0d9488',
25+
disabled: '#99f6e4',
26+
readonly: '#5eead4',
27+
},
28+
borderWidth: '2px',
29+
borderRadius: '8px',
30+
backgroundColor: {
31+
default: '#99f6e4',
32+
hover: '#5eead4',
33+
focus: '#5eead4',
34+
disabled: '#5eead4',
35+
readonly: '#ccfbf1',
36+
},
37+
boxShadow: {
38+
default: '0 1px 2px rgba(0, 0, 0, 0.05)',
39+
hover: '0 2px 4px rgba(20, 184, 166, 0.15)',
40+
focus: '0 0 0 4px rgba(20, 184, 166, 0.2), 0 2px 4px rgba(20, 184, 166, 0.15)',
41+
disabled: 'none',
42+
readonly: '0 1px 2px rgba(0, 0, 0, 0.05)',
43+
},
44+
color: {
45+
default: '#0d5c54',
46+
hover: '#0d5c54',
47+
focus: '#0d5c54',
48+
disabled: '#0d5c54',
49+
readonly: '#0f766e',
50+
},
51+
fontSize: '16px',
52+
fontWeight: '500',
53+
paddingBlock: '12px',
54+
paddingInline: '16px',
55+
},
56+
placeholder: {
57+
color: '#14b8a6',
58+
fontSize: '14px',
59+
fontStyle: 'italic',
60+
fontWeight: '400',
61+
},
62+
},
63+
{
64+
root: {
65+
borderColor: {
66+
default: '#ef4444',
67+
hover: '#b91c1c',
68+
focus: '#dc2626',
69+
disabled: '#fca5a5',
70+
readonly: '#fca5a5',
71+
},
72+
borderWidth: '2px',
73+
borderRadius: '8px',
74+
backgroundColor: {
75+
default: '#fecaca',
76+
hover: '#fca5a5',
77+
focus: '#fca5a5',
78+
disabled: '#fca5a5',
79+
readonly: '#fee2e2',
80+
},
81+
boxShadow: {
82+
default: '0 1px 2px rgba(0, 0, 0, 0.05)',
83+
hover: '0 2px 4px rgba(239, 68, 68, 0.15)',
84+
focus: '0 0 0 4px rgba(239, 68, 68, 0.2), 0 2px 4px rgba(239, 68, 68, 0.15)',
85+
disabled: 'none',
86+
readonly: '0 1px 2px rgba(0, 0, 0, 0.05)',
87+
},
88+
color: {
89+
default: '#7f1d1d',
90+
hover: '#7f1d1d',
91+
focus: '#7f1d1d',
92+
disabled: '#7f1d1d',
93+
readonly: '#991b1b',
94+
},
95+
},
96+
},
97+
{
98+
root: {
99+
borderColor: {
100+
default: '#f59e0b',
101+
hover: '#b45309',
102+
focus: '#d97706',
103+
disabled: '#fcd34d',
104+
readonly: '#fcd34d',
105+
},
106+
borderWidth: '2px',
107+
borderRadius: '16px',
108+
backgroundColor: {
109+
default: '#fde68a',
110+
hover: '#fcd34d',
111+
focus: '#fcd34d',
112+
disabled: '#fcd34d',
113+
readonly: '#fef3c7',
114+
},
115+
boxShadow: {
116+
default: '0 2px 8px rgba(245, 158, 11, 0.15)',
117+
hover: '0 6px 16px rgba(245, 158, 11, 0.25)',
118+
focus: '0 0 0 4px rgba(245, 158, 11, 0.25), 0 6px 16px rgba(245, 158, 11, 0.3)',
119+
disabled: 'none',
120+
readonly: '0 2px 8px rgba(245, 158, 11, 0.15)',
121+
},
122+
color: {
123+
default: '#78350f',
124+
hover: '#78350f',
125+
focus: '#78350f',
126+
disabled: '#78350f',
127+
readonly: '#92400e',
128+
},
129+
},
130+
},
131+
{
132+
root: {
133+
borderColor: {
134+
default: '#10b981',
135+
hover: '#047857',
136+
focus: '#059669',
137+
disabled: '#6ee7b7',
138+
readonly: '#6ee7b7',
139+
},
140+
borderWidth: '3px',
141+
borderRadius: '0px',
142+
backgroundColor: {
143+
default: '#d1fae5',
144+
hover: '#a7f3d0',
145+
focus: '#a7f3d0',
146+
disabled: '#a7f3d0',
147+
readonly: '#ecfdf5',
148+
},
149+
boxShadow: {
150+
default: '0 1px 2px rgba(0, 0, 0, 0.05)',
151+
hover: '0 2px 4px rgba(16, 185, 129, 0.1)',
152+
focus: '0 0 0 4px rgba(16, 185, 129, 0.2), 0 2px 4px rgba(16, 185, 129, 0.15)',
153+
disabled: 'none',
154+
readonly: '0 1px 2px rgba(0, 0, 0, 0.05)',
155+
},
156+
color: {
157+
default: '#064e3b',
158+
hover: '#064e3b',
159+
focus: '#064e3b',
160+
disabled: '#064e3b',
161+
readonly: '#065f46',
162+
},
163+
},
164+
},
165+
],
166+
},
167+
]);
168+
169+
export default function InputStylePermutations() {
170+
return (
171+
<>
172+
<h1>Input Style permutations</h1>
173+
<ScreenshotArea disableAnimations={true}>
174+
<PermutationsView
175+
permutations={permutations}
176+
render={permutation => <Input ariaLabel="Input field" {...permutation} />}
177+
/>
178+
</ScreenshotArea>
179+
</>
180+
);
181+
}

0 commit comments

Comments
 (0)