From 0a10d52f2085db9c979d0253e6e2ab704710cd7a Mon Sep 17 00:00:00 2001 From: Kelly Phan Date: Wed, 2 Oct 2024 17:59:24 +0200 Subject: [PATCH 1/2] feat: migrate selector component to tailwind --- src/components/designSystem/Selector.tsx | 163 +++++++++-------------- src/main.css | 2 +- src/pages/__devOnly/DesignSystem.tsx | 4 + tailwind.config.ts | 10 +- 4 files changed, 78 insertions(+), 101 deletions(-) diff --git a/src/components/designSystem/Selector.tsx b/src/components/designSystem/Selector.tsx index 049f52fe7..53b1f6738 100644 --- a/src/components/designSystem/Selector.tsx +++ b/src/components/designSystem/Selector.tsx @@ -1,7 +1,7 @@ +import { cva } from 'class-variance-authority' import { ReactElement, useState } from 'react' -import styled, { css } from 'styled-components' -import { theme } from '~/styles' +import { tw } from '~/styles/utils' import { Avatar } from './Avatar' import { Icon, IconName } from './Icon' @@ -21,6 +21,44 @@ interface SelectorProps { onClick?: () => Promise | unknown } +const selectorVariants = cva('flex h-18 items-center rounded-xl border p-4', { + variants: { + selected: { + true: 'border-blue-600 bg-blue-100', + false: 'border-grey-400 bg-white', + }, + disabled: { + true: 'cursor-not-allowed bg-grey-100', + false: 'cursor-default', + }, + clickable: { + true: 'cursor-pointer focus-not-active:ring', + }, + fullWidth: { + true: 'w-full', + false: 'min-w-full max-w-full md:min-w-[calc(50%-32px)] md:max-w-[calc(50%-32px)]', + }, + }, + compoundVariants: [ + { + selected: false, + clickable: true, + disabled: false, + class: 'active:bg-grey-200 hover-not-active:bg-grey-100', + }, + { + selected: true, + clickable: true, + disabled: false, + class: 'hover-not-active:bg-blue-200', + }, + ], + defaultVariants: { + fullWidth: true, + selected: false, + }, +}) + export const Selector = ({ title, subtitle, @@ -34,10 +72,21 @@ export const Selector = ({ onClick, }: SelectorProps) => { const [loading, setLoading] = useState(false) + const clickable = !!onClick && !loading && !disabled return ( - { if (loading || disabled) return let result = !!onClick && onClick() @@ -48,12 +97,8 @@ export const Selector = ({ setLoading(false) } }} - $clickable={!!onClick && !loading} - $selected={selected} - $disabled={disabled} - $fullWidth={fullWidth} > - +
{typeof icon === 'string' ? ( @@ -61,8 +106,13 @@ export const Selector = ({ ) : ( icon )} - - +
+
{subtitle} - +
{loading ? ( ) : typeof endIcon === 'string' ? ( @@ -81,98 +131,15 @@ export const Selector = ({ ) : ( endIcon )} -
+ ) } export const SelectorSkeleton = ({ fullWidth = false }: { fullWidth?: boolean } = {}) => ( - +
- +
) export const SELECTOR_HEIGHT = 72 - -const MainIcon = styled.div` - margin-right: ${theme.spacing(3)}; -` - -const ICON_CONTAINER_SIZE = 40 - -const Infos = styled.div<{ $titleFirst?: boolean; $withEndIcon?: boolean }>` - display: flex; - text-align: left; - flex-direction: ${({ $titleFirst }) => ($titleFirst ? 'column' : 'column-reverse')}; - flex: 1; - margin-right: ${theme.spacing(4)}; - // 100 - Container icon size - end icon size (if present) - (padding left + right) - max-width: ${({ $withEndIcon }) => - $withEndIcon - ? `calc(100% - ${ICON_CONTAINER_SIZE}px - ${theme.spacing(4)} - ${theme.spacing(4 * 2)})` - : `calc(100% - ${ICON_CONTAINER_SIZE}px - ${theme.spacing(4 * 2)})`}; -` - -const Container = styled.button<{ - $selected?: boolean - $disabled?: boolean - $clickable?: boolean - $fullWidth?: boolean -}>` - display: flex; - align-items: center; - padding: ${theme.spacing(4)}; - box-sizing: border-box; - height: ${SELECTOR_HEIGHT}px; - background-color: ${({ $selected, $disabled }) => - $selected - ? theme.palette.primary[100] - : $disabled - ? theme.palette.grey[100] - : theme.palette.background.default}; - border: 1px solid - ${({ $selected }) => ($selected ? theme.palette.primary[600] : theme.palette.grey[400])}; - cursor: ${({ $disabled }) => ($disabled ? 'not-allowed' : 'default')}; - - ${({ $fullWidth }) => - !$fullWidth - ? css` - min-width: calc(50% - ${theme.spacing(4 * 2)}); - max-width: calc(50% - ${theme.spacing(4 * 2)}); - ${theme.breakpoints.down('sm')} { - min-width: initial; - max-width: 100%; - } - ` - : css` - width: 100%; - `} - - ${({ $clickable, $selected, $disabled }) => - $clickable && - !$disabled && - css` - cursor: pointer; - :focus:not(:active) { - box-shadow: 0px 0px 0px 4px ${theme.palette.primary[200]}; - border-radius: 12px; - } - - ${() => - !!$clickable && - css` - :hover:not(:active) { - background-color: ${$selected ? theme.palette.primary[200] : theme.palette.grey[100]}; - } - `} - `} - - ${({ $selected, $clickable }) => - !$selected && - $clickable && - css` - :active { - background-color: ${theme.palette.grey[200]}; - } - `} -` diff --git a/src/main.css b/src/main.css index 4e0db82e7..1cf9e7f29 100644 --- a/src/main.css +++ b/src/main.css @@ -15,7 +15,7 @@ body { } a { - @apply text-blue no-underline visited:text-purple hover:underline focus:ring; + @apply text-blue no-underline visited:text-purple hover:underline focus:rounded focus:ring; } b { diff --git a/src/pages/__devOnly/DesignSystem.tsx b/src/pages/__devOnly/DesignSystem.tsx index 5df2eb16c..4bdaf3403 100644 --- a/src/pages/__devOnly/DesignSystem.tsx +++ b/src/pages/__devOnly/DesignSystem.tsx @@ -23,6 +23,7 @@ import { NavigationTab, Popper, Selector, + SelectorSkeleton, ShowMoreText, Skeleton, Status, @@ -487,6 +488,9 @@ const DesignSystem = () => { +
+ +
), }, diff --git a/tailwind.config.ts b/tailwind.config.ts index 396685f04..f4a7a637a 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -134,7 +134,7 @@ const config = { }, }, plugins: [ - plugin(function ({ addUtilities, theme }) { + plugin(function ({ addUtilities, addVariant, theme }) { // Dividers addUtilities({ '.shadow-t': { @@ -153,14 +153,20 @@ const config = { boxShadow: `1px 0px 0px 0px ${theme('colors.grey.300')} inset`, }, }) + // Outline ring addUtilities({ '.ring': { outline: 'none', boxShadow: `0px 0px 0px 4px ${theme('colors.blue.200')}`, - borderRadius: '4px', }, }) + + // Focus not active + addVariant('focus-not-active', '&:focus:not(:active)') + + // Hover not active + addVariant('hover-not-active', '&:hover:not(:active)') }), ], } From fa663a4e1228d1818c039a5d8b1cad9811b510d8 Mon Sep 17 00:00:00 2001 From: Kelly Phan Date: Wed, 2 Oct 2024 18:03:19 +0200 Subject: [PATCH 2/2] feat: migrate selector occurence --- src/pages/settings/Integrations.tsx | 32 +++++++++++++---------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/pages/settings/Integrations.tsx b/src/pages/settings/Integrations.tsx index 8bb52bdf0..905764f3f 100644 --- a/src/pages/settings/Integrations.tsx +++ b/src/pages/settings/Integrations.tsx @@ -186,8 +186,8 @@ const Integrations = () => { ))} ) : ( - <> - + { } }} /> - { }} fullWidth /> - { }} fullWidth /> - { }} fullWidth /> - { }} fullWidth /> - { fullWidth /> {isHubspotFeatureFlagEnabled && ( - { fullWidth /> )} - { } }} /> - { } }} /> - { }} fullWidth /> - { fullWidth /> - { } }} /> - + )} @@ -484,10 +484,6 @@ const Title = styled(Typography)` margin-bottom: ${theme.spacing(2)}; ` -const StyledSelector = styled(Selector)` - margin-bottom: ${theme.spacing(4)}; -` - const Subtitle = styled(Typography)` margin-bottom: ${theme.spacing(8)}; `