Skip to content

Commit 756c2aa

Browse files
authored
Merge pull request #3913 from LiteFarmOrg/LF-5028-refactor-input-to-use-input-base-label-and-adjust-label-styles-2
LF-5028 Refactor <Input /> to use <InputBaseLabel /> and adjust Optional styles
2 parents b791c43 + d4b703f commit 756c2aa

File tree

25 files changed

+340
-274
lines changed

25 files changed

+340
-274
lines changed

packages/webapp/public/locales/en/common.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"NOT_SURE": "Not sure",
6767
"NOTES": "Notes",
6868
"OK": "OK",
69-
"OPTIONAL": "(optional)",
69+
"OPTIONAL": "Optional",
7070
"OR": "or",
7171
"ORGANIC": "Organic",
7272
"OTHER": "Other",

packages/webapp/public/locales/en/translation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,9 @@
19171917
"WRONG_BROWSER": "LiteFarm is not optimized for this browser.",
19181918
"WRONG_BROWSER_BOTTOM": "Please login using Chrome."
19191919
},
1920+
"SIMPLE_BADGE": {
1921+
"PRIVATE": "Private"
1922+
},
19201923
"SLIDE_MENU": {
19211924
"CROPS": "Crops",
19221925
"DOCUMENTS": "Documents",

packages/webapp/src/components/Form/Input/index.tsx

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import clsx from 'clsx';
2626
import i18n from '../../../locales/i18n';
2727
import styles from './input.module.scss';
2828
import { mergeRefs } from '../utils';
29-
import { Error, Info, Label, TextWithExternalLink } from '../../Typography';
29+
import { Error, Info, TextWithExternalLink } from '../../Typography';
30+
import InputBaseLabel from '../InputBase/InputBaseLabel';
3031
import { Cross } from '../../Icons';
3132
import {
3233
MdVisibility,
@@ -37,8 +38,6 @@ import {
3738
import { ReactComponent as SearchIcon } from '../../../assets/images/search.svg';
3839
import { ReactComponent as SearchClearIcon } from '../../../assets/images/search-close.svg';
3940
import TextButton from '../Button/TextButton';
40-
import { ReactComponent as Leaf } from '../../../assets/images/signUp/leaf.svg';
41-
import Infoi from '../../Tooltip/Infoi';
4241
import useElementWidth from '../../hooks/useElementWidth';
4342

4443
interface InputClasses {
@@ -195,45 +194,35 @@ const Input = ({
195194
style={(style || classes.container) && { ...style, ...classes.container }}
196195
>
197196
{(label || toolTipContent || icon) && (
198-
<div className={styles.labelContainer}>
199-
<Label style={{ position: 'absolute', bottom: 0 }}>
200-
{label}
201-
{optional && (
202-
<Label sm className={styles.sm} style={{ marginLeft: '4px' }}>
203-
{t('common:OPTIONAL')}
204-
</Label>
205-
)}
206-
{hasLeaf && <Leaf className={styles.leaf} />}
207-
</Label>
208-
{toolTipContent && (
209-
<div className={styles.tooltipIconContainer}>
210-
<Infoi content={toolTipContent} />
211-
</div>
212-
)}
213-
{icon && <span className={styles.icon}>{icon}</span>}
214-
</div>
215-
)}
216-
{isPassword &&
217-
!showError &&
218-
(showPassword ? (
219-
<MdVisibility
220-
aria-label="hide-password"
221-
className={styles.visibilityIcon}
222-
onClick={setVisibility}
223-
/>
224-
) : (
225-
<MdVisibilityOff
226-
aria-label="show-password"
227-
className={styles.visibilityIcon}
228-
onClick={setVisibility}
229-
/>
230-
))}
231-
{currency && (
232-
<div ref={currencyRef} className={styles.currency}>
233-
{currency}
234-
</div>
197+
<InputBaseLabel
198+
label={label}
199+
optional={optional}
200+
hasLeaf={hasLeaf}
201+
toolTipContent={toolTipContent}
202+
icon={icon}
203+
/>
235204
)}
236205
<div className={styles.inputWrapper}>
206+
{isPassword &&
207+
!showError &&
208+
(showPassword ? (
209+
<MdVisibility
210+
aria-label="hide-password"
211+
className={styles.visibilityIcon}
212+
onClick={setVisibility}
213+
/>
214+
) : (
215+
<MdVisibilityOff
216+
aria-label="show-password"
217+
className={styles.visibilityIcon}
218+
onClick={setVisibility}
219+
/>
220+
))}
221+
{currency && (
222+
<div ref={currencyRef} className={styles.currency}>
223+
{currency}
224+
</div>
225+
)}
237226
{unit && <div className={styles.unit}>{unit}</div>}
238227
{showError && !unit && showCross && (
239228
<Cross
@@ -310,12 +299,13 @@ const Input = ({
310299
</div>
311300
)}
312301
{isSearchBar && input?.current?.value && (
313-
<TextButton onClick={onClear}>
302+
<TextButton onClick={onClear} className={styles.searchClearButton}>
314303
<SearchClearIcon className={styles.searchClearIcon} />
315304
</TextButton>
316305
)}
306+
{isSearchBar && <SearchIcon className={styles.searchIcon} />}
317307
</div>
318-
{isSearchBar && <SearchIcon className={styles.searchIcon} />}
308+
319309
{info && !showError && <Info style={classes.info}>{info}</Info>}
320310
{showError ? (
321311
<Error data-cy="error" style={classes.errors}>

packages/webapp/src/components/Form/Input/input.module.scss

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
@import '@assets/mixin.scss';
22

3+
.container {
4+
display: flex;
5+
flex-direction: column;
6+
overflow: visible;
7+
position: relative;
8+
min-width: 0;
9+
}
10+
11+
.inputWrapper {
12+
position: relative;
13+
width: 100%;
14+
display: flex;
15+
align-items: center;
16+
}
17+
318
.input {
419
width: 100%;
520
border: 1px solid var(--grey400);
@@ -52,14 +67,6 @@ input:focus::placeholder {
5267
flex-grow: 1;
5368
}
5469

55-
.container {
56-
display: flex;
57-
flex-direction: column;
58-
overflow: visible;
59-
position: relative;
60-
min-width: 0;
61-
}
62-
6370
.inputError {
6471
border-color: var(--error);
6572
}
@@ -69,34 +76,23 @@ input:focus::placeholder {
6976
border-color: var(--inputActive);
7077
}
7178

72-
.icon {
73-
position: absolute;
74-
right: 0;
75-
top: -8px;
76-
color: var(--iconDefault);
77-
}
78-
79-
.icon > * {
80-
cursor: pointer;
81-
}
82-
.sm {
83-
margin-left: 8px;
84-
}
85-
8679
.searchIcon {
8780
width: 22px;
8881
height: 22px;
8982
position: absolute;
9083
left: 11px;
91-
top: 13px;
84+
}
85+
86+
.searchClearButton {
87+
display: inline-flex;
88+
align-items: center;
9289
}
9390

9491
.searchClearIcon {
9592
width: 17px;
9693
height: 17px;
9794
position: absolute;
9895
right: 12px;
99-
top: 15px;
10096
}
10197

10298
.searchBar {
@@ -105,43 +101,27 @@ input:focus::placeholder {
105101

106102
.visibilityIcon {
107103
position: absolute;
108-
right: 0;
109-
transform: translate(-8px, 32px);
104+
right: 8px;
110105
font-size: 22px;
111106
color: var(--iconDefault);
112107
cursor: pointer;
113108
z-index: 1;
114109
}
115110

116-
.labelContainer {
117-
display: flex;
118-
justify-content: space-between;
119-
min-height: 20px;
120-
position: relative;
121-
}
122-
123111
.unit {
124112
font-size: 16px;
125-
line-height: 20px;
126113
color: var(--labels);
127-
font-style: normal;
128-
font-weight: normal;
129114
@include fontFamily();
130115
position: absolute;
131-
right: 0;
132-
transform: translate(-8px, 14px);
116+
right: 8px;
133117
}
134118

135119
.currency {
136120
font-size: 16px;
137-
line-height: 20px;
138121
color: var(--labels);
139-
font-style: normal;
140-
font-weight: normal;
141122
@include fontFamily();
142123
position: absolute;
143-
left: 0;
144-
transform: translate(8px, 34px);
124+
left: 8px;
145125
z-index: 1; // otherwise hidden behind the disabled background color
146126
}
147127

@@ -156,12 +136,6 @@ input:focus::placeholder {
156136
justify-content: flex-end;
157137
}
158138

159-
/* Wrapper for Input + stepper buttons */
160-
.inputWrapper {
161-
position: relative;
162-
width: 100%;
163-
}
164-
165139
.stepper {
166140
display: flex;
167141
flex-flow: column nowrap;
@@ -199,7 +173,6 @@ input:focus::placeholder {
199173
.clearIcon {
200174
position: absolute;
201175
right: 17px;
202-
top: -5px;
203176
cursor: pointer;
204177
z-index: 1;
205178

packages/webapp/src/components/Form/InputAutoSize/index.jsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,11 @@ export default function InputAutoSize({
3232
style={(style || classes.container) && { ...style, ...classes.container }}
3333
>
3434
{label && (
35-
<Label>
36-
{label}
37-
{optional && (
38-
<Label sm className={styles.sm} style={{ marginLeft: '4px' }}>
39-
{t('common:OPTIONAL')}
40-
</Label>
41-
)}
42-
</Label>
35+
<div className={styles.labelContainer}>
36+
<Label>{label}</Label>
37+
{optional && <Label sm>{t('common:OPTIONAL')}</Label>}
38+
</div>
4339
)}
44-
4540
<TextareaAutosize
4641
maxRows={maxRows}
4742
minRows={minRows}

packages/webapp/src/components/Form/InputAutoSize/styles.module.scss

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@
2222
position: relative;
2323
}
2424

25-
.sm {
26-
margin-left: 8px;
25+
.labelContainer {
26+
display: flex;
27+
justify-content: space-between;
28+
align-items: baseline;
29+
margin-bottom: 4px;
30+
31+
h5,
32+
span {
33+
margin-bottom: 0;
34+
}
2735
}
2836

2937
.inputError {
@@ -40,4 +48,3 @@
4048
color: var(--grey600);
4149
border-color: var(--inputDefault);
4250
}
43-

packages/webapp/src/components/Form/InputBase/InputBaseLabel/index.tsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
* GNU General Public License for more details, see <https://www.gnu.org/licenses/>.
1414
*/
1515

16+
import { useTranslation } from 'react-i18next';
17+
import { ReactNode } from 'react';
18+
import clsx from 'clsx';
1619
import Infoi from '../../../Tooltip/Infoi';
1720
import { ReactComponent as Leaf } from '../../../../assets/images/signUp/leaf.svg';
1821
import { Label } from '../../../Typography';
1922
import styles from './styles.module.scss';
20-
import { useTranslation } from 'react-i18next';
21-
import { ReactNode } from 'react';
2223

2324
export type InputBaseLabelProps = {
2425
label?: string;
@@ -27,28 +28,25 @@ export type InputBaseLabelProps = {
2728
toolTipContent?: string;
2829
icon?: ReactNode;
2930
labelStyles?: React.CSSProperties;
31+
leftJustified?: boolean;
3032
};
3133

3234
export default function InputBaseLabel(props: InputBaseLabelProps) {
3335
const { t } = useTranslation();
3436

3537
return (
36-
<div className={styles.labelContainer}>
38+
<div className={clsx(styles.labelContainer, props.leftJustified && styles.leftJustified)}>
3739
<Label style={props.labelStyles}>
3840
{props.label}
39-
{props.optional && (
40-
<Label sm className={styles.sm}>
41-
{t('common:OPTIONAL')}
42-
</Label>
43-
)}
4441
{props.hasLeaf && <Leaf className={styles.leaf} />}
4542
</Label>
46-
{props.toolTipContent && (
47-
<div className={styles.tooltipIconContainer}>
48-
<Infoi content={props.toolTipContent} />
49-
</div>
50-
)}
51-
{props.icon && <span className={styles.icon}>{props.icon}</span>}
43+
<div className={styles.rightContent}>
44+
{props.toolTipContent && (
45+
<Infoi content={props.toolTipContent} className={styles.tooltipIcon} />
46+
)}
47+
{props.icon && <span className={styles.icon}>{props.icon}</span>}
48+
{props.optional && <Label sm>{t('common:OPTIONAL')}</Label>}
49+
</div>
5250
</div>
5351
);
5452
}

0 commit comments

Comments
 (0)