-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #822 from safe-global/chore/move-react-components-…
…to-tx-builder chore(tx-builder-theme): move safe react components to TX-builder components folder
- Loading branch information
Showing
30 changed files
with
2,505 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { ReactElement } from 'react' | ||
import AccordionMUI, { AccordionProps as AccordionMUIProps } from '@material-ui/core/Accordion' | ||
import AccordionSummaryMUI, { | ||
AccordionSummaryProps as AccordionSummaryMUIProps, | ||
} from '@material-ui/core/AccordionSummary' | ||
import styled from 'styled-components' | ||
import FixedIcon from '../FixedIcon' | ||
|
||
type AccordionProps = AccordionMUIProps & { | ||
compact?: boolean | ||
} | ||
|
||
type StyledAccordionProps = AccordionMUIProps & { | ||
$compact?: AccordionProps['compact'] | ||
} | ||
|
||
const StyledAccordion = styled(AccordionMUI)<StyledAccordionProps>` | ||
&.MuiAccordion-root { | ||
border-radius: ${({ $compact }) => ($compact ? '8px' : '0')}; | ||
border: ${({ $compact, theme }) => ($compact ? '2px solid ' + theme.palette.divider : 'none')}; | ||
border-bottom: 2px solid ${({ theme }) => theme.palette.divider}; | ||
margin-bottom: ${({ $compact }) => ($compact ? '16px' : '0')}; | ||
overflow: hidden; | ||
&:before { | ||
height: 0; | ||
} | ||
&:first-child { | ||
border-top: 2px solid ${({ theme }) => theme.palette.divider}; | ||
} | ||
&.Mui-expanded { | ||
margin: ${({ $compact }) => ($compact ? '0 0 16px 0' : '0')}; | ||
} | ||
.MuiAccordionDetails-root { | ||
padding: 16px; | ||
} | ||
} | ||
` | ||
|
||
const StyledAccordionSummary = styled(AccordionSummaryMUI)` | ||
&.MuiAccordionSummary-root { | ||
&.Mui-expanded { | ||
min-height: 48px; | ||
border-bottom: 2px solid ${({ theme }) => theme.palette.divider}; | ||
background-color: ${({ theme }) => theme.palette.background.default}; | ||
} | ||
&:hover { | ||
background-color: ${({ theme }) => theme.palette.background.default}; | ||
} | ||
.MuiAccordionSummary-content { | ||
&.Mui-expanded { | ||
margin: 0; | ||
} | ||
} | ||
.MuiIconButton-root { | ||
font-size: 0; | ||
padding: 16px; | ||
} | ||
} | ||
` | ||
|
||
export const Accordion = ({ compact, children, ...props }: AccordionProps): ReactElement => { | ||
return ( | ||
<StyledAccordion square elevation={0} $compact={compact} {...props}> | ||
{children} | ||
</StyledAccordion> | ||
) | ||
} | ||
|
||
export const AccordionSummary = ({ | ||
children, | ||
...props | ||
}: AccordionSummaryMUIProps): ReactElement => { | ||
return ( | ||
<StyledAccordionSummary expandIcon={<FixedIcon type="chevronDown" />} {...props}> | ||
{children} | ||
</StyledAccordionSummary> | ||
) | ||
} | ||
|
||
export { default as AccordionActions } from '@material-ui/core/AccordionActions' | ||
export { default as AccordionDetails } from '@material-ui/core/AccordionDetails' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
import React, { ReactElement, ReactNode, HTMLAttributes } from 'react' | ||
import ButtonMUI, { ButtonProps as ButtonMUIProps } from '@material-ui/core/Button' | ||
import { alpha } from '@material-ui/core/styles' | ||
|
||
import styled, { css, DefaultTheme, FlattenInterpolation, ThemeProps } from 'styled-components' | ||
import { Icon, IconProps, IconTypes } from './Icon' | ||
|
||
type Colors = 'primary' | 'secondary' | 'error' | ||
type Variations = 'bordered' | 'contained' | 'outlined' | ||
|
||
type CustomButtonMuiProps = Omit<ButtonMUIProps, 'size' | 'color' | 'variant'> & { | ||
to?: string | ||
component?: ReactNode | ||
} | ||
type LocalProps = { | ||
children?: ReactNode | ||
color?: Colors | ||
variant?: Variations | ||
iconType?: IconProps['type'] | ||
iconSize?: IconProps['size'] | ||
} | ||
|
||
type Props = LocalProps & CustomButtonMuiProps & HTMLAttributes<HTMLButtonElement> | ||
|
||
const StyledIcon = styled(Icon)<IconProps>` | ||
margin-right: 5px; | ||
` | ||
|
||
const customStyles: { | ||
[key in Colors]: { | ||
[key in Variations]: FlattenInterpolation<ThemeProps<DefaultTheme>> | ||
} | ||
} = { | ||
primary: { | ||
contained: css` | ||
color: ${({ theme }) => theme.palette.common.white}; | ||
background-color: ${({ theme }) => theme.palette.primary.main}; | ||
box-shadow: 1px 2px 10px ${alpha('#28363D', 0.18)}; | ||
&:hover { | ||
color: ${({ theme }) => theme.palette.common.white}; | ||
background-color: ${({ theme }) => theme.palette.primary.dark}; | ||
} | ||
`, | ||
outlined: css` | ||
color: ${({ theme }) => theme.palette.primary.main}; | ||
background-color: transparent; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.primary.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.primary.main}; | ||
} | ||
&:hover { | ||
color: ${({ theme }) => theme.palette.primary.dark}; | ||
} | ||
`, | ||
bordered: css` | ||
color: ${({ theme }) => theme.palette.primary.main}; | ||
background-color: transparent; | ||
border: 2px solid ${({ theme }) => theme.palette.primary.main}; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.primary.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.primary.main}; | ||
} | ||
`, | ||
}, | ||
secondary: { | ||
contained: css` | ||
color: ${({ theme }) => theme.palette.primary}; | ||
background-color: ${({ theme }) => theme.palette.secondary.main}; | ||
box-shadow: 1px 2px 10px ${alpha('#28363D', 0.18)}; | ||
path.icon-color { | ||
color: ${({ theme }) => theme.palette.common.primary}; | ||
} | ||
&:hover { | ||
path.icon-color { | ||
color: ${({ theme }) => theme.palette.common.primary}; | ||
} | ||
background-color: ${({ theme }) => theme.palette.secondary.dark}; | ||
} | ||
`, | ||
outlined: css` | ||
color: ${({ theme }) => theme.palette.secondary.main}; | ||
background-color: transparent; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.secondary.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.secondary.main}; | ||
} | ||
`, | ||
bordered: css` | ||
color: ${({ theme }) => theme.palette.secondary.main}; | ||
background-color: transparent; | ||
border: 2px solid ${({ theme }) => theme.palette.secondary.main}; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.secondary.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.secondary.main}; | ||
} | ||
`, | ||
}, | ||
error: { | ||
contained: css` | ||
color: ${({ theme }) => theme.palette.common.white}; | ||
background-color: ${({ theme }) => theme.palette.error.main}; | ||
box-shadow: 1px 2px 10px ${alpha('#28363D', 0.18)}; | ||
&:hover { | ||
background-color: ${({ theme }) => theme.palette.error.dark}; | ||
} | ||
`, | ||
outlined: css` | ||
color: ${({ theme }) => theme.palette.error.main}; | ||
background-color: transparent; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.error.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.error.main}; | ||
} | ||
`, | ||
bordered: css` | ||
color: ${({ theme }) => theme.palette.error.main}; | ||
background-color: transparent; | ||
border: 2px solid ${({ theme }) => theme.palette.error.main}; | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.error.main}; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.error.main}; | ||
} | ||
`, | ||
}, | ||
} | ||
|
||
const StyledButton = styled(ButtonMUI)<{ $localProps: LocalProps }>` | ||
&& { | ||
font-weight: 700; | ||
padding: 8px 1.4rem; | ||
min-width: 120px; | ||
&.MuiButton-root { | ||
text-transform: none; | ||
border-radius: 8px; | ||
letter-spacing: 0; | ||
} | ||
&.Mui-disabled { | ||
color: ${({ theme }) => theme.palette.common.white}; | ||
} | ||
path.icon-color { | ||
fill: ${({ theme }) => theme.palette.common.white}; | ||
} | ||
&:disabled { | ||
opacity: 0.5; | ||
} | ||
${({ $localProps }) => { | ||
if ($localProps.color !== undefined && $localProps.variant !== undefined) { | ||
return customStyles[$localProps.color][$localProps.variant] | ||
} | ||
}} | ||
} | ||
` | ||
|
||
const Button = ({ | ||
children, | ||
color = 'primary', | ||
variant = 'contained', | ||
iconType, | ||
iconSize, | ||
// We need destructuring all LocalProps, remaining props are for CustomButtonMuiProps | ||
...buttonMuiProps | ||
}: Props): ReactElement => { | ||
return ( | ||
<StyledButton | ||
className={`${color} ${variant}`} | ||
{...buttonMuiProps} | ||
$localProps={{ color, variant }} | ||
> | ||
{iconType && iconSize && <StyledIcon size={iconSize} type={iconType} />} | ||
{children} | ||
</StyledButton> | ||
) | ||
} | ||
|
||
export default Button |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
import { alpha } from '@material-ui/core/styles' | ||
|
||
const StyledCard = styled.div` | ||
box-shadow: 1px 2px 10px 0 ${alpha('#28363D', 0.18)}; | ||
border-radius: 8px; | ||
padding: 24px; | ||
background-color: ${({ theme }) => theme.palette.common.white}; | ||
position: relative; | ||
` | ||
|
||
const Disabled = styled.div` | ||
opacity: 0.5; | ||
position: absolute; | ||
height: 100%; | ||
width: 100%; | ||
background-color: ${({ theme }) => theme.palette.common.white}; | ||
z-index: 1; | ||
top: 0; | ||
left: 0; | ||
` | ||
|
||
type Props = { | ||
className?: string | ||
disabled?: boolean | ||
} & React.HTMLAttributes<HTMLDivElement> | ||
|
||
const Card: React.FC<Props> = ({ className, children, disabled, ...rest }): React.ReactElement => ( | ||
<StyledCard className={className} {...rest}> | ||
{disabled && <Disabled />} | ||
{children} | ||
</StyledCard> | ||
) | ||
|
||
export default Card |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
|
||
type Props = { | ||
className?: string | ||
orientation?: 'vertical' | 'horizontal' | ||
} | ||
|
||
const HorizontalDivider = styled.div` | ||
margin: 16px -1.6rem; | ||
border-top: solid 1px #dcdee0; | ||
width: calc(100% + 3.2rem); | ||
` | ||
|
||
const VerticalDivider = styled.div` | ||
border-right: 1px solid ${({ theme }) => theme.legacy.colors.separator}; | ||
margin: 0 5px; | ||
height: 100%; | ||
` | ||
|
||
const Divider = ({ className, orientation }: Props): React.ReactElement => { | ||
return orientation === 'vertical' ? ( | ||
<VerticalDivider className={className} /> | ||
) : ( | ||
<HorizontalDivider className={className} /> | ||
) | ||
} | ||
|
||
export default Divider |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
import { type Theme } from '@material-ui/core/styles' | ||
|
||
type Props = { | ||
className?: string | ||
color: keyof Theme['palette'] | ||
} | ||
|
||
const StyledDot = styled.div<Props>` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
border-radius: 50%; | ||
height: 36px; | ||
width: 36px; | ||
background-color: ${({ theme, color }) => theme.palette[color].main}; | ||
` | ||
|
||
const Dot: React.FC<Props> = ({ children, ...rest }): React.ReactElement => ( | ||
<StyledDot {...rest}>{children}</StyledDot> | ||
) | ||
|
||
export default Dot |
Oops, something went wrong.