Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Redesign text fields (#187)
Browse files Browse the repository at this point in the history
* New TextFieldInput designs

* New Select designs

* New AddressInput designs
  • Loading branch information
yagopv authored Feb 24, 2022
1 parent c986e41 commit 59b0080
Show file tree
Hide file tree
Showing 39 changed files with 2,074 additions and 1,169 deletions.
13 changes: 7 additions & 6 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module.exports = {
stories: ["../src/**/*.stories.tsx"],
stories: ['../src/**/*.stories.tsx'],
addons: [
"@storybook/addon-actions",
"@storybook/addon-links",
"@storybook/addon-docs",
"storybook-addon-react-docgen",
]
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-docs',
'storybook-addon-react-docgen',
'storybook-addon-controls',
],
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/safe-react-components",
"version": "0.9.8",
"version": "1.0.0",
"description": "Gnosis UI components",
"main": "dist/index.min.js",
"typings": "dist/index.d.ts",
Expand Down Expand Up @@ -35,10 +35,12 @@
"@babel/preset-typescript": "^7.16.0",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.0",
"@mui/x-data-grid": "4.0.2",
"@storybook/addon-actions": "^6.3.12",
"@storybook/addon-docs": "^6.3.12",
"@storybook/addon-links": "^6.3.12",
"@storybook/addon-storyshots": "^6.3.12",
"@storybook/addon-controls": "^6.4.19",
"@storybook/addons": "^6.3.12",
"@storybook/react": "^6.3.12",
"@testing-library/jest-dom": "^5.11.5",
Expand Down Expand Up @@ -70,7 +72,6 @@
"rimraf": "^3.0.2",
"storybook-addon-react-docgen": "^1.2.42",
"styled-components": "^5.3.3",
"@mui/x-data-grid": "4.0.2",
"ts-loader": "^8.2.0",
"typescript": "^4.5.0",
"url-loader": "^4.1.1",
Expand Down
4 changes: 3 additions & 1 deletion src/inputs/AddressInput/AddressInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default {

hiddenLabel: {
control: { type: 'boolean' },
defaultValue: true,
defaultValue: false,
},
disabled: {
control: { type: 'boolean' },
Expand Down Expand Up @@ -99,6 +99,8 @@ export const SimpleAddressInput = ({
<div>
<StyledText>Network Settings:</StyledText>
<Select
name="network"
label="Network"
items={networks}
activeItemId={currentNetworkPrefix}
onItemClick={(networkPrefix) => {
Expand Down
14 changes: 8 additions & 6 deletions src/inputs/AddressInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function AddressInput({
...rest
}: AddressInputProps): ReactElement {
const [isLoadingENSResolution, setIsLoadingENSResolution] = useState(false);
const [inputValue, setInputValue] = useState('');
const defaulInputValue = addPrefix(address, networkPrefix, showNetworkPrefix);
const inputRef = useRef({ value: defaulInputValue });
const throttle = useThrottle();
Expand Down Expand Up @@ -126,14 +127,14 @@ function AddressInput({
const inputPrefix = getNetworkPrefix(inputValue);
const inputWithoutPrefix = getAddressWithoutNetworkPrefix(inputValue);

// if the valid network prefix is present, we remove it from the address state
const isValidPrefix = networkPrefix === inputPrefix;
const checksumAddress = checksumValidAddress(
isValidPrefix ? inputWithoutPrefix : inputValue
);

if (isValidPrefix) {
// if the valid network prefix is present, we remove it from the address state
onChangeAddress(checksumValidAddress(inputWithoutPrefix));
} else {
onChangeAddress(checksumValidAddress(inputValue));
}
onChangeAddress(checksumAddress);
setInputValue(checksumAddress);
},
[networkPrefix, onChangeAddress]
);
Expand Down Expand Up @@ -162,6 +163,7 @@ function AddressInput({
hiddenLabel={hiddenLabel && !shrink}
disabled={disabled || isLoadingENSResolution}
onChange={onChange}
value={inputValue}
InputProps={{
...InputProps,
// if isLoading we show a custom loader adornment
Expand Down
Binary file removed src/inputs/Select/dai.png
Binary file not shown.
Binary file removed src/inputs/Select/gnosis.png
Binary file not shown.
189 changes: 119 additions & 70 deletions src/inputs/Select/index.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,16 @@
import React from 'react';
import MenuItem from '@material-ui/core/MenuItem';
import SelectMUI, {
SelectProps as SelectMuiProps,
} from '@material-ui/core/Select';
import FormControl from '@material-ui/core/FormControl';
import SelectMUI from '@material-ui/core/Select';
import FormHelperText from '@material-ui/core/FormHelperText';
import InputLabel from '@material-ui/core/InputLabel';
import styled from 'styled-components';

import { Text } from '../../dataDisplay';

const IconImg = styled.img`
width: 20px;
margin-right: 10px;
`;

const StyledSelect = styled(SelectMUI)`
background-color: ${(props) => props.theme.colors.separator};
border-radius: 5px;
height: 56px;
width: 140px;
.MuiSelect-select {
display: flex;
align-items: center;
padding-left: 15px;
}
.MuiSelect-selectMenu {
font-family: ${(props) => props.theme.fonts.fontFamily};
}
&.MuiInput-underline:hover:not(.Mui-disabled):before {
border-bottom: 2px solid ${(props) => props.theme.colors.primary};
}
&.MuiInput-underline:after {
border-bottom: 2px solid ${(props) => props.theme.colors.primary};
}
`;
import { inputLabelStyles, inputStyles, errorStyles } from '../styles';

export type SelectItem = {
id: string;
Expand All @@ -42,24 +19,37 @@ export type SelectItem = {
iconUrl?: string;
};

type Props = {
type SelectProps = {
id?: string;
name: string;
label: string;
error?: string;
helperText?: string | undefined;
showErrorsInTheLabel?: boolean | undefined;
items: Array<SelectItem>;
activeItemId: string;
onItemClick: (id: string) => void;
id?: string;
fallbackImage?: string;
};
} & Omit<SelectMuiProps, 'error'>;

function Select({
id,
name,
label,
error,
helperText,
showErrorsInTheLabel,
items,
activeItemId,
onItemClick,
id,
fallbackImage,
fullWidth,
...rest
}: Props): React.ReactElement {
}: SelectProps): React.ReactElement {
const [open, setOpen] = React.useState(false);

const hasError = !!error;

const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
onItemClick(event.target.value as string);
};
Expand All @@ -82,44 +72,103 @@ function Select({
};

return (
<div>
<FormControl>
<StyledSelect
labelId={id ? id : 'generic-select'}
id={id ? id : 'generic-select'}
open={open}
onClose={handleClose}
onOpen={handleOpen}
value={activeItemId}
onChange={handleChange}
{...rest}>
{items.map((i) => {
return (
<MenuItem value={i.id} key={i.id}>
{i.iconUrl && (
<IconImg
alt={i.label}
onError={onFallbackImage}
src={i.iconUrl}
/>
)}
<div>
<Text size="sm" color="text">
{i.label}
<StyledFormControl variant="outlined" fullWidth={fullWidth}>
<InputLabel error={!!error}>
{showErrorsInTheLabel && hasError ? error : label}
</InputLabel>
<StyledSelect
id={id}
name={name}
labelId={id}
error={hasError}
open={open}
onClose={handleClose}
onOpen={handleOpen}
value={activeItemId}
onChange={handleChange}
label={id ? id : 'generic-select'}
variant="outlined"
{...rest}>
{items.map((i) => {
return (
<MenuItem value={i.id} key={i.id}>
{i.iconUrl && (
<IconImg
alt={i.label}
onError={onFallbackImage}
src={i.iconUrl}
/>
)}
<div>
<Text size="sm" color="text">
{i.label}
</Text>
{i.subLabel && (
<Text size="sm" color="secondary" strong>
{i.subLabel}
</Text>
{i.subLabel && (
<Text size="sm" color="secondary" strong>
{i.subLabel}
</Text>
)}
</div>
</MenuItem>
);
})}
</StyledSelect>
</FormControl>
</div>
)}
</div>
</MenuItem>
);
})}
</StyledSelect>
{(helperText || (error && showErrorsInTheLabel)) && (
<StyledFormHelperText error={hasError && !showErrorsInTheLabel}>
{helperText || error}
</StyledFormHelperText>
)}
</StyledFormControl>
);
}

const IconImg = styled.img`
width: 20px;
margin-right: 10px;
`;

const StyledSelect = styled(SelectMUI)`
&& {
.MuiSelect-root {
background: #fff;
}
.MuiSelect-select {
display: flex;
align-items: center;
padding-left: 15px;
}
.MuiSelect-selectMenu {
font-family: ${(props) => props.theme.fonts.fontFamily};
}
&& {
fieldset {
border: 1px solid
${({ theme, value, error }) =>
error
? theme.colors.error
: value
? theme.colors.inputFilled
: theme.colors.inputDisabled};
}
}
}
`;

const StyledFormControl = styled(FormControl)`
&& {
${inputLabelStyles}
${inputStyles}
${errorStyles}
}
`;

const StyledFormHelperText = styled(FormHelperText)`
&& {
font-family: ${(props) => props.theme.fonts.fontFamily};
}
`;

export default Select;
Loading

0 comments on commit 59b0080

Please sign in to comment.