From 97c40b44bc2e345cf9887da359c8c4d9bf0c1a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Sim=C3=A3o?= Date: Mon, 4 Mar 2024 17:54:17 +0000 Subject: [PATCH] feat: continue --- .storybook/preview-body.html | 5 + packages/components/package.json | 1 + .../components/src/Button/Button.stories.tsx | 8 ++ packages/components/src/Button/Button.tsx | 8 +- .../src/CoinIcon/CoinIcon.stories.tsx | 36 -------- .../src/CoinIcon/CoinIcon.style.tsx | 10 -- packages/components/src/CoinIcon/CoinIcon.tsx | 40 -------- .../components/src/CoinIcon/FallbackIcon.tsx | 17 ---- .../components/src/CoinIcon/LPCoinIcon.tsx | 65 ------------- .../src/CoinIcon/__tests__/Card.test.tsx | 29 ------ packages/components/src/CoinIcon/index.tsx | 2 - packages/components/src/CoinIcon/types.ts | 4 - .../components/src/Dialog/Dialog.style.tsx | 43 ++++----- packages/components/src/Dialog/Dialog.tsx | 17 ++-- .../components/src/Dialog/DialogContext.tsx | 7 +- .../components/src/Dialog/DialogDivider.tsx | 15 --- .../components/src/Dialog/DialogHeader.tsx | 10 +- .../src/Dialog/__tests__/Dialog.test.tsx | 5 +- packages/components/src/Dialog/index.tsx | 2 - .../components/src/Divider/Divider.style.tsx | 14 +-- packages/components/src/Divider/Divider.tsx | 9 +- .../components/src/Drawer/Drawer.style.tsx | 12 +-- .../src/HelperText/HelperText.style.tsx | 12 +-- packages/components/src/Input/BaseInput.tsx | 23 +---- .../components/src/Input/Input.stories.tsx | 38 ++++---- packages/components/src/Input/Input.style.tsx | 91 ++++++------------- packages/components/src/Label/Label.style.tsx | 17 ++-- packages/components/src/Label/Label.tsx | 2 +- .../components/src/Modal/Modal.stories.tsx | 4 +- .../components/src/Modal/ModalDivider.tsx | 8 -- packages/components/src/Modal/index.tsx | 2 - .../src/NumberInput/NumberInput.tsx | 2 +- .../components/src/Select/Select.stories.tsx | 7 +- .../src/TextArea/TextArea.stories.tsx | 12 +-- .../src/TokenStack/TokenStack.stories.tsx | 30 ------ .../src/TokenStack/TokenStack.style.tsx | 37 -------- .../components/src/TokenStack/TokenStack.tsx | 27 ------ .../TokenStack/__tests__/TokenStack.test.tsx | 16 ---- packages/components/src/TokenStack/index.tsx | 2 - packages/components/src/index.ts | 8 +- packages/components/src/utils/margin.ts | 4 +- .../components/src/utils/visually-hidden.ts | 2 +- .../core/themeV2/src/components/dialog.ts | 23 ++--- .../core/themeV2/src/components/divider.ts | 6 +- .../core/themeV2/src/components/drawer.ts | 8 +- packages/core/themeV2/src/components/input.ts | 7 +- packages/core/themeV2/src/index.ts | 11 ++- .../core/themeV2/src/themes/bob/dialog.ts | 51 ++++++++++- .../core/themeV2/src/themes/bob/divider.ts | 4 +- .../core/themeV2/src/themes/bob/drawer.ts | 7 +- packages/core/themeV2/src/themes/bob/input.ts | 86 ++++++------------ pnpm-lock.yaml | 5 +- 52 files changed, 270 insertions(+), 641 deletions(-) create mode 100644 .storybook/preview-body.html delete mode 100644 packages/components/src/CoinIcon/CoinIcon.stories.tsx delete mode 100644 packages/components/src/CoinIcon/CoinIcon.style.tsx delete mode 100644 packages/components/src/CoinIcon/CoinIcon.tsx delete mode 100644 packages/components/src/CoinIcon/FallbackIcon.tsx delete mode 100644 packages/components/src/CoinIcon/LPCoinIcon.tsx delete mode 100644 packages/components/src/CoinIcon/__tests__/Card.test.tsx delete mode 100644 packages/components/src/CoinIcon/index.tsx delete mode 100644 packages/components/src/CoinIcon/types.ts delete mode 100644 packages/components/src/Dialog/DialogDivider.tsx delete mode 100644 packages/components/src/Modal/ModalDivider.tsx delete mode 100644 packages/components/src/TokenStack/TokenStack.stories.tsx delete mode 100644 packages/components/src/TokenStack/TokenStack.style.tsx delete mode 100644 packages/components/src/TokenStack/TokenStack.tsx delete mode 100644 packages/components/src/TokenStack/__tests__/TokenStack.test.tsx delete mode 100644 packages/components/src/TokenStack/index.tsx diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html new file mode 100644 index 000000000..dd62e467e --- /dev/null +++ b/.storybook/preview-body.html @@ -0,0 +1,5 @@ + diff --git a/packages/components/package.json b/packages/components/package.json index 3e5f15788..6834a50ac 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -44,6 +44,7 @@ "@interlay/system": "workspace:*", "@interlay/theme": "workspace:*", "@interlay/themev2": "workspace:*", + "@radix-ui/react-slot": "^1.0.2", "@react-aria/accordion": "3.0.0-alpha.20", "@react-aria/breadcrumbs": "^3.5.4", "@react-aria/button": "^3.8.1", diff --git a/packages/components/src/Button/Button.stories.tsx b/packages/components/src/Button/Button.stories.tsx index b1a5220d8..271eed31e 100644 --- a/packages/components/src/Button/Button.stories.tsx +++ b/packages/components/src/Button/Button.stories.tsx @@ -28,6 +28,14 @@ export const Icon: StoryObj = { } }; +export const Link: StoryObj = { + args: { + asChild: true, + // eslint-disable-next-line jsx-a11y/anchor-is-valid + children: Link + } +}; + // export const Secondary: StoryObj = { // args: { // variant: 'secondary' diff --git a/packages/components/src/Button/Button.tsx b/packages/components/src/Button/Button.tsx index 294e3078c..66d45cf67 100644 --- a/packages/components/src/Button/Button.tsx +++ b/packages/components/src/Button/Button.tsx @@ -5,6 +5,7 @@ import { mergeProps } from '@react-aria/utils'; import { PressEvent } from '@react-types/shared'; import { ButtonHTMLAttributes, forwardRef } from 'react'; import { ButtonVariants, ButtonSizes, ButtonColors, SpinnerSizes, SpinnerColors } from '@interlay/themev2'; +import { Slot, Slottable } from '@radix-ui/react-slot'; import { Flex } from '../Flex'; import { Spinner } from '../Spinner'; @@ -39,6 +40,7 @@ type Props = { color?: ButtonColors; loading?: boolean; isIconOnly?: boolean; + asChild?: boolean; onPress?: (e: PressEvent) => void; }; @@ -59,6 +61,7 @@ const Button = forwardRef( isIconOnly, onPress, onClick, + asChild, ...props }, ref @@ -70,6 +73,8 @@ const Button = forwardRef( const { buttonProps } = useButton({ isDisabled, onPress, ...props }, domRef); const { focusProps, isFocusVisible } = useFocusRing(props); + const Comp = asChild ? Slot : 'button'; + return ( ( $isIconOnly={isIconOnly} $size={size} $variant={variant} + as={Comp} disabled={isDisabled} {...mergeProps(props, buttonProps, focusProps, { onClick })} > @@ -87,7 +93,7 @@ const Button = forwardRef( )} - {isIconOnly ? (loading ? undefined : children) : children} + {isIconOnly ? loading ? undefined : {children} : {children}} ); } diff --git a/packages/components/src/CoinIcon/CoinIcon.stories.tsx b/packages/components/src/CoinIcon/CoinIcon.stories.tsx deleted file mode 100644 index 2d57e54e0..000000000 --- a/packages/components/src/CoinIcon/CoinIcon.stories.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Meta, StoryFn, StoryObj } from '@storybook/react'; - -import * as coins from '../../../icons/coin/src'; -import { Flex } from '../Flex'; - -import { CoinIcon, CoinIconProps } from './CoinIcon'; - -export default { - title: 'Coin/CoinIcon', - component: CoinIcon, - parameters: { - layout: 'centered' - }, - args: { - size: 'xl2' - } -} as Meta; - -export const Default: StoryObj = { - args: { - ticker: 'BTC' - }, - argTypes: { - ticker: { control: 'select', options: Object.keys(coins) } - } -}; - -export const LPTokens: StoryFn = (args) => { - return ( - - - - - - ); -}; diff --git a/packages/components/src/CoinIcon/CoinIcon.style.tsx b/packages/components/src/CoinIcon/CoinIcon.style.tsx deleted file mode 100644 index 98d0e79ff..000000000 --- a/packages/components/src/CoinIcon/CoinIcon.style.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import styled from 'styled-components'; -import { Icon } from '@interlay/icons'; -import { theme } from '@interlay/theme'; - -const StyledFallbackIcon = styled(Icon)` - stroke: ${theme.icon.fallback.stroke}; - color: ${theme.icon.fallback.color}; -`; - -export { StyledFallbackIcon }; diff --git a/packages/components/src/CoinIcon/CoinIcon.tsx b/packages/components/src/CoinIcon/CoinIcon.tsx deleted file mode 100644 index 2ec3b2f0c..000000000 --- a/packages/components/src/CoinIcon/CoinIcon.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { forwardRef } from 'react'; -import { IconProps } from '@interlay/icons'; - -import * as coins from '../../../icons/coin/src'; - -import { FallbackIcon } from './FallbackIcon'; -import { LPCoinIcon } from './LPCoinIcon'; -import { CoinComponent } from './types'; - -const DATA = coins as unknown as Record; - -type Props = { - ticker: string; - // Multi tickers icons - tickers?: string[]; -}; - -type NativeAttrs = Omit; - -type CoinIconProps = Props & NativeAttrs; - -const CoinIcon = forwardRef(({ ticker, tickers, ...props }, ref): JSX.Element => { - // Only want to render multi-token if has more than 1 ticker - if (tickers && tickers?.length > 1) { - return ; - } - - const CoinIcon = DATA[ticker]; - - if (!CoinIcon) { - return ; - } - - return ; -}); - -CoinIcon.displayName = 'CoinIcon'; - -export { CoinIcon }; -export type { CoinIconProps }; diff --git a/packages/components/src/CoinIcon/FallbackIcon.tsx b/packages/components/src/CoinIcon/FallbackIcon.tsx deleted file mode 100644 index 1d11f7a8f..000000000 --- a/packages/components/src/CoinIcon/FallbackIcon.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { forwardRef } from 'react'; - -import { CoinIconProps } from './CoinIcon'; -import { StyledFallbackIcon } from './CoinIcon.style'; - -const FallbackIcon = forwardRef( - ({ ticker, ...props }, ref): JSX.Element => ( - - {ticker} - - - ) -); - -FallbackIcon.displayName = 'FallbackIcon'; - -export { FallbackIcon }; diff --git a/packages/components/src/CoinIcon/LPCoinIcon.tsx b/packages/components/src/CoinIcon/LPCoinIcon.tsx deleted file mode 100644 index 43bb77061..000000000 --- a/packages/components/src/CoinIcon/LPCoinIcon.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { forwardRef, useCallback } from 'react'; -import { Icon } from '@interlay/icons'; - -import { CoinIconProps } from './CoinIcon'; -import { FallbackIcon } from './FallbackIcon'; -import { CoinComponent } from './types'; - -type Props = { - tickers: string[]; - data: Record; -}; - -type InheritAttrs = Omit; - -type LPCoinIconProps = Props & InheritAttrs; - -const LPCoinIcon = forwardRef( - ({ tickers, size = 'md', ticker, data, ...props }, ref): JSX.Element => { - const [tickerA, tickerB, tickerC, tickerD] = tickers; - - const getIcon = useCallback( - (ticker: string) => data[ticker] || (() => ), - [size] - ); - - const IconA = getIcon(tickerA); - const IconB = getIcon(tickerB); - - if (tickers.length === 2) { - return ( - - {ticker} - - - - ); - } - - const IconC = getIcon(tickerC); - - const hasIconD = !!tickerD; - - const IconD = hasIconD && getIcon(tickerD); - - const commonSize = { - width: '60%', - height: '60%' - }; - - return ( - - {ticker} - - - - {IconD && } - - ); - } -); - -LPCoinIcon.displayName = 'LPCoinIcon'; - -export { LPCoinIcon }; -export type { LPCoinIconProps }; diff --git a/packages/components/src/CoinIcon/__tests__/Card.test.tsx b/packages/components/src/CoinIcon/__tests__/Card.test.tsx deleted file mode 100644 index 634140e42..000000000 --- a/packages/components/src/CoinIcon/__tests__/Card.test.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { render } from '@testing-library/react'; -import { createRef } from 'react'; -import { testA11y } from '@interlay/test-utils'; - -import { CoinIcon } from '..'; - -describe('CoinIcon', () => { - it('should render correctly', () => { - const wrapper = render(); - - expect(() => wrapper.unmount()).not.toThrow(); - }); - - it('ref should be forwarded', () => { - const ref = createRef(); - - render( - - content - - ); - - expect(ref.current).not.toBeNull(); - }); - - it('should pass a11y', async () => { - await testA11y(); - }); -}); diff --git a/packages/components/src/CoinIcon/index.tsx b/packages/components/src/CoinIcon/index.tsx deleted file mode 100644 index ab9ba1d84..000000000 --- a/packages/components/src/CoinIcon/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export type { CoinIconProps } from './CoinIcon'; -export { CoinIcon } from './CoinIcon'; diff --git a/packages/components/src/CoinIcon/types.ts b/packages/components/src/CoinIcon/types.ts deleted file mode 100644 index 16b884c64..000000000 --- a/packages/components/src/CoinIcon/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ForwardRefExoticComponent, RefAttributes } from 'react'; -import { IconProps } from '@interlay/icons'; - -export type CoinComponent = ForwardRefExoticComponent>; diff --git a/packages/components/src/Dialog/Dialog.style.tsx b/packages/components/src/Dialog/Dialog.style.tsx index b8c99f851..6bd38f90a 100644 --- a/packages/components/src/Dialog/Dialog.style.tsx +++ b/packages/components/src/Dialog/Dialog.style.tsx @@ -1,54 +1,49 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; +import { DialogSize } from '@interlay/themev2'; -import { theme } from '../../../core/theme/src'; -import { Sizes } from '../../../core/theme/src'; -import { CTA } from '../CTA'; -import { Divider } from '../Divider'; import { Flex } from '../Flex'; import { H3 } from '../Text'; +import { Button } from '../Button'; type StyledDialogProps = { - $size: Sizes; + $size: DialogSize; }; const StyledDialog = styled.section` - background: ${theme.colors.bgPrimary}; - border: ${theme.border.default}; - border-radius: ${theme.rounded.md}; - color: ${theme.colors.textPrimary}; max-width: 100%; - width: ${({ $size }) => theme.dialog[$size].width}; display: flex; flex-direction: column; position: relative; outline: none; + + ${({ theme, $size }) => css` + ${theme.dialog.base} + ${theme.dialog.size[$size].base} + `} `; -const StyledCloseCTA = styled(CTA)` +const StyledCloseCTA = styled(Button)` position: absolute; - top: ${theme.spacing.spacing2}; - right: ${theme.spacing.spacing2}; - z-index: ${theme.dialog.closeBtn.zIndex}; + top: ${({ theme }) => theme.spacing('s')}; + right: ${({ theme }) => theme.spacing('s')}; + z-index: 100; `; const StyledDialogHeader = styled(H3)` - padding: ${({ $size }) => theme.dialog[$size].header.padding}; - overflow: hidden; - flex-shrink: 0; -`; + ${({ $size, theme }) => theme.dialog.size[$size].header}; -const StyledDialogDivider = styled(Divider)` - margin: ${({ $size }) => `0 ${theme.dialog[$size].divider.marginX} ${theme.dialog[$size].divider.marginBottom}`}; + overflow: hidden; flex-shrink: 0; `; const StyledDialogBody = styled(Flex)` - padding: ${({ $size }) => `${theme.dialog[$size].body.paddingY} ${theme.dialog[$size].body.paddingX}`}; + ${({ $size, theme }) => theme.dialog.size[$size].body}; + flex: 1 1 auto; `; const StyledDialogFooter = styled(Flex)` - padding: ${({ $size }) => theme.dialog[$size].footer.padding}; + ${({ $size, theme }) => theme.dialog.size[$size].footer}; `; -export { StyledCloseCTA, StyledDialog, StyledDialogBody, StyledDialogDivider, StyledDialogFooter, StyledDialogHeader }; +export { StyledCloseCTA, StyledDialog, StyledDialogBody, StyledDialogFooter, StyledDialogHeader }; diff --git a/packages/components/src/Dialog/Dialog.tsx b/packages/components/src/Dialog/Dialog.tsx index 8eb4fcb6f..47f67066f 100644 --- a/packages/components/src/Dialog/Dialog.tsx +++ b/packages/components/src/Dialog/Dialog.tsx @@ -4,19 +4,20 @@ import { PressEvent } from '@react-types/shared'; import { forwardRef, ReactNode } from 'react'; import { XMark } from '@interlay/icons'; import { useDOMRef } from '@interlay/hooks'; +import { ButtonSizes, DialogSize } from '@interlay/themev2'; -import { CTASizes, Sizes } from '../../../core/theme/src'; import { ElementTypeProp } from '../utils/types'; +import { Button } from '../Button'; -import { StyledCloseCTA, StyledDialog } from './Dialog.style'; +import { StyledDialog } from './Dialog.style'; import { DialogContext } from './DialogContext'; -const closeCTASizeMap: Record = { small: 'x-small', medium: 'small', large: 'small' }; +const closeBtnSizeMap: Record = { s: 's', md: 'md', lg: 'md' }; type Props = { children?: ReactNode; onClose?: (e: PressEvent) => void; - size?: Sizes; + size?: DialogSize; }; type InheritAttrs = Omit; @@ -24,21 +25,21 @@ type InheritAttrs = Omit; type DialogProps = Props & InheritAttrs & ElementTypeProp; const Dialog = forwardRef( - ({ children, onClose, size = 'medium', elementType, role = 'dialog', ...props }, ref): JSX.Element => { + ({ children, onClose, size = 'md', elementType, role = 'dialog', ...props }, ref): JSX.Element => { const dialogRef = useDOMRef(ref); // Get props for the dialog and its title const { dialogProps, titleProps } = useDialog(props, dialogRef); - const closeCTASize = closeCTASizeMap[size]; + const closeCTASize = closeBtnSizeMap[size]; return ( {onClose && ( - + )} {children} diff --git a/packages/components/src/Dialog/DialogContext.tsx b/packages/components/src/Dialog/DialogContext.tsx index bbd1cc2f9..e161f1a9c 100644 --- a/packages/components/src/Dialog/DialogContext.tsx +++ b/packages/components/src/Dialog/DialogContext.tsx @@ -1,14 +1,13 @@ import { DOMAttributes } from '@react-types/shared'; import React from 'react'; - -import { Sizes } from '../../../core/theme/src'; +import { DialogSize } from '@interlay/themev2'; interface DialogConfig { titleProps?: DOMAttributes; - size: Sizes; + size: DialogSize; } -const defaultContext: DialogConfig = { size: 'medium' }; +const defaultContext: DialogConfig = { size: 'md' }; const DialogContext = React.createContext(defaultContext); diff --git a/packages/components/src/Dialog/DialogDivider.tsx b/packages/components/src/Dialog/DialogDivider.tsx deleted file mode 100644 index 4a37a37e9..000000000 --- a/packages/components/src/Dialog/DialogDivider.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { DividerProps } from '../Divider'; - -import { StyledDialogDivider } from './Dialog.style'; -import { useDialogContext } from './DialogContext'; - -type DialogDividerProps = Omit; - -const DialogDivider = (props: DialogDividerProps): JSX.Element => { - const { size } = useDialogContext(); - - return ; -}; - -export { DialogDivider }; -export type { DialogDividerProps }; diff --git a/packages/components/src/Dialog/DialogHeader.tsx b/packages/components/src/Dialog/DialogHeader.tsx index 031bda8b1..8c3c37185 100644 --- a/packages/components/src/Dialog/DialogHeader.tsx +++ b/packages/components/src/Dialog/DialogHeader.tsx @@ -1,16 +1,16 @@ import { mergeProps } from '@react-aria/utils'; import { ElementType } from 'react'; +import { DialogSize, Typography } from '@interlay/themev2'; -import { FontSize, Sizes } from '../../../core/theme/src'; import { TextProps } from '../Text'; import { StyledDialogHeader } from './Dialog.style'; import { useDialogContext } from './DialogContext'; -const sizeMap: Record = { - small: 'base', - medium: 'xl', - large: 'xl' +const sizeMap: Record = { + s: 'md', + md: 'xl', + lg: 'xl' }; type Props = { diff --git a/packages/components/src/Dialog/__tests__/Dialog.test.tsx b/packages/components/src/Dialog/__tests__/Dialog.test.tsx index f71c3ac18..f48aa61e0 100644 --- a/packages/components/src/Dialog/__tests__/Dialog.test.tsx +++ b/packages/components/src/Dialog/__tests__/Dialog.test.tsx @@ -2,14 +2,13 @@ import { render } from '@testing-library/react'; import { createRef } from 'react'; import { testA11y } from '@interlay/test-utils'; -import { Dialog, DialogBody, DialogDivider, DialogFooter, DialogHeader } from '..'; +import { Dialog, DialogBody, DialogFooter, DialogHeader } from '..'; describe('Dialog', () => { it('should render correctly', () => { const wrapper = render( title - body footer @@ -24,7 +23,6 @@ describe('Dialog', () => { render( title - body footer @@ -37,7 +35,6 @@ describe('Dialog', () => { await testA11y( title - body footer diff --git a/packages/components/src/Dialog/index.tsx b/packages/components/src/Dialog/index.tsx index b5980d46c..328100e8d 100644 --- a/packages/components/src/Dialog/index.tsx +++ b/packages/components/src/Dialog/index.tsx @@ -2,8 +2,6 @@ export type { DialogProps } from './Dialog'; export { Dialog } from './Dialog'; export type { DialogBodyProps } from './DialogBody'; export { DialogBody } from './DialogBody'; -export type { DialogDividerProps } from './DialogDivider'; -export { DialogDivider } from './DialogDivider'; export type { DialogFooterProps } from './DialogFooter'; export { DialogFooter } from './DialogFooter'; export type { DialogHeaderProps } from './DialogHeader'; diff --git a/packages/components/src/Divider/Divider.style.tsx b/packages/components/src/Divider/Divider.style.tsx index 08288fb05..683c62e07 100644 --- a/packages/components/src/Divider/Divider.style.tsx +++ b/packages/components/src/Divider/Divider.style.tsx @@ -1,20 +1,20 @@ import styled from 'styled-components'; import { StyledMarginProps } from '@interlay/hooks'; +import { Color, DividerSizes } from '@interlay/themev2'; -import { theme, resolveColor } from '../../../core/theme/src'; -import { DividerVariants, Orientation, Sizes } from '../../../core/theme/src'; +import { Orientation } from '../../../core/theme/src'; import { marginCSS } from '../utils/margin'; type StyledDividerProps = { - $color: DividerVariants; + $color: Color; $orientation: Orientation; - $size: Sizes; + $size: DividerSizes; } & StyledMarginProps; const StyledDivider = styled.hr` - background-color: ${({ $color }) => ($color === 'default' ? 'var(--colors-border)' : resolveColor($color))}; - height: ${({ $orientation, $size }) => ($orientation === 'horizontal' ? theme.divider.size[$size] : 'auto')}; - width: ${({ $orientation, $size }) => ($orientation === 'horizontal' ? '' : theme.divider.size[$size])}; + background-color: ${({ $color, theme }) => theme.color($color)}; + height: ${({ $orientation, $size, theme }) => ($orientation === 'horizontal' ? theme.divider.size[$size] : 'auto')}; + width: ${({ $orientation, $size, theme }) => ($orientation === 'horizontal' ? '' : theme.divider.size[$size])}; border: 0; margin: 0; align-self: stretch; diff --git a/packages/components/src/Divider/Divider.tsx b/packages/components/src/Divider/Divider.tsx index 633aa17f5..deac02751 100644 --- a/packages/components/src/Divider/Divider.tsx +++ b/packages/components/src/Divider/Divider.tsx @@ -2,16 +2,17 @@ import { useSeparator } from '@react-aria/separator'; import { mergeProps } from '@react-aria/utils'; import { forwardRef, HTMLAttributes } from 'react'; import { useStyleProps } from '@interlay/hooks'; +import { Color, DividerSizes } from '@interlay/themev2'; -import { DividerVariants, MarginProps, Orientation, Sizes } from '../../../core/theme/src'; +import { MarginProps, Orientation } from '../../../core/theme/src'; import { ElementTypeProp } from '../utils/types'; import { StyledDivider } from './Divider.style'; type Props = { orientation?: Orientation; - color?: DividerVariants; - size?: Sizes; + color?: Color; + size?: DividerSizes; }; type NativeAttrs = Omit, keyof Props>; @@ -20,7 +21,7 @@ type DividerProps = Props & NativeAttrs & ElementTypeProp & MarginProps; const Divider = forwardRef( ( - { elementType: elementTypeProp, orientation = 'horizontal', color = 'primary', size = 'small', ...props }, + { elementType: elementTypeProp, orientation = 'horizontal', color = 'grey-200', size = 's', ...props }, ref ): JSX.Element => { const elementType = elementTypeProp || orientation === 'vertical' ? 'div' : 'hr'; diff --git a/packages/components/src/Drawer/Drawer.style.tsx b/packages/components/src/Drawer/Drawer.style.tsx index d624d0fc8..c698b0a62 100644 --- a/packages/components/src/Drawer/Drawer.style.tsx +++ b/packages/components/src/Drawer/Drawer.style.tsx @@ -1,5 +1,4 @@ import styled from 'styled-components'; -import { theme } from '@interlay/theme'; import { overlayCSS } from '../utils/overlay'; import { Dialog } from '../Dialog'; @@ -23,7 +22,7 @@ const StyledModal = styled.div` opacity: 1; overflow-y: scroll; - z-index: ${theme.modal.zIndex}; + z-index: 2; position: fixed; top: 0; bottom: 0; @@ -31,11 +30,10 @@ const StyledModal = styled.div` right: 100%; height: 100%; - background: ${theme.colors.bgPrimary}; - transition: transform - ${({ $isOpen }) => ($isOpen ? theme.transition.duration.duration250 : theme.transition.duration.duration100)}ms - ease-in-out; + transition: transform ${({ $isOpen }) => ($isOpen ? '250ms' : '100ms')} ease-in-out; + + ${({ theme }) => theme.drawer}; `; const StyledDialog = styled(Dialog)` @@ -48,7 +46,7 @@ const StyledDialog = styled(Dialog)` flex-direction: column; position: relative; outline: none; - padding: ${theme.spacing.spacing4}; + padding: ${({ theme }) => theme.spacing('md')}; `; export { StyledDialog, StyledModal }; diff --git a/packages/components/src/HelperText/HelperText.style.tsx b/packages/components/src/HelperText/HelperText.style.tsx index bf979bbe1..f4e25d674 100644 --- a/packages/components/src/HelperText/HelperText.style.tsx +++ b/packages/components/src/HelperText/HelperText.style.tsx @@ -1,5 +1,4 @@ import styled from 'styled-components'; -import { theme } from '@interlay/theme'; import { visuallyHidden } from '../utils/visually-hidden'; @@ -9,16 +8,15 @@ type StyledHelperTextProps = { }; const StyledHelperText = styled.div` - font-weight: ${theme.fontWeight.medium}; - line-height: ${theme.lineHeight.lg}; - font-size: ${theme.text.xs}; - color: ${(props) => (props.$hasError ? theme.input.helperText.error.color : theme.colors.textTertiary)}; - padding: ${theme.spacing.spacing1} 0; + font-weight: ${({ theme }) => theme.fontWeight('medium')}; + ${({ theme }) => theme.typography('xs')} + color: ${({ $hasError, theme }) => ($hasError ? '#FF0000' : theme.color('grey-100'))}; + padding: ${({ theme }) => theme.spacing('xs')} 0; ${({ $isHidden }) => $isHidden && visuallyHidden()} `; const StyledSubHelperText = styled.p` - line-height: ${theme.lineHeight.s}; + line-height: ${({ theme }) => theme.lineHeight('s')}; `; export { StyledHelperText, StyledSubHelperText }; diff --git a/packages/components/src/Input/BaseInput.tsx b/packages/components/src/Input/BaseInput.tsx index f0d039ff7..e3617f366 100644 --- a/packages/components/src/Input/BaseInput.tsx +++ b/packages/components/src/Input/BaseInput.tsx @@ -1,14 +1,13 @@ -import { Spacing } from '@interlay/theme'; +import { Spacing, InputSizes } from '@interlay/themev2'; import { FocusEvent, forwardRef, InputHTMLAttributes, ReactNode, TextareaHTMLAttributes } from 'react'; -import { InputSizes } from '@interlay/themev2'; -import { ElementTypeProp } from '../utils/types'; import { Field, FieldProps, useFieldProps } from '../Field'; import { HelperTextProps } from '../HelperText'; import { LabelProps } from '../Label'; import { hasError } from '../utils/input'; +import { ElementTypeProp } from '../utils/types'; -import { StyledAdornmentBottom, StyledAdornmentLeft, StyledAdornmentRight, StyledBaseInput } from './Input.style'; +import { StyledAdornmentLeft, StyledAdornmentRight, StyledBaseInput } from './Input.style'; // TODO: might need to consolidate this later interface HTMLInputProps extends ElementTypeProp { @@ -28,7 +27,6 @@ type Props = { labelProps?: LabelProps; startAdornment?: ReactNode; endAdornment?: ReactNode; - bottomAdornment?: ReactNode; value?: string | ReadonlyArray | number; defaultValue?: string | ReadonlyArray | number; size?: InputSizes; @@ -47,17 +45,7 @@ type BaseInputProps = Props & InheritAttrs; const BaseInput = forwardRef( ( - { - startAdornment, - endAdornment, - bottomAdornment, - size = 'md', - isInvalid, - inputProps, - minHeight, - elementType = 'input', - ...props - }, + { startAdornment, endAdornment, size = 'md', isInvalid, inputProps, minHeight, elementType = 'input', ...props }, ref ): JSX.Element => { // FIXME: move this into Field @@ -70,7 +58,7 @@ const BaseInput = forwardRef( {startAdornment && {startAdornment}} ( as={elementType} {...inputProps} /> - {bottomAdornment && {bottomAdornment}} {endAdornment && {endAdornment}} ); diff --git a/packages/components/src/Input/Input.stories.tsx b/packages/components/src/Input/Input.stories.tsx index ee5b961ac..c871d8bf8 100644 --- a/packages/components/src/Input/Input.stories.tsx +++ b/packages/components/src/Input/Input.stories.tsx @@ -1,7 +1,6 @@ import { Meta, StoryFn, StoryObj } from '@storybook/react'; import { InformationCircle } from '@interlay/icons'; -import { Span } from '../Text'; import { Flex } from '../Flex'; import { Input, InputProps } from '.'; @@ -31,17 +30,17 @@ export const Default: StoryObj = {}; // } // }; -// export const WithDescription: StoryObj = { -// args: { -// description: 'Please enter your street address' -// } -// }; +export const WithDescription: StoryObj = { + args: { + description: 'Please enter your street address' + } +}; -// export const WithErrorMessage: StoryObj = { -// args: { -// errorMessage: 'Please enter your street address' -// } -// }; +export const WithErrorMessage: StoryObj = { + args: { + errorMessage: 'Please enter your street address' + } +}; // export const WithMultipleErrorMessage: StoryObj = { // args: { @@ -65,7 +64,6 @@ export const Adornments: StoryFn = (args) => ( } /> } label='End Adornment' /> - $0.00} label='Bottom Adornment' /> ); @@ -77,8 +75,14 @@ export const Adornments: StoryFn = (args) => ( // // ); -// export const Disabled: StoryObj = { -// args: { -// isDisabled: true -// } -// }; +export const Placeholder: StoryObj = { + args: { + placeholder: 'Enter address' + } +}; + +export const Disabled: StoryObj = { + args: { + isDisabled: true + } +}; diff --git a/packages/components/src/Input/Input.style.tsx b/packages/components/src/Input/Input.style.tsx index 295e2c32c..89d515409 100644 --- a/packages/components/src/Input/Input.style.tsx +++ b/packages/components/src/Input/Input.style.tsx @@ -1,10 +1,9 @@ +import { InputSizes, Spacing } from '@interlay/themev2'; import styled, { css } from 'styled-components'; -import { Spacing, theme as oldTheme } from '@interlay/theme'; -import { InputSizes } from '@interlay/themev2'; type BaseInputProps = { $size: InputSizes; - $adornments: { bottom: boolean; left: boolean; right: boolean }; + $adornments: { left: boolean; right: boolean }; $isDisabled: boolean; $hasError: boolean; $minHeight?: Spacing; @@ -22,57 +21,47 @@ const StyledBaseInput = styled.input` text-overflow: ellipsis; - /* background-color: ${({ $isDisabled }) => - $isDisabled ? oldTheme.input.disabled.bg : oldTheme.input.background}; */ - overflow: hidden; - - border: ${(props) => - props.$isDisabled - ? oldTheme.input.disabled.border - : props.$hasError - ? oldTheme.input.error.border - : oldTheme.border.default}; - transition: - border-color ${oldTheme.transition.duration.duration150}ms ease-in-out, - box-shadow ${oldTheme.transition.duration.duration150}ms ease-in-out; - - min-height: ${({ $minHeight, as }) => - $minHeight ? oldTheme.spacing[$minHeight] : as === 'textarea' && oldTheme.spacing.spacing16}; + // Properties for textarea + min-height: ${({ $minHeight, theme, as }) => + $minHeight ? theme.spacing($minHeight) : as === 'textarea' && theme.spacing('7xl')}; resize: ${({ as }) => as === 'textarea' && 'vertical'}; - ${({ theme, $size, $adornments }) => { - const { paddingRight, paddingTop, paddingBottom, paddingLeft, fontSize, ...sizeCss } = theme.input.size[$size]; + ${({ theme, $size, $adornments, $hasError }) => { + const { paddingRight, paddingTop, paddingBottom, paddingLeft, ...sizeCss } = theme.input.size[$size]; // MEMO: adding `spacing6` is a hacky solution because // the `endAdornmentWidth` does not update width correctly // after fonts are loaded. Instead of falling back to a more // complex solution, an extra offset does the job of not allowing // the input overlap the adornment. - //$adornments.bottom ? `calc(${fontSize} - ${theme.spacing('md')})` : return css` - font-size: ${fontSize}; padding-top: ${paddingTop}; + padding-bottom: ${paddingBottom}; padding-left: ${$adornments.left ? theme.spacing('5xl') : paddingLeft}; padding-right: ${$adornments.right ? theme.spacing('5xl') : paddingRight}; - padding-bottom: ${$adornments.bottom ? theme.spacing('3xl') : paddingBottom}; ${sizeCss} ${theme.input.base} - `; - }} + ${$hasError && theme.input.error.base} - &:hover:not(:disabled):not(:focus) { - border: ${(props) => !props.$isDisabled && !props.$hasError && oldTheme.border.focus}; - } - &:focus { - border: ${(props) => !props.$isDisabled && oldTheme.border.focus}; - box-shadow: ${(props) => !props.$isDisabled && oldTheme.boxShadow.focus}; - } + &:hover:not(:disabled):not(:focus) { + ${$hasError ? theme.input.error.hover : theme.input.hover} + } - &::placeholder { - color: ${(props) => (props.disabled ? oldTheme.input.disabled.color : oldTheme.colors.textTertiary)}; - } + &:focus:not(:disabled) { + ${$hasError ? theme.input.error.focus : theme.input.focus} + } + + &::placeholder { + ${theme.input.placeholder} + } + + &:disabled { + ${theme.input.disabled} + } + `; + }} /* MEMO: inspired by https://www.w3schools.com/howto/howto_css_hide_arrow_number.asp */ /* Chrome, Safari, Edge, Opera */ @@ -87,9 +76,8 @@ const StyledBaseInput = styled.input` } `; -const BaseInputWrapper = styled.div` +const StyledWrapper = styled.div` position: relative; - color: ${oldTheme.colors.textPrimary}; box-sizing: border-box; display: flex; align-items: center; @@ -119,34 +107,9 @@ const StyledAdornmentLeft = styled(StyledAdornment)` transform: translateY(-50%); `; -const StyledAdornmentBottom = styled(StyledAdornment)` - left: ${({ theme, $size }) => theme.input.size[$size].paddingLeft}; - bottom: ${({ theme }) => theme.spacing('s')}; -`; - const Wrapper = styled.div` display: flex; flex-direction: column; `; -// TODO: here -const StyledAddon = styled.div` - display: flex; - align-items: center; - width: auto; -`; - -const StyledLeftAddon = styled(StyledAddon)` - border-top-right-radius: ${({ theme }) => theme.input.base.borderRadius}; - border-bottom-right-radius: ${({ theme }) => theme.input.base.borderRadius}; -`; - -export { - StyledAdornmentRight, - StyledAdornmentLeft, - StyledLeftAddon, - StyledAdornmentBottom, - BaseInputWrapper, - StyledBaseInput, - Wrapper -}; +export { StyledAdornmentLeft, StyledAdornmentRight, StyledBaseInput, StyledWrapper, Wrapper }; diff --git a/packages/components/src/Label/Label.style.tsx b/packages/components/src/Label/Label.style.tsx index 706ae80dd..6e49e342d 100644 --- a/packages/components/src/Label/Label.style.tsx +++ b/packages/components/src/Label/Label.style.tsx @@ -1,19 +1,18 @@ import styled from 'styled-components'; -import { LabelPosition, theme } from '@interlay/theme'; +import { LabelPosition } from '@interlay/theme'; type StyledLabelProps = { $position: LabelPosition; }; const StyledLabel = styled.label` - font-weight: ${theme.fontWeight.medium}; - line-height: ${theme.lineHeight.lg}; - font-size: ${theme.text.xs}; - color: ${theme.label.text}; - padding: ${({ $position }) => - $position === 'top' - ? `${theme.spacing.spacing1} 0` - : `${theme.spacing.spacing2} ${theme.spacing.spacing1} 0.438rem 0`}; + ${({ theme }) => theme.typography('xs')} + color: ${({ theme }) => theme.color('light')}; + font-weight: ${({ theme }) => theme.fontWeight('medium')}; + + // FIXME: padding bottom when position is on side + padding: ${({ theme, $position }) => + $position === 'top' ? `${theme.spacing('xs')} 0` : `${theme.spacing('s')} ${theme.spacing('xs')} 0.625rem 0`}; align-self: flex-start; `; diff --git a/packages/components/src/Label/Label.tsx b/packages/components/src/Label/Label.tsx index d7bf4e9a0..a2c0cbdfa 100644 --- a/packages/components/src/Label/Label.tsx +++ b/packages/components/src/Label/Label.tsx @@ -13,7 +13,7 @@ type LabelProps = Props & NativeAttrs; const Label = forwardRef( ({ children, position = 'top', ...props }, ref): JSX.Element => ( - + {children} ) diff --git a/packages/components/src/Modal/Modal.stories.tsx b/packages/components/src/Modal/Modal.stories.tsx index 758b77220..6731ebc01 100644 --- a/packages/components/src/Modal/Modal.stories.tsx +++ b/packages/components/src/Modal/Modal.stories.tsx @@ -19,9 +19,7 @@ const Render = ({ title, footer, children, ...args }: StoryProps) => { setState(false)}> {title && ( <> - - {title} - + {title} )} {children} diff --git a/packages/components/src/Modal/ModalDivider.tsx b/packages/components/src/Modal/ModalDivider.tsx deleted file mode 100644 index 1e9630a48..000000000 --- a/packages/components/src/Modal/ModalDivider.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { DialogDivider, DialogDividerProps } from '../Dialog'; - -type ModalDividerProps = DialogDividerProps; - -const ModalDivider = (props: ModalDividerProps): JSX.Element => ; - -export { ModalDivider }; -export type { ModalDividerProps }; diff --git a/packages/components/src/Modal/index.tsx b/packages/components/src/Modal/index.tsx index d5534e741..f4212748f 100644 --- a/packages/components/src/Modal/index.tsx +++ b/packages/components/src/Modal/index.tsx @@ -2,8 +2,6 @@ export type { ModalProps } from './Modal'; export { Modal } from './Modal'; export type { ModalBodyProps } from './ModalBody'; export { ModalBody } from './ModalBody'; -export type { ModalDividerProps } from './ModalDivider'; -export { ModalDivider } from './ModalDivider'; export type { ModalFooterProps } from './ModalFooter'; export { ModalFooter } from './ModalFooter'; export type { ModalHeaderProps } from './ModalHeader'; diff --git a/packages/components/src/NumberInput/NumberInput.tsx b/packages/components/src/NumberInput/NumberInput.tsx index fcdcc664a..23585035e 100644 --- a/packages/components/src/NumberInput/NumberInput.tsx +++ b/packages/components/src/NumberInput/NumberInput.tsx @@ -26,7 +26,7 @@ type Props = { type InheritAttrs = Omit< BaseInputProps, - keyof Props | 'errorMessageProps' | 'descriptionProps' | 'inputProps' | 'elementType' + keyof Props | 'errorMessageProps' | 'descriptionProps' | 'inputProps' | 'elementType' | 'autoCapitalize' >; type AriaAttrs = Omit, keyof (Props & InheritAttrs)>; diff --git a/packages/components/src/Select/Select.stories.tsx b/packages/components/src/Select/Select.stories.tsx index 337f2bbd9..519199ad0 100644 --- a/packages/components/src/Select/Select.stories.tsx +++ b/packages/components/src/Select/Select.stories.tsx @@ -2,7 +2,6 @@ import { Item } from '@react-stately/collections'; import { Meta, StoryFn, StoryObj } from '@storybook/react'; import { Key, useState } from 'react'; -import { CoinIcon } from '../CoinIcon'; import { Flex } from '../Flex'; import { CTA } from '..'; @@ -12,17 +11,17 @@ const Render = (args: SelectProps) => ( {...args}> - BTC + BTC - ETH + ETH - USDT + USDT diff --git a/packages/components/src/TextArea/TextArea.stories.tsx b/packages/components/src/TextArea/TextArea.stories.tsx index 5581cde0e..a85c39826 100644 --- a/packages/components/src/TextArea/TextArea.stories.tsx +++ b/packages/components/src/TextArea/TextArea.stories.tsx @@ -2,7 +2,7 @@ import { Meta, StoryFn, StoryObj } from '@storybook/react'; import { useState } from 'react'; import { InformationCircle } from '@interlay/icons'; -import { Flex, Span } from '..'; +import { Flex } from '..'; import { TextArea, TextAreaProps } from '.'; @@ -71,15 +71,7 @@ export const Adornments: StoryFn = (args) => (