From 4c76e38cc3b2bdc293640a3388ce36890bad393d Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 16 Jan 2024 11:32:39 -0600 Subject: [PATCH] Toggle invalid states --- src/components/forms/Toggle.tsx | 159 ++++++++++++++++++--------- src/view/screens/Storybook/Forms.tsx | 12 ++ 2 files changed, 117 insertions(+), 54 deletions(-) diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx index 8a9c53a608..875ccbbed5 100644 --- a/src/components/forms/Toggle.tsx +++ b/src/components/forms/Toggle.tsx @@ -12,6 +12,7 @@ type ItemState = { name: string value: boolean disabled: boolean + hasError: boolean hovered: boolean pressed: boolean focused: boolean @@ -22,6 +23,7 @@ const ItemContext = React.createContext({ name: '', value: false, disabled: false, + hasError: false, hovered: false, pressed: false, focused: false, @@ -80,11 +82,12 @@ function Item({ name, value, disabled: disabled ?? false, + hasError: hasError ?? false, hovered, pressed, focused, }), - [labelId, name, value, disabled, hovered, pressed, focused], + [labelId, name, value, disabled, hovered, pressed, focused, hasError], ) return ( @@ -235,47 +238,87 @@ function createSharedToggleStyles({ focused, value, disabled, + hasError, }: { theme: ReturnType value: boolean hovered: boolean focused: boolean disabled: boolean + hasError: boolean }) { - return [ - hovered || focused - ? { - backgroundColor: t.palette.contrast_50, - borderColor: t.palette.contrast_500, - } - : {}, - value - ? { - backgroundColor: - t.name === 'light' ? t.palette.primary_25 : t.palette.primary_900, - borderColor: t.palette.primary_500, - } - : {}, - value && (hovered || focused) - ? { - backgroundColor: - t.name === 'light' ? t.palette.primary_100 : t.palette.primary_800, - borderColor: - t.name === 'light' ? t.palette.primary_600 : t.palette.primary_400, - } - : {}, - disabled - ? { - backgroundColor: t.palette.contrast_200, - borderColor: t.palette.contrast_300, - } - : {}, - ] + const base: ViewStyle[] = [] + const baseHover: ViewStyle[] = [] + const indicator: ViewStyle[] = [] + + if (value) { + base.push({ + backgroundColor: + t.name === 'light' ? t.palette.primary_25 : t.palette.primary_900, + borderColor: t.palette.primary_500, + }) + + if (hovered || focused) { + baseHover.push({ + backgroundColor: + t.name === 'light' ? t.palette.primary_100 : t.palette.primary_800, + borderColor: + t.name === 'light' ? t.palette.primary_600 : t.palette.primary_400, + }) + } + } else { + if (hovered || focused) { + baseHover.push({ + backgroundColor: t.palette.contrast_50, + borderColor: t.palette.contrast_500, + }) + } + } + + if (hasError) { + base.push({ + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: + t.name === 'light' ? t.palette.negative_300 : t.palette.negative_800, + }) + + if (hovered || focused) { + baseHover.push({ + backgroundColor: + t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900, + borderColor: t.palette.negative_500, + }) + } + } + + if (disabled) { + base.push({ + backgroundColor: t.palette.contrast_200, + borderColor: t.palette.contrast_300, + }) + } + + return { + baseStyles: base, + baseHoverStyles: baseHover, + indicatorStyles: indicator, + } } function Checkbox() { const t = useTheme() - const {value, hovered, focused, disabled} = React.useContext(ItemContext) + const {value, hovered, focused, disabled, hasError} = + React.useContext(ItemContext) + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + value, + disabled, + hasError, + }) return ( {value ? ( ) : null} @@ -318,7 +357,17 @@ function Checkbox() { function Switch() { const t = useTheme() - const {value, hovered, focused, disabled} = React.useContext(ItemContext) + const {value, hovered, focused, disabled, hasError} = + React.useContext(ItemContext) + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + value, + disabled, + hasError, + }) return ( @@ -364,7 +409,17 @@ function Switch() { function Radio() { const t = useTheme() - const {value, hovered, focused, disabled} = React.useContext(ItemContext) + const {value, hovered, focused, disabled, hasError} = + React.useContext(ItemContext) + const {baseStyles, baseHoverStyles, indicatorStyles} = + createSharedToggleStyles({ + theme: t, + hovered, + focused, + value, + disabled, + hasError, + }) return ( {value ? ( ) : null} diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx index a6513641be..bd15e7fec4 100644 --- a/src/view/screens/Storybook/Forms.tsx +++ b/src/view/screens/Storybook/Forms.tsx @@ -146,6 +146,10 @@ export function Forms() { Click me + + + Click me + Click me + + + Click me + Click me + + + Click me +