Skip to content

Commit

Permalink
feat: pills and checkboxes and radios (#3060)
Browse files Browse the repository at this point in the history
* feat: update checkbox and radio styles for One Twilio

* feat: update display pill group for One Twilio design language

* feat(form-pill-group): update the styles for One Twilio Design Updates

* fix: keep track of checked state for svg rendering in disabled states

* chore: changesets

* fix: font weight for pills changed to medium

* fix: always call onChange if passed
  • Loading branch information
SiTaggart committed Mar 7, 2023
1 parent 45cdceb commit 71ce96c
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 48 deletions.
7 changes: 7 additions & 0 deletions .changeset/lazy-owls-change.md
@@ -0,0 +1,7 @@
---
'@twilio-paste/display-pill-group': patch
'@twilio-paste/form-pill-group': patch
'@twilio-paste/core': patch
---

[Display and Form pill group] Update styles for new design language
9 changes: 9 additions & 0 deletions .changeset/mighty-countries-heal.md
@@ -0,0 +1,9 @@
---
'@twilio-paste/base-radio-checkbox': patch
'@twilio-paste/checkbox': patch
'@twilio-paste/inline-control-group': patch
'@twilio-paste/radio-group': patch
'@twilio-paste/core': patch
---

[Checkbox, Radio group] Update to styles for the One Twilio Design Language refresh
6 changes: 6 additions & 0 deletions .changeset/rude-jokes-sniff.md
@@ -0,0 +1,6 @@
---
'@twilio-paste/radio-group': patch
'@twilio-paste/core': patch
---

[Radio group] Improved checked state tracking for uncontrolled radios to help with styling
Expand Up @@ -27,7 +27,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
borderStyle="solid"
borderWidth="borderWidth10"
height="sizeSquare50"
marginX="space20"
marginRight="space20"
marginY="space10"
width="sizeSquare50"
color="colorTextWeakest"
Expand All @@ -38,7 +38,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
_focusSibling={{
borderColor: 'colorBorderPrimaryStronger',
boxShadow: 'shadowFocus',
color: 'colorTextWeakest',
color: 'colorTextInverse',
}}
_activeSibling={
!disabled
Expand All @@ -56,6 +56,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
}}
_disabledSibling={{
borderColor: 'colorBorderWeaker',
backgroundColor: 'colorBackgroundStrong',
}}
_invalidSibling={{
borderColor: 'colorBorderError',
Expand All @@ -72,9 +73,9 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
color: 'colorTextWeakest',
}}
_checkedAndFocusSibling={{
borderColor: 'colorBorderPrimaryStronger',
backgroundColor: 'colorBackgroundPrimaryStronger',
color: 'colorTextWeakest',
borderColor: 'colorBorderPrimary',
backgroundColor: 'colorBackgroundPrimary',
color: 'colorTextInverse',
}}
_checkedAndActiveSibling={
!disabled
Expand All @@ -87,7 +88,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
_checkedAndDisabledSibling={{
borderColor: 'colorBorderWeaker',
backgroundColor: 'colorBackgroundStrong',
color: 'colorTextWeakest',
color: 'colorTextWeaker',
}}
_checkedAndInvalidSibling={{
borderColor: 'colorBorderError',
Expand All @@ -101,7 +102,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
_checkedAndInvalidAndDisabledSibling={{
borderColor: 'colorBorderWeaker',
backgroundColor: 'colorBackgroundStrong',
color: 'colorTextWeakest',
color: 'colorTextWeaker',
}}
{...props}
>
Expand Down Expand Up @@ -141,15 +142,7 @@ export interface BaseRadioCheckboxLabelTextProps extends Omit<TextProps, 'as'>,
const BaseRadioCheckboxLabelText = React.forwardRef<HTMLSpanElement, BaseRadioCheckboxLabelTextProps>(
({children, element = 'BASE_RADIO_CHECKBOX_LABEL_TEXT', ...props}, ref) => {
return (
<Text
as="span"
color="currentColor"
marginLeft="space20"
fontWeight="fontWeightMedium"
element={element}
ref={ref}
{...props}
>
<Text as="span" color="currentColor" marginLeft="space20" element={element} ref={ref} {...props}>
{children}
</Text>
);
Expand All @@ -168,7 +161,7 @@ export interface BaseRadioCheckboxHelpTextProps extends Pick<BoxProps, 'element'
const BaseRadioCheckboxHelpText = React.forwardRef<HTMLSpanElement, BaseRadioCheckboxHelpTextProps>(
({children, helpTextId, element = 'BASE_RADIO_CHECKBOX_HELP_TEXT_WRAPPER'}, ref) => {
return (
<Box as="span" display="block" element={element} marginLeft="space80" ref={ref}>
<Box as="span" display="block" element={element} marginLeft="space70" ref={ref}>
<HelpText id={helpTextId} marginTop="space0">
{children}
</HelpText>
Expand Down
6 changes: 3 additions & 3 deletions packages/paste-core/components/checkbox/src/Checkbox.tsx
Expand Up @@ -20,14 +20,14 @@ const selectAllStyleProps = {
paddingTop: 'space20',
paddingRight: 'space30',
paddingBottom: 'space20',
paddingLeft: 'space20',
paddingLeft: 'space30',
borderRadius: 'borderRadius10',
backgroundColor: 'colorBackground',
};

const selectAllActiveStyleProps = {
...selectAllStyleProps,
backgroundColor: 'colorBackgroundPrimaryWeakest',
backgroundColor: 'colorBackground',
};

const selectAllChildStyleProps = {
Expand Down Expand Up @@ -188,7 +188,7 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
<BaseRadioCheckboxLabel disabled={disabled} htmlFor={checkboxId}>
<BaseRadioCheckboxControl
alignItems="center"
borderRadius="borderRadius10"
borderRadius="borderRadius20"
element={`${element}_CONTROL`}
disabled={disabled}
position="relative"
Expand Down
Expand Up @@ -33,21 +33,28 @@ export const DisplayPill = React.forwardRef<HTMLAnchorElement, DisplayPillProps>
element={element}
as={props.href ? 'a' : 'div'}
alignItems="center"
backgroundColor="colorBackgroundStrong"
backgroundColor="colorBackgroundWeak"
borderRadius="borderRadiusPill"
color="colorText"
boxShadow="shadowBorderWeaker"
color="colorTextWeak"
columnGap="space20"
cursor={props.href ? 'pointer' : 'default'}
display="flex"
fontSize="fontSize20"
fontWeight="fontWeightSemibold"
fontWeight="fontWeightMedium"
lineHeight="lineHeight10"
paddingX="space30"
paddingY="space20"
outline="none"
_hover={{
textDecoration: 'none',
}}
_hover={
props.href
? {
backgroundColor: 'colorBackground',
boxShadow: 'shadowBorder',
textDecoration: 'none',
}
: undefined
}
_focus={{
boxShadow: 'shadowFocus',
textDecoration: 'none',
Expand Down
Expand Up @@ -46,13 +46,15 @@ export const pillStyles: VariantStyles = {
default: {
color: 'colorText',
backgroundColor: 'colorBackgroundPrimaryWeakest',
boxShadow: 'shadowBorderPrimaryWeaker',

_focus: {
boxShadow: 'shadowFocus',
color: 'colorText',
},
_selected: {
backgroundColor: 'colorBackgroundPrimaryStronger',
boxShadow: 'shadowBorderPrimaryStronger',
color: 'colorTextWeakest',
},
_selected_focus: {
Expand All @@ -61,20 +63,23 @@ export const pillStyles: VariantStyles = {
},
_disabled: {
backgroundColor: 'colorBackgroundStrong',
boxShadow: 'shadowBorderWeaker',
cursor: 'not-allowed',
color: 'colorText',
},
},
error: {
backgroundColor: 'colorBackgroundErrorWeakest',
color: 'colorTextErrorStrong',
boxShadow: 'shadowBorderErrorWeaker',
color: 'colorTextError',

_focus: {
boxShadow: 'shadowFocus',
color: 'colorTextErrorStrong',
},
_selected: {
backgroundColor: 'colorBackgroundError',
boxShadow: 'shadowBorderError',
color: 'colorTextInverse',
},
_selected_focus: {
Expand All @@ -83,6 +88,7 @@ export const pillStyles: VariantStyles = {
},
_disabled: {
backgroundColor: 'colorBackgroundStrong',
boxShadow: 'shadowBorderWeaker',
cursor: 'not-allowed',
color: 'colorText',
},
Expand All @@ -93,35 +99,39 @@ export const hoverPillStyles: VariantStyles = {
default: {
cursor: 'pointer',
color: 'colorText',
backgroundColor: 'colorBackgroundPrimaryWeakest',
boxShadow: 'shadowBorderPrimaryWeaker',

_hover: {
borderColor: 'colorBorderPrimaryStronger',
color: 'colorTextLinkStronger',
boxShadow: 'shadowBorderPrimaryStronger',
color: 'colorTextPrimaryStronger',
},
_selected_hover: {
backgroundColor: 'colorBackgroundPrimary',
borderColor: 'transparent',
boxShadow: 'shadowBorderPrimary',
color: 'colorTextInverse',
},
_focus_hover: {
borderColor: 'transparent',
boxShadow: 'shadowFocus',
},
},
error: {
cursor: 'pointer',
color: 'colorTextErrorStrong',
backgroundColor: 'colorBackgroundErrorWeakest',
boxShadow: 'shadowBorderErrorWeaker',
color: 'colorTextError',

_hover: {
borderColor: 'colorBorderErrorStronger',
boxShadow: 'shadowBorderErrorStronger',
color: 'colorTextErrorStronger',
},
_selected_hover: {
backgroundColor: 'colorBackgroundErrorStrongest',
borderColor: 'transparent',
boxShadow: 'shadowBorderErrorStrongest',
color: 'colorTextWeakest',
},
_focus_hover: {
borderColor: 'transparent',
boxShadow: 'shadowFocus',
},
},
};
Expand All @@ -134,13 +144,14 @@ export const baseCloseStyles: VariantStyles = {
default: {
_hover: {
cursor: 'pointer',
borderColor: 'colorBorderPrimaryStronger',
boxShadow: 'shadowBorderPrimaryStronger',
},
},
error: {
_hover: {
backgroundColor: 'colorBackgroundErrorWeakest',
boxShadow: 'shadowBorderErrorStronger',
cursor: 'pointer',
borderColor: 'colorBorderErrorStronger',
},
},
};
Expand All @@ -149,15 +160,15 @@ export const selectedBaseCloseStyles: VariantStyles = {
default: {
_hover: {
cursor: 'pointer',
borderColor: 'transparent',
backgroundColor: 'colorBackgroundPrimary',
boxShadow: 'shadowBorderPrimary',
},
},
error: {
_hover: {
cursor: 'pointer',
borderColor: 'transparent',
backgroundColor: 'colorBackgroundErrorStrongest',
boxShadow: 'shadowBorderErrorStrongest',
},
},
};
Expand All @@ -173,7 +184,7 @@ export const closeColorStyles: VariantStyles = {
default: {
color: 'colorTextIcon',
_hover: {
color: 'colorTextLinkStronger',
color: 'colorTextPrimaryStronger',
},
},
error: {
Expand Down
Expand Up @@ -53,14 +53,12 @@ export const FormPillButton = React.forwardRef<HTMLElement, FormPillStylesProps>
margin="space0"
position="relative"
borderRadius="borderRadiusPill"
borderWidth="borderWidth10"
borderColor="transparent"
borderStyle="solid"
borderStyle="none"
cursor="default"
height="sizeIcon40"
fontFamily="inherit"
fontSize="fontSize20"
fontWeight="fontWeightSemibold"
fontWeight="fontWeightMedium"
outline="none"
paddingLeft="space30"
paddingRight={isDismissable ? 'space80' : 'space30'}
Expand Down
Expand Up @@ -58,7 +58,7 @@ const InlineControlGroup = React.forwardRef<HTMLFieldSetElement, InlineControlGr
{legend}
</Label>
{helpText && <HelpText marginTop="space0">{helpText}</HelpText>}
<Box element={`${element}_SET`} marginLeft="space20" marginRight="space20">
<Box element={`${element}_SET`} marginRight="space20">
{React.Children.map(children, (child) => {
return (
<Box
Expand Down
23 changes: 20 additions & 3 deletions packages/paste-core/components/radio-group/src/Radio.tsx
Expand Up @@ -91,6 +91,12 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
);
}

/*
* Keeps track of the `checked` state on uncontrolled Radios
* in order to properly render the Radio dot icon svg.
*/
const [checkedState, setCheckedState] = React.useState(defaultChecked);

const radioGroupContext = React.useContext(RadioContext);
const helpTextId = useUID();
const radioId = id ? id : useUID();
Expand All @@ -104,8 +110,12 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
} else {
radioGroupContext.onChange(event);
}
if (!isControlled) {
// we need to keep track of checked state when uncontrolled to render the svg correctly
setCheckedState(event.target.checked);
}
},
[onChange, radioGroupContext.onChange]
[onChange, radioGroupContext, isControlled]
);

const state: HiddenRadioState = {
Expand All @@ -130,6 +140,8 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
// Lastly fall back to default checked if state isn't controlled
state.defaultChecked = defaultChecked;
}
// Determines if the checkbox is checked in either controlled or uncontrolled environments specifically for the svg
const mergedChecked = isControlled ? state.checked || state.defaultChecked : checkedState;

return (
<Box
Expand All @@ -156,12 +168,15 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
borderRadius="borderRadiusCircle"
disabled={state.disabled}
type="radio"
_checkedAndDisabledSibling={{
color: 'colorTextWeaker',
}}
>
<Box
as="span"
element={`${element}_CONTROL_CIRCLE`}
lineHeight="lineHeight0"
display="block"
display={mergedChecked ? 'block' : 'none'}
color="inherit"
size="sizeIcon10"
>
Expand All @@ -170,7 +185,9 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
</svg>
</Box>
</BaseRadioCheckboxControl>
<BaseRadioCheckboxLabelText element={`${element}_LABEL_TEXT`}>{children}</BaseRadioCheckboxLabelText>
<BaseRadioCheckboxLabelText element={`${element}_LABEL_TEXT`} fontWeight="fontWeightMedium">
{children}
</BaseRadioCheckboxLabelText>
</BaseRadioCheckboxLabel>
{helpText && (
<BaseRadioCheckboxHelpText element={`${element}_HELP_TEXT_WRAPPER`} helpTextId={helpTextId}>
Expand Down

0 comments on commit 71ce96c

Please sign in to comment.