Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit styles [Modal/Stepper/IconSpinner] #3097

Merged
merged 8 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/cowswap-frontend/src/assets/icon/arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/cowswap-frontend/src/assets/icon/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/cowswap-frontend/src/assets/icon/x.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions apps/cowswap-frontend/src/common/pure/IconSpinner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Currency } from '@uniswap/sdk-core'

import styled from 'styled-components/macro'

import { CurrencyLogo } from 'common/pure/CurrencyLogo'

type IconSpinnerProps = {
currency?: Currency | null
image?: string
size?: number
children?: React.ReactNode
bgColor?: string
spinnerWidth?: number
}

const Wrapper = styled.div<{ size: number; spinnerWidth: number; bgColor?: string }>`
--bgColor: ${({ bgColor }) => `var(${bgColor})` || 'var(--cow-container-bg-01)'};
display: flex;
position: relative;
align-items: center;
justify-content: center;
width: ${({ size }) => size}px;
height: ${({ size }) => size}px;
min-width: ${({ size }) => size}px;
min-height: ${({ size }) => size}px;
border-radius: ${({ size }) => size}px;

&:before {
content: "";
position: absolute;
top: calc(-1 * ${({ spinnerWidth }) => spinnerWidth}px);
left: calc(-1 * ${({ spinnerWidth }) => spinnerWidth}px);
width: calc(100% + 2 * ${({ spinnerWidth }) => spinnerWidth}px);
height: calc(100% + 2 * ${({ spinnerWidth }) => spinnerWidth}px);
border-radius: 50%;
background: conic-gradient(from 0deg at 50% 50%, var(--cow-color-border) 0%, var(--cow-color-link) 100%);
animation: spin 2s linear infinite;
z-index: 1;
}

> img,
> svg,
> span {
object-fit: contain;
z-index: 2;
position: relative;
border: ${({ spinnerWidth }) => spinnerWidth}px solid var(--cow-container-bg-01);
border-radius: ${({ size }) => size}px;
background-color: var(--bgColor);
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}

@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
`;

export function IconSpinner({ currency, image, size = 24, children, bgColor, spinnerWidth = 2 }: IconSpinnerProps) {

return (
Copy link
Collaborator

@shoom3301 shoom3301 Sep 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea how to write it shorter:

<Wrapper size={size} spinnerWidth={spinnerWidth} bgColor={bgColor}>
      {(() => {
        if (currency) {
          return <CurrencyLogo currency={currency} size="100%" />
        } else if (image) {
          return <img src={image} alt="Spinning icon" width={size} height={size} />
        } else if (children) {
          return <span>{children}</span>
        }

        return <span />
      })()}
    </Wrapper>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion, updated!

<Wrapper size={size} spinnerWidth={spinnerWidth} bgColor={bgColor}>
{(() => {
if (currency) {
return <CurrencyLogo currency={currency} size="100%" />
} else if (image) {
return <img src={image} alt="Spinning icon" width={size} height={size} />
} else if (children) {
return <span>{children}</span>
}
return <span />
})()}
</Wrapper>
)
}
109 changes: 109 additions & 0 deletions apps/cowswap-frontend/src/common/pure/Modal/index.cosmos.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Token } from '@uniswap/sdk-core'

import ICON_ARROW from 'assets/icon/arrow.svg'
import SVG from 'react-inlinesvg'
import styled from 'styled-components/macro'

import { IconSpinner } from 'common/pure/IconSpinner'
import { Stepper } from 'common/pure/Stepper'

import { Modal, CowModal, NewModal, NewModalContentTop, NewModalContentBottom } from './index'

const mockToken = new Token(
1,
'0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
18,
'AAVE',
'Aave Token'
)

const IMAGE_ACCOUNT = "data:image/png;base64,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"

const Wrapper = styled.div`
width: 100vw;
height: 100vh;
`

const ArrowRight = styled(SVG)`
--size: 12px;
width: var(--size);
height: var(--size);
margin: auto;

> path {
fill: var(--cow-color-text2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the enum would be used:

Suggested change
fill: var(--cow-color-text2);
fill: var(${ColorTypes.COLOR_TEXT_2});

}
`

const ModalFixtures = {
'default modal': (
<Wrapper>
<Modal isOpen={true} onDismiss={() => console.log("Dismissed")}>
Default modal content here
</Modal>
</Wrapper>
),
'modal with minHeight and maxHeight': (
<Wrapper>
<Modal isOpen={true} onDismiss={() => console.log("Dismissed")} minHeight={50} maxHeight={80}>
Modal with minHeight and maxHeight
</Modal>
</Wrapper>
),
'cow modal': (
<Wrapper>
<CowModal isOpen={true} onDismiss={() => console.log("Cow Modal Dismissed")} maxWidth={400}>
Cow Modal Content
</CowModal>
</Wrapper>
),
'cow modal with background color': (
<Wrapper>
<CowModal isOpen={true} onDismiss={() => console.log("Cow Modal Dismissed")} maxWidth={400} backgroundColor="pink">
Cow Modal with Pink Background
</CowModal>
</Wrapper>
),
'new modal + content top/bottom': (
<Wrapper>
<NewModal>
<NewModalContentTop paddingTop={90}>
<IconSpinner currency={mockToken} size={84} />
<h3>Approve spending AAVE <br /> on CoW Swap</h3>
</NewModalContentTop>

<NewModalContentBottom>
<p>Sign (gas-free!) in your wallet...</p>
<Stepper maxWidth={'75%'} steps={[{ stepState: 'active', stepNumber: 1, label: 'Approve' }, { stepState: 'open', stepNumber: 2, label: 'Submit' },]} />
</NewModalContentBottom>
</NewModal>
</Wrapper>
),
'new modal + content top/bottom 2': (
<Wrapper>
<NewModal>
<NewModalContentTop paddingTop={90}>
<IconSpinner image={IMAGE_ACCOUNT} size={84} />
<span>
<h3>Confirm Swap</h3>
<p>10 AAVE <ArrowRight src={ICON_ARROW} /> 564.7202 DAI</p>
</span>
</NewModalContentTop>

<NewModalContentBottom>
<p>Sign (gas-free!) in your wallet...</p>
<Stepper maxWidth={'75%'} steps={[{ stepState: 'finished', stepNumber: 1, label: 'Approved' }, { stepState: 'active', stepNumber: 2, label: 'Submit' },]} />
</NewModalContentBottom>
</NewModal>
</Wrapper>
),
'new modal + heading title': (
<Wrapper>
<NewModal title="Review transaction">
- New Modal -
</NewModal>
</Wrapper>
),
}

export default ModalFixtures
Loading