Skip to content

Commit

Permalink
Merge pull request #822 from safe-global/chore/move-react-components-…
Browse files Browse the repository at this point in the history
…to-tx-builder

chore(tx-builder-theme): move safe react components to TX-builder components folder
  • Loading branch information
clovisdasilvaneto authored Oct 4, 2024
2 parents 44091e4 + f0a67ea commit 8f5c550
Show file tree
Hide file tree
Showing 30 changed files with 2,505 additions and 0 deletions.
87 changes: 87 additions & 0 deletions apps/tx-builder/src/components/Accordion/index.tsx
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'
204 changes: 204 additions & 0 deletions apps/tx-builder/src/components/Button.tsx
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'

Check warning on line 6 in apps/tx-builder/src/components/Button.tsx

View workflow job for this annotation

GitHub Actions / eslint

'IconTypes' is defined but never used

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
36 changes: 36 additions & 0 deletions apps/tx-builder/src/components/Card/index.tsx
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
29 changes: 29 additions & 0 deletions apps/tx-builder/src/components/Divider.tsx
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
24 changes: 24 additions & 0 deletions apps/tx-builder/src/components/Dot/index.tsx
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
Loading

0 comments on commit 8f5c550

Please sign in to comment.