Skip to content

Commit

Permalink
feat(radio): radio themed
Browse files Browse the repository at this point in the history
  • Loading branch information
OlenaKashuba committed Jul 19, 2024
1 parent d0e3438 commit b5dd93b
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-mirrors-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@zopauk/react-components': minor
---

Radio themed
81 changes: 54 additions & 27 deletions src/components/molecules/RadioField/RadioField.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
import React from 'react';
import styled, { keyframes, css } from 'styled-components';
import { colors, typography } from '../../../constants';
import { getBorderColorByStatus } from '../../../helpers/utils';
import InputLabel from '../../atoms/InputLabel/InputLabel';
import SizedContainer from '../../layout/SizedContainer/SizedContainer';
import { FieldProps, InputStatus, InputProps, GroupingControlsProps } from '../../types';
import deprecate from 'util-deprecate';
import { AppTheme, useThemeContext } from '../../styles/Theme';
import { AppTheme, AppThemeProps, useThemeContext } from '../../styles/Theme';

const getCheckedColor = ({ disabled, isValid }: Pick<InputProps, 'disabled' | 'isValid'>) => {
const getCheckedColor = ({
disabled,
hasError,
isValid,
theme,
}: Pick<InputProps, 'disabled' | 'isValid' | 'hasError'> & AppThemeProps) => {
if (isValid) {
return theme.radio.checked.colorByStatus.valid;
}
if (hasError) {
return theme.radio.checked.colorByStatus.error;
}
if (disabled) {
return theme.radio.checked.colorByStatus.disabled;
}
return theme.radio.checked.colorByStatus.default;
};

const getColorByStatus = ({
hasError,
isValid,
disabled,
theme,
}: Pick<InputProps, 'disabled' | 'isValid' | 'hasError'> & AppThemeProps) => {
if (hasError) {
return theme.radio.colorByStatus.error;
}
if (isValid) {
return colors.success;
return theme.radio.colorByStatus.valid;
}
if (disabled) {
return colors.grey;
return theme.radio.colorByStatus.disabled;
}
return colors.brand;
return theme.radio.colorByStatus.default;
};

const zoomIn = keyframes`
Expand Down Expand Up @@ -47,10 +72,10 @@ const Label = styled(InputLabel)<LabelProps & { theme: AppTheme }>`
font-size: ${typography.sizes.text.body};
color: ${colors.greyDarkest};
padding: 14px 16px;
border: 1px solid ${getBorderColorByStatus};
border: 1px solid ${getColorByStatus};
transition-property: border, box-shadow;
transition: 0.2s ease-in-out;
border-radius: 8px;
border-radius: ${({ theme }) => theme.radio.fieldBorderRadius};
position: relative;
margin-bottom: 0;
justify-content: ${(props) => (props.hideControl ? `center` : `left`)};
Expand All @@ -63,7 +88,7 @@ const Label = styled(InputLabel)<LabelProps & { theme: AppTheme }>`
width: 20px;
display: inline-block;
margin-right: 8px;
border: 1px ${getBorderColorByStatus} solid;
border: 1px solid ${getColorByStatus};
box-shadow: 0 0 4px 0 transparent;
transition-property: border, box-shadow;
transition: 0.2s ease-in-out;
Expand All @@ -90,21 +115,6 @@ const Input = styled.input<InputStatus & GroupingControlsProps>`
z-index: -1;
position: absolute;
&:hover:not(:disabled) + label,
&:focus + label {
border-color: ${colors.brand};
box-shadow: 0 0 4px 0 ${colors.brand};
&:before {
border-color: ${colors.brand};
box-shadow: 0 0 4px 0 ${colors.brand};
}
}
&:hover:checked:not(:disabled) + label,
&:focus:checked + label {
&:after {
background-color: ${colors.brand};
}
}
&:disabled + label {
cursor: not-allowed;
color: ${colors.grey};
Expand All @@ -118,11 +128,11 @@ const Input = styled.input<InputStatus & GroupingControlsProps>`
}
&:checked + label {
border-color: ${getCheckedColor};
background-color: ${colors.brandLight};
box-shadow: none;
background-color: ${({ theme }) => theme.radio.checked.bgColor};
box-shadow: ${({ theme }) => theme.radio.checked.boxShadow};
&:before {
border-color: ${getCheckedColor};
box-shadow: none;
box-shadow: ${({ theme }) => theme.radio.checked.boxShadow};
}
&:after {
background-color: ${getCheckedColor};
Expand All @@ -131,6 +141,22 @@ const Input = styled.input<InputStatus & GroupingControlsProps>`
animation: ${zoomIn} 200ms ease-in-out;
}
}
&:hover:not(:disabled) + label,
&:focus + label {
border-color: ${({ theme }) => theme.radio.hover.borderColor};
box-shadow: ${({ theme }) => theme.radio.hover.boxShadow};
background-color: ${({ theme }) => theme.radio.hover.bgColor};
&:before {
border-color: ${({ theme }) => theme.radio.hover.borderColor};
box-shadow: ${({ theme }) => theme.radio.hover.boxShadow};
}
}
&:hover:checked:not(:disabled) + label,
&:focus:checked + label {
&:after {
background-color: ${({ theme }) => theme.radio.checked.radioBgColor};
}
}
${({ hideControl }) =>
hideControl &&
css`
Expand Down Expand Up @@ -172,6 +198,7 @@ const RadioField = ({
value={value}
hideControl={hideControl}
type="radio"
theme={theme}
{...rest}
/>
<Label htmlFor={id} hasError={hasError} isValid={isValid} hideControl={hideControl} theme={theme}>
Expand Down
52 changes: 52 additions & 0 deletions src/components/styles/Theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,32 @@ export interface TypographyTheme {
};
}

export interface RadioTheme {
fieldBorderRadius: string;
colorByStatus: {
default: string;
disabled: string;
error: string;
valid: string;
};
hover: {
borderColor: string;
boxShadow: string;
bgColor: string;
};
checked: {
colorByStatus: {
default: string;
disabled: string;
error: string;
valid: string;
};
bgColor: string;
radioBgColor: string;
boxShadow: string;
};
}

export interface AppTheme {
alert: AlertTheme;
button: ButtonsTheme;
Expand All @@ -299,6 +325,7 @@ export interface AppTheme {
scrollableArea: ScrollableAreaTheme;
spinner: SpinnerTheme;
productTemplate?: ProductTemplate;
radio: RadioTheme;
}

export interface AppThemeProps {
Expand Down Expand Up @@ -598,6 +625,31 @@ export const zopaTheme: AppTheme = {
extraBold: 800,
},
},
radio: {
fieldBorderRadius: '8px',
colorByStatus: {
error: `${colors.alert}`,
valid: `${colors.success}`,
disabled: `${colors.greyLight}`,
default: `${colors.grey}`,
},
hover: {
borderColor: `${colors.brand}`,
boxShadow: `0 0 4px 0 ${colors.brand}`,
bgColor: 'transparent',
},
checked: {
colorByStatus: {
default: `${colors.brand}`,
disabled: `${colors.grey}`,
error: `${colors.brand}`,
valid: `${colors.success}`,
},
bgColor: `${colors.brandLight}`,
radioBgColor: `${colors.brand}`,
boxShadow: `none`,
},
},
};

const ThemeContext = React.createContext<AppTheme>(zopaTheme);
Expand Down

0 comments on commit b5dd93b

Please sign in to comment.