From 05e5227cb88c3e69d009a70f070a73f95eda9e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Pot=C4=99pa?= Date: Wed, 8 Nov 2023 18:05:43 +0100 Subject: [PATCH 01/13] fix(Button): border radius token TET-513 --- src/components/Button/Button.styles.ts | 167 +++++++++++++++++- src/components/Button/Button.tsx | 4 +- .../stylesBuilder/stylesBuilder.test.ts | 7 +- .../Button/stylesBuilder/stylesBuilder.ts | 39 +++- .../ButtonDocs/ButtonSizes.tsx | 6 +- .../ButtonDocs/LoadingButton.tsx | 14 -- src/docs-components/IconButtonDocs.tsx | 20 +-- 7 files changed, 213 insertions(+), 44 deletions(-) delete mode 100644 src/docs-components/ButtonDocs/LoadingButton.tsx diff --git a/src/components/Button/Button.styles.ts b/src/components/Button/Button.styles.ts index ea288cee..9c04ef19 100644 --- a/src/components/Button/Button.styles.ts +++ b/src/components/Button/Button.styles.ts @@ -1,5 +1,9 @@ +import { LoaderProps } from '../Loader'; + import { BaseProps } from '@/types/BaseProps'; +type LoaderAppearance = Pick; + export type DefaultButtonConfig = { appearance?: { primary?: { @@ -39,6 +43,37 @@ export type DefaultButtonConfig = { hasAfterIcon?: BaseProps; } & BaseProps; }; + innerElements?: { + loader?: { + appearance?: { + primary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + success?: LoaderAppearance; + destructive?: LoaderAppearance; + }; + }; + secondary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + success?: LoaderAppearance; + destructive?: LoaderAppearance; + }; + }; + inverted?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + }; + }; + }; } & BaseProps; export type GhostButtonConfig = { @@ -83,6 +118,42 @@ export type GhostButtonConfig = { hasAfterIcon?: BaseProps; } & BaseProps; }; + innerElements?: { + loader?: { + appearance?: { + primary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + success?: LoaderAppearance; + destructive?: LoaderAppearance; + }; + }; + secondary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + inverted?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + reverseInverted?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + }; + }; + }; } & BaseProps; export type BareButtonConfig = { @@ -122,6 +193,42 @@ export type BareButtonConfig = { hasAfterIcon?: BaseProps; } & BaseProps; }; + innerElements?: { + loader?: { + appearance?: { + primary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + success?: LoaderAppearance; + destructive?: LoaderAppearance; + }; + }; + secondary?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + inverted?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + reverseInverted?: + | LoaderAppearance + | { + intent?: { + none?: LoaderAppearance; + }; + }; + }; + }; + }; } & BaseProps; const size = { @@ -178,7 +285,8 @@ const size = { const commonConfig = { display: 'inline-flex', - gap: '$space-component-gap-xSmall', + borderRadius: '$border-radius-large', + gap: '$space-component-gap-small', w: 'fit-content', justifyContent: 'center', alignItems: 'center', @@ -207,7 +315,6 @@ const commonConfig = { const defaultButtonConfig = { ...commonConfig, - borderRadius: '$border-radius-medium', boxShadow: '$elevation-bottom-100', appearance: { primary: { @@ -300,11 +407,25 @@ const defaultButtonConfig = { }, }, size, + innerElements: { + loader: { + appearance: { + primary: { + appearance: 'white', + }, + secondary: { + appearance: 'greyscale', + }, + inverted: { + appearance: 'greyscale', + }, + }, + }, + }, } satisfies DefaultButtonConfig; const ghostButtonConfig = { ...commonConfig, - borderRadius: '$border-radius-large', backgroundColor: { _: 'transparent', hover: '$color-action-ghost-hover', @@ -384,6 +505,26 @@ const ghostButtonConfig = { }, }, size, + innerElements: { + loader: { + appearance: { + primary: { + appearance: 'greyscale', + intent: { + none: { + appearance: 'primary', + }, + }, + }, + secondary: { + appearance: 'greyscale', + }, + inverted: { + appearance: 'greyscale', + }, + }, + }, + }, } satisfies GhostButtonConfig; const bareButtonConfig = { @@ -473,6 +614,26 @@ const bareButtonConfig = { hasAfterIcon: {}, }, }, + innerElements: { + loader: { + appearance: { + primary: { + appearance: 'greyscale', + intent: { + none: { + appearance: 'primary', + }, + }, + }, + secondary: { + appearance: 'greyscale', + }, + inverted: { + appearance: 'greyscale', + }, + }, + }, + }, } satisfies BareButtonConfig; export type ButtonConfig = { diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index b6abe707..626ab9fb 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -57,13 +57,13 @@ export const Button: FC = ({ {state === 'loading' && ( - + )} {beforeIcon && state !== 'loading' && } {children} diff --git a/src/components/Button/stylesBuilder/stylesBuilder.test.ts b/src/components/Button/stylesBuilder/stylesBuilder.test.ts index bbfdc889..1c358923 100644 --- a/src/components/Button/stylesBuilder/stylesBuilder.test.ts +++ b/src/components/Button/stylesBuilder/stylesBuilder.test.ts @@ -23,11 +23,11 @@ describe('stylesBuilder', () => { loading: '$color-action-primary-loading', selected: '$color-action-primary-selected', }, - borderRadius: '$border-radius-medium', + borderRadius: '$border-radius-large', boxShadow: '$elevation-bottom-100', color: '$color-action-inverted-normal', display: 'inline-flex', - gap: '$space-component-gap-xSmall', + gap: '$space-component-gap-small', justifyContent: 'center', opacity: { disabled: '$opacity-disabled', @@ -56,6 +56,9 @@ describe('stylesBuilder', () => { w: 'fit-content', whiteSpace: 'nowrap', }, + loader: { + appearance: 'white', + }, }); }); }); diff --git a/src/components/Button/stylesBuilder/stylesBuilder.ts b/src/components/Button/stylesBuilder/stylesBuilder.ts index c0bda5e3..934aa644 100644 --- a/src/components/Button/stylesBuilder/stylesBuilder.ts +++ b/src/components/Button/stylesBuilder/stylesBuilder.ts @@ -1,3 +1,4 @@ +import { LoaderProps } from '../../Loader'; import { ButtonProps } from '../Button.props'; import { defaultConfig } from '../Button.styles'; @@ -17,6 +18,32 @@ type ButtonStylesBulderInput = { type ButtonStylesBuilder = { container: BaseProps; + loader: Pick; +}; + +const getLoaderProps = ( + loader: object, + props: Pick, +) => { + let loaderProps: Pick = {}; + + if (!('appearance' in loader)) return loader; + + const loaderAppearance = + loader?.appearance?.[props.appearance as keyof typeof loader.appearance]; + + if (loaderAppearance) { + if ('intent' in loaderAppearance) { + const { intent: loaderIntent } = loaderAppearance; + + loaderProps = + loaderIntent?.[props.intent as keyof typeof loaderIntent] || {}; + } else { + loaderProps = loaderAppearance; + } + } + + return loaderProps; }; export const stylesBuilder = ( @@ -26,7 +53,13 @@ export const stylesBuilder = ( defaultConfig, custom: props.custom, }); - const { appearance, size, ...container } = variants[props.variant]; + + const { + appearance, + size, + innerElements: { loader }, + ...container + } = variants[props.variant]; const { hasDropdownIndicator, hasBeforeIcon, hasAfterIcon, ...sizeStyles } = fallbackKey( @@ -68,5 +101,9 @@ export const stylesBuilder = ( ...appearanceStyles, ...intentStyles, }, + loader: getLoaderProps(loader, { + appearance: props.appearance, + intent: props.intent, + }), }; }; diff --git a/src/docs-components/ButtonDocs/ButtonSizes.tsx b/src/docs-components/ButtonDocs/ButtonSizes.tsx index 419bf8dd..e8a34d93 100644 --- a/src/docs-components/ButtonDocs/ButtonSizes.tsx +++ b/src/docs-components/ButtonDocs/ButtonSizes.tsx @@ -1,6 +1,4 @@ -import { LoadingButton } from './LoadingButton'; - -import { ButtonProps } from '@/components/Button'; +import { Button, ButtonProps } from '@/components/Button'; import { tet } from '@/tetrisly'; const getButtonSizes = (variant: ButtonProps['variant']) => { @@ -23,7 +21,7 @@ export const ButtonSizes = ({ variant, ...buttonProps }: ButtonProps) => ( py="$dimension-500" > {getButtonSizes(variant).map((size) => ( - diff --git a/src/docs-components/ButtonDocs/LoadingButton.tsx b/src/docs-components/ButtonDocs/LoadingButton.tsx deleted file mode 100644 index b1b2d30c..00000000 --- a/src/docs-components/ButtonDocs/LoadingButton.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useLoading } from '../hooks/useLoading'; - -import { Button, ButtonProps } from '@/components/Button'; - -export const LoadingButton = (props: ButtonProps) => { - const [isLoading, startLoading] = useLoading(); - return ( -