From 6333f95d729ac3eff6044349222fb59415949311 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 12 Dec 2023 17:15:54 -0300 Subject: [PATCH 1/8] new button by figma --- src/components/Button/button.test.tsx | 2 +- src/components/Button/index.stories.tsx | 5 - src/components/Button/index.tsx | 63 ++---- src/components/Button/styles.tsx | 257 ++++++++++++++---------- src/components/Button/types.ts | 35 ++++ src/components/Typography/index.tsx | 1 + 6 files changed, 209 insertions(+), 154 deletions(-) create mode 100644 src/components/Button/types.ts diff --git a/src/components/Button/button.test.tsx b/src/components/Button/button.test.tsx index 021af18..684351f 100644 --- a/src/components/Button/button.test.tsx +++ b/src/components/Button/button.test.tsx @@ -21,7 +21,7 @@ describe('Component: Button', () => { // when const { getByText } = render( - , diff --git a/src/components/Button/index.stories.tsx b/src/components/Button/index.stories.tsx index 98e9edb..d283e1b 100644 --- a/src/components/Button/index.stories.tsx +++ b/src/components/Button/index.stories.tsx @@ -31,12 +31,7 @@ const meta: Meta = { component: Button, argTypes: { loading: { control: 'boolean' }, - rounded: { control: 'boolean' }, - contrast: { control: 'boolean' }, - hasBorder: { control: 'boolean' }, disabled: { control: 'boolean' }, - minWidth: { control: 'text' }, - maxWidth: { control: 'text' }, id: { control: 'text' }, testID: { control: 'text' }, }, diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index f572ef1..003a0b9 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -1,52 +1,22 @@ -import { FC, ReactNode } from 'react'; -import { - ButtonVariants, - TypographyVariants, -} from '@platformbuilders/theme-toolkit'; -import RadixIcon from '@radix-ui/react-icons'; +import { FC } from 'react'; import Icons from '../Icons'; import { ContentWrapper, Loading, TextButton, Touchable } from './styles'; - -type TouchableType = { - id?: string; - accessibility: string; - testID?: string; - disabled?: boolean; - onPress?: (param: any) => void; -}; - -export type ButtonProps = { - style?: any; - type?: 'button' | 'submit' | 'reset'; - textStyle?: any; - rounded?: boolean; - loading?: boolean; - contrast?: boolean; - variant?: ButtonVariants; - typographyVariant?: TypographyVariants; - children?: string | ReactNode; - minWidth?: string | number; - maxWidth?: string | number; - leftIconName?: keyof typeof RadixIcon; - rightIconName?: keyof typeof RadixIcon; - hasBorder?: boolean; -} & TouchableType; +import { ButtonProps } from './types'; const Button: FC = ({ id, children, onPress, accessibility, - textStyle = {}, disabled = false, - rounded = false, loading = false, - contrast = false, - hasBorder = false, - variant = 'primary', + fullWidth = false, + variant = 'filled', typographyVariant = 'md', leftIconName, rightIconName, + colorVariant = 'primary', + size = 'normal', ...rest }) => { const LeftIcon = leftIconName ? Icons[leftIconName] : undefined; @@ -58,22 +28,22 @@ const Button: FC = ({ accessibility={accessibility} disabled={loading || disabled} onPress={onPress} - $hasBorder={hasBorder} - $rounded={rounded} variant={variant} + colorVariant={colorVariant} + size={size} {...rest} > {loading ? ( - + ) : ( - + {LeftIcon ? : null} - + {children} {RightIcon ? : null} @@ -84,3 +54,4 @@ const Button: FC = ({ }; export default Button; +export * from './types'; diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index 91709c3..300076c 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -1,52 +1,121 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import { - ButtonVariants, ThemeProps, getTheme, ifStyle, pxToRem, } from '@platformbuilders/theme-toolkit'; -import { getBackgroundColor, getHoverColor, getTextColor } from '../../utils'; import LoadingIndicator from '../LoadingIndicator'; import TouchableComponent from '../Touchable'; -import TypographyComponent from '../Typography'; +import Typography from '../Typography'; +import { ButtonProps } from './types'; -const spacingMd = getTheme('spacing.md'); -const borderWidthSmall = getTheme('borderWidth.sm'); -const buttonRadius = getTheme('borderRadius.sm'); -const minimumSpacing = getTheme('spacing.xs'); +const buttonRadius = getTheme('themeRadius.button'); const isDisabled = ifStyle('disabled'); -const hasBorder = ifStyle('$hasBorder'); -const isRounded = ifStyle('$rounded'); -type ButtonWrapperProps = { - $rounded: boolean; - $hasBorder: boolean; - variant: ButtonVariants; - disabled?: boolean; - style?: any; - minWidth?: string | number; - maxWidth?: string | number; -} & ThemeProps; +type ButtonWrapperProps = ButtonProps & ThemeProps; -const buttonSize = 45; +const getStylesButton = (props: ButtonWrapperProps) => { + const colorButton = + getTheme(`brand.${props.colorVariant}.main`)(props) || + getTheme(`${props.colorVariant}.main`)(props); + const colorConstrastButton = + getTheme(`brand.${props.colorVariant}.contrast`)(props) || + getTheme(`${props.colorVariant}.contrast`)(props); + const defaultTheme = css` + background-color: ${colorButton}; + box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.1); + &:hover { + background-color: ${colorButton}90; + } + .text-button { + color: ${colorConstrastButton}; + } + svg { + color: ${colorConstrastButton}; + } + `; + switch (props.variant) { + case 'filled': + return defaultTheme; + case 'ghost': + return css` + background-color: transparent; + &:hover { + background-color: ${colorButton}10; + } + .text-button { + color: ${colorButton}; + } + svg { + color: ${colorButton}; + } + `; + + case 'tint': + return css` + background-color: ${colorButton}10; + &:hover { + background-color: ${colorButton}20; + } + .text-button { + color: ${colorButton}; + } + svg { + color: ${colorButton}; + } + `; + + case 'outline': + return css` + background-color: transparent; + border: 2px solid ${colorButton}; + &:hover { + background-color: ${colorButton}10; + } + .text-button { + color: ${colorButton}; + } + svg { + color: ${colorButton}; + } + `; + + default: + return defaultTheme; + } +}; + +const sizeButton = { + normal: css` + height: 2.25rem; + font-size: 16px; + border: none; + `, + medium: css` + height: 2.75rem; + font-size: 16px; + border: none; + `, + large: css` + height: 3.25rem; + font-size: 18px; + border: none; + `, +}; export const Touchable = styled(TouchableComponent)` + ${getStylesButton} + ${({ size }) => !!size && sizeButton[size]} + width: ${({ fullWidth }) => (!!fullWidth ? '100%' : undefined)}; + padding: 12px; cursor: ${isDisabled('not-allowed', 'pointer')}; - height: ${buttonSize}px; flex-direction: row; align-items: center; - min-width: ${({ minWidth }: ButtonWrapperProps): string => - `${minWidth || '180px'}`}; - max-width: ${({ maxWidth }: ButtonWrapperProps) => maxWidth || '100%'}; overflow: hidden; - padding: ${isRounded(0, minimumSpacing)}px; - border-radius: ${isRounded(buttonSize / 2, buttonRadius)}px; + border-radius: ${buttonRadius}px; justify-content: center; - border-color: ${getBackgroundColor}; - border-width: ${hasBorder(borderWidthSmall, '0')}px; transition: all 0.2s ease-in-out; - position: relative; display: inline-flex; box-sizing: border-box; @@ -54,92 +123,76 @@ export const Touchable = styled(TouchableComponent)` text-align: center; text-overflow: ellipsis; text-transform: uppercase; - background-color: ${getBackgroundColor}; - box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), - 0 1px 5px 0 rgba(0, 0, 0, 0.12); outline: none; - && { - ::-moz-focus-inner { - border: none; - } - ::before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); - opacity: 0; - transition: opacity 0.2s; - } - ::after { - content: ''; - position: absolute; - left: 50%; - top: 50%; - border-radius: 50%; - padding: 50%; - width: 32px; /* Safari */ - height: 32px; /* Safari */ - background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); - opacity: 0; - transform: translate(-50%, -50%) scale(1); - transition: opacity 1s, transform 0.5s; - } - :hover, - :focus { - background-color: ${getHoverColor}; - } - :hover::before { - opacity: 0.08; - } - :focus::before { - opacity: 0.24; - } - :hover:focus::before { - opacity: 0.3; - } - :active { - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); - } - :active::after { - opacity: 0.32; - transform: translate(-50%, -50%) scale(0); - transition: transform 0s; - } - :disabled { - color: rgba(var(--pure-material-onsurface-rgb, 0, 0, 0), 0.38); - background-color: rgba(var(--pure-material-onsurface-rgb, 0, 0, 0), 0.12); - box-shadow: none; - cursor: initial; - } - :disabled::before { - opacity: 0; - } - :disabled::after { - opacity: 0; - } + &::-moz-focus-inner { + border: none; + } + &::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); + opacity: 0; + transition: opacity 0.2s; + } + &::after { + content: ''; + position: absolute; + left: 50%; + top: 50%; + border-radius: 50%; + padding: 50%; + width: 32px; /* Safari */ + height: 32px; /* Safari */ + background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); + opacity: 0; + transform: translate(-50%, -50%) scale(1); + transition: opacity 1s, transform 0.5s; + } + &:active { + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); + } + &:active::after { + opacity: 0.3; + transform: translate(-50%, -50%) scale(0); + transition: transform 0s; + } + &:disabled { + opacity: 0.3; + cursor: initial; + } + &:disabled::before { + opacity: 0; + } + &:disabled::after { + opacity: 0; } `; -export const ContentWrapper = styled.div` +export const ContentWrapper = styled.div` display: flex; align-items: center; - gap: ${spacingMd}px; + gap: 8px; + flex-direction: row; svg { - color: ${(props) => - getTextColor({ ...props, variant: props.$buttonVariant })}; + width: 20px; + height: 20px; } `; -export const TextButton = styled(TypographyComponent)` +export const TextButton = styled(Typography)` letter-spacing: 0.4px; - color: ${(props) => - getTextColor({ ...props, variant: props.$buttonVariant })}; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 100%; + letter-spacing: 0.8px; `; export const Loading = styled(LoadingIndicator).attrs({ diff --git a/src/components/Button/types.ts b/src/components/Button/types.ts new file mode 100644 index 0000000..37f9d74 --- /dev/null +++ b/src/components/Button/types.ts @@ -0,0 +1,35 @@ +import { ReactNode } from 'react'; +import { TypographyVariants } from '@platformbuilders/theme-toolkit'; +import RadixIcon from '@radix-ui/react-icons'; + +export type ButtonVariants = 'filled' | 'ghost' | 'tint' | 'outline'; +export type ButtonColorType = + | 'primary' + | 'secondary' + | 'accent' + | 'danger' + | 'success' + | 'warning' + | 'info'; + +export type ButtonProps = { + style?: any; + type?: 'button' | 'submit' | 'reset'; + loading?: boolean; + fullWidth?: boolean; + variant?: ButtonVariants; + typographyVariant?: TypographyVariants; + children?: string | ReactNode; + leftIconName?: keyof typeof RadixIcon; + rightIconName?: keyof typeof RadixIcon; + colorVariant?: ButtonColorType; + size?: string; +} & TouchableType; + +export type TouchableType = { + id?: string; + accessibility: string; + testID?: string; + disabled?: boolean; + onPress?: (param: any) => void; +}; diff --git a/src/components/Typography/index.tsx b/src/components/Typography/index.tsx index 77b10c1..481037e 100644 --- a/src/components/Typography/index.tsx +++ b/src/components/Typography/index.tsx @@ -13,6 +13,7 @@ export type TypographyTypeBase = PropsWithChildren<{ export type TypographyTypeProps = TypographyTypeBase & { lineHeightVariant?: TypographyVariants; + className?: string; }; const Typography: FC = ({ From 82dac0847597fedf62e5b2eb540d65bd86686765 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 12 Dec 2023 17:33:16 -0300 Subject: [PATCH 2/8] fix size button --- src/components/Button/styles.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index 300076c..2c0f386 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -88,17 +88,17 @@ const getStylesButton = (props: ButtonWrapperProps) => { const sizeButton = { normal: css` - height: 2.25rem; + min-height: 2.25rem; font-size: 16px; border: none; `, medium: css` - height: 2.75rem; + min-height: 2.75rem; font-size: 16px; border: none; `, large: css` - height: 3.25rem; + min-height: 3.25rem; font-size: 18px; border: none; `, @@ -122,7 +122,6 @@ export const Touchable = styled(TouchableComponent)` vertical-align: middle; text-align: center; text-overflow: ellipsis; - text-transform: uppercase; outline: none; &::-moz-focus-inner { From 01deb9c7e93d6a07210493a96b04498076928e88 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 12 Dec 2023 18:05:25 -0300 Subject: [PATCH 3/8] fix border --- src/components/Button/styles.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index 2c0f386..2f9fe92 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -90,17 +90,14 @@ const sizeButton = { normal: css` min-height: 2.25rem; font-size: 16px; - border: none; `, medium: css` min-height: 2.75rem; font-size: 16px; - border: none; `, large: css` min-height: 3.25rem; font-size: 18px; - border: none; `, }; From f821982731de4edcd9e7498ad43dd394c17ccbd0 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 12 Dec 2023 20:52:02 -0300 Subject: [PATCH 4/8] remove font-size of button added padding from theme --- src/components/Button/styles.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index 2f9fe92..0c2410d 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -11,6 +11,8 @@ import Typography from '../Typography'; import { ButtonProps } from './types'; const buttonRadius = getTheme('themeRadius.button'); +const spacingSm = getTheme('spacing.sm'); +const borderWidthSm = getTheme('borderWidth.sm'); const isDisabled = ifStyle('disabled'); type ButtonWrapperProps = ButtonProps & ThemeProps; @@ -69,7 +71,7 @@ const getStylesButton = (props: ButtonWrapperProps) => { case 'outline': return css` background-color: transparent; - border: 2px solid ${colorButton}; + border: ${borderWidthSm}px solid ${colorButton}; &:hover { background-color: ${colorButton}10; } @@ -89,15 +91,12 @@ const getStylesButton = (props: ButtonWrapperProps) => { const sizeButton = { normal: css` min-height: 2.25rem; - font-size: 16px; `, medium: css` min-height: 2.75rem; - font-size: 16px; `, large: css` min-height: 3.25rem; - font-size: 18px; `, }; @@ -105,7 +104,7 @@ export const Touchable = styled(TouchableComponent)` ${getStylesButton} ${({ size }) => !!size && sizeButton[size]} width: ${({ fullWidth }) => (!!fullWidth ? '100%' : undefined)}; - padding: 12px; + padding: ${spacingSm}px; cursor: ${isDisabled('not-allowed', 'pointer')}; flex-direction: row; align-items: center; @@ -184,7 +183,6 @@ export const ContentWrapper = styled.div` export const TextButton = styled(Typography)` letter-spacing: 0.4px; - font-size: 16px; font-style: normal; font-weight: 600; line-height: 100%; From 1b249284966b5b7ef7fb841f8b95fed8541f1c30 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Dec 2023 14:24:19 -0300 Subject: [PATCH 5/8] fix border Button --- package.json | 4 ++-- src/components/Button/styles.tsx | 1 + src/components/Button/types.ts | 16 +++++----------- yarn.lock | 8 ++++---- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 3881407..5de4a41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@platformbuilders/fluid-react", - "version": "1.1.3", + "version": "1.2.0", "private": false, "description": "Builders React for Fluid Design System", "keywords": [ @@ -47,7 +47,7 @@ }, "dependencies": { "@platformbuilders/helpers": "0.10.2", - "@platformbuilders/theme-toolkit": "0.2.6", + "@platformbuilders/theme-toolkit": "^0.3.0", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-select": "^1.2.2", diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index 0c2410d..d24d600 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -101,6 +101,7 @@ const sizeButton = { }; export const Touchable = styled(TouchableComponent)` + border: none; ${getStylesButton} ${({ size }) => !!size && sizeButton[size]} width: ${({ fullWidth }) => (!!fullWidth ? '100%' : undefined)}; diff --git a/src/components/Button/types.ts b/src/components/Button/types.ts index 37f9d74..70eb954 100644 --- a/src/components/Button/types.ts +++ b/src/components/Button/types.ts @@ -1,17 +1,11 @@ import { ReactNode } from 'react'; -import { TypographyVariants } from '@platformbuilders/theme-toolkit'; +import { + ButtonColorType, + ButtonVariants, + TypographyVariants, +} from '@platformbuilders/theme-toolkit'; import RadixIcon from '@radix-ui/react-icons'; -export type ButtonVariants = 'filled' | 'ghost' | 'tint' | 'outline'; -export type ButtonColorType = - | 'primary' - | 'secondary' - | 'accent' - | 'danger' - | 'success' - | 'warning' - | 'info'; - export type ButtonProps = { style?: any; type?: 'button' | 'submit' | 'reset'; diff --git a/yarn.lock b/yarn.lock index 54a9892..fb6b125 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,10 +2725,10 @@ dependencies: lint-staged "^13.2.2" -"@platformbuilders/theme-toolkit@0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@platformbuilders/theme-toolkit/-/theme-toolkit-0.2.6.tgz#532a712bcce6d43cee76f90f4a0d0a913250dffb" - integrity sha512-uoRf3D2dszihYYHF/KP1iC6Gc0uzeri16/bw6ZVlBeDdFFDZbSc7RFcXePbU6Hg6hbuN7n4bSVB0g0Wyg5qhBQ== +"@platformbuilders/theme-toolkit@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@platformbuilders/theme-toolkit/-/theme-toolkit-0.3.0.tgz#eff59fd6693e9e59a6d65b304d22dd204cb7793c" + integrity sha512-6/Ifts8C1DeQaavmOM5JnZRfFL/qJRdfzKgUeB1B01iDEIiIzpDNGp6bn2oGd5JnDkXpwgnCuuo4K0InoYPnwA== dependencies: "@platformbuilders/helpers" "0.8.2" lodash "4.17.21" From cb19b83747e3753da189d2bb91cfaaaa84ff6460 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Dec 2023 14:37:23 -0300 Subject: [PATCH 6/8] fix version theme-toolkit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5de4a41..2aa5a91 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ }, "dependencies": { "@platformbuilders/helpers": "0.10.2", - "@platformbuilders/theme-toolkit": "^0.3.0", + "@platformbuilders/theme-toolkit": "0.3.0", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-select": "^1.2.2", From 9257b0371c8f44d0c8a5e97cac526d9f73f5ab24 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Dec 2023 14:43:24 -0300 Subject: [PATCH 7/8] added type size --- src/components/Button/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Button/types.ts b/src/components/Button/types.ts index 70eb954..5321c54 100644 --- a/src/components/Button/types.ts +++ b/src/components/Button/types.ts @@ -17,7 +17,7 @@ export type ButtonProps = { leftIconName?: keyof typeof RadixIcon; rightIconName?: keyof typeof RadixIcon; colorVariant?: ButtonColorType; - size?: string; + size?: 'normal' | 'medium' | 'large'; } & TouchableType; export type TouchableType = { From afcd72bdf1f620eacaa9da2dd189358f84c56c42 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Dec 2023 14:45:25 -0300 Subject: [PATCH 8/8] remove material var css --- src/components/Button/styles.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx index d24d600..c7975d6 100644 --- a/src/components/Button/styles.tsx +++ b/src/components/Button/styles.tsx @@ -131,7 +131,7 @@ export const Touchable = styled(TouchableComponent)` bottom: 0; left: 0; right: 0; - background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); + background-color: rgb(255, 255, 255); opacity: 0; transition: opacity 0.2s; } @@ -144,7 +144,7 @@ export const Touchable = styled(TouchableComponent)` padding: 50%; width: 32px; /* Safari */ height: 32px; /* Safari */ - background-color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255)); + background-color: rgb(255, 255, 255); opacity: 0; transform: translate(-50%, -50%) scale(1); transition: opacity 1s, transform 0.5s;