From 4dfb7a4cd7e7e0ef9a780a741ec78aa58e444e11 Mon Sep 17 00:00:00 2001 From: Elvira Date: Thu, 11 Jan 2024 21:10:45 +0300 Subject: [PATCH 1/5] feat: adds checkboxes, radio buttons, toggles --- src/5_shared/assets/icons/actions/tick.svg | 2 +- .../CustomCheckbox/CustomCheckbox.module.scss | 70 ++++++++++++ .../ui/CustomCheckbox/CustomCheckbox.tsx | 75 +++++++++++++ .../ui/CustomRadio/CustomRadio.module.scss | 84 ++++++++++++++ src/5_shared/ui/CustomRadio/CustomRadio.tsx | 67 +++++++++++ .../ui/CustomToggle/CustomToggle.module.scss | 104 ++++++++++++++++++ src/5_shared/ui/CustomToggle/CustomToggle.tsx | 59 ++++++++++ 7 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss create mode 100644 src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx create mode 100644 src/5_shared/ui/CustomRadio/CustomRadio.module.scss create mode 100644 src/5_shared/ui/CustomRadio/CustomRadio.tsx create mode 100644 src/5_shared/ui/CustomToggle/CustomToggle.module.scss create mode 100644 src/5_shared/ui/CustomToggle/CustomToggle.tsx diff --git a/src/5_shared/assets/icons/actions/tick.svg b/src/5_shared/assets/icons/actions/tick.svg index cea3353..a2fcc91 100644 --- a/src/5_shared/assets/icons/actions/tick.svg +++ b/src/5_shared/assets/icons/actions/tick.svg @@ -1,3 +1,3 @@ - + diff --git a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss new file mode 100644 index 0000000..7ccd769 --- /dev/null +++ b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss @@ -0,0 +1,70 @@ +@import '@styles/colors.scss'; + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + border: 0; + clip: rect(0 0 0 0); + overflow: hidden; +} + +.checkbox { + position: relative; + display: flex; + align-items: center; + padding: 0; + + &--right { + justify-content: space-between; + } +} + +.checkbox__icon { + display: flex; + margin-right: 10px; + justify-content: center; + align-items: center; + width: 24px; + height: 24px; + box-sizing: border-box; + border: 2px solid $neutral-text-light-color; + border-radius: 6px; + color: rgb(255, 255, 255, 0); + + &--right { + margin-right: 0; + } + + &--error { + border: 2px solid $danger-bright-color; + } +} + +label:hover .checkbox__icon { + border-color: $primary-background-color; +} + +input:checked ~ .checkbox__icon { + background-color: $primary-button-active-color; + border: 2px solid $primary-button-active-color; + color: $neutral-background-main-color; +} + +input:disabled ~ .checkbox__icon { + background-color: $neutral-background-second-color; + border: 2px solid $neutral-line-color; +} + +input:checked:disabled ~ .checkbox__icon { + background-color: $neutral-background-second-color; + border: 2px solid $neutral-text-light-color; + color: $neutral-text-light-color; +} + +.checkbox__label { + font-size: 14px; + line-height: 16px; +} diff --git a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx new file mode 100644 index 0000000..d727a6a --- /dev/null +++ b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx @@ -0,0 +1,75 @@ +import cx from 'classnames'; +import { ChangeEvent } from 'react'; + +import SvgIconTick from '@assets/icons/actions/tick.svg?react'; + +import styles from './CustomCheckbox.module.scss'; + +interface CustomCheckboxProps { + name: string; + value?: string; + id?: string; + onChange?: (event: ChangeEvent) => void; + inputClassName?: string; + labelClassName?: string; + labelText?: string; + isDisabled?: boolean; + isChecked?: boolean; + isPositionRight?: boolean; + isError?: boolean; +} + +export const CustomCheckbox = ({ + name, + value, + id, + onChange, + inputClassName, + labelClassName, + labelText, + isDisabled, + isChecked, + isPositionRight, + isError, +}: CustomCheckboxProps) => { + return ( + + ); +}; diff --git a/src/5_shared/ui/CustomRadio/CustomRadio.module.scss b/src/5_shared/ui/CustomRadio/CustomRadio.module.scss new file mode 100644 index 0000000..de91a1d --- /dev/null +++ b/src/5_shared/ui/CustomRadio/CustomRadio.module.scss @@ -0,0 +1,84 @@ +@import '@styles/colors.scss'; + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + border: 0; + clip: rect(0 0 0 0); + overflow: hidden; +} + +.radio { + position: relative; + display: flex; + align-items: center; + padding: 0; + + &--right { + justify-content: space-between; + } +} + +.radio__icon { + display: flex; + margin-right: 10px; + justify-content: center; + align-items: center; + width: 24px; + height: 24px; + box-sizing: border-box; + background-color: $neutral-background-main-color; + border: 2px solid $neutral-text-light-color; + border-radius: 50%; + + &--right { + margin-right: 0; + } + + &--error { + border: 2px solid $danger-bright-color; + } +} + +label:hover .radio__icon { + border-color: $primary-background-color; +} + +input:checked ~ .radio__icon { + background-color: $primary-button-active-color; + border: 2px solid $primary-button-active-color; +} + +input:checked ~ .radio__icon::before { + content: ''; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: $neutral-background-main-color; +} + +input:disabled ~ .radio__icon { + background-color: $neutral-background-second-color; + border: 2px solid $neutral-line-color; +} + +input:checked:disabled ~ .radio__icon { + background-color: $neutral-background-main-color; + border: 2px solid $neutral-text-light-color; +} + +input:checked:disabled ~ .radio__icon::before { + content: ''; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: $neutral-text-light-color; +} + +.radio__label { + font-size: 14px; + line-height: 16px; +} diff --git a/src/5_shared/ui/CustomRadio/CustomRadio.tsx b/src/5_shared/ui/CustomRadio/CustomRadio.tsx new file mode 100644 index 0000000..e863835 --- /dev/null +++ b/src/5_shared/ui/CustomRadio/CustomRadio.tsx @@ -0,0 +1,67 @@ +import cx from 'classnames'; +import { ChangeEvent } from 'react'; + +import styles from './CustomRadio.module.scss'; + +interface CustomRadioProps { + name: string; + value: string; + id?: string; + onChange?: (event: ChangeEvent) => void; + inputClassName?: string; + labelClassName?: string; + labelText?: string; + isDisabled?: boolean; + isChecked?: boolean; + isPositionRight?: boolean; + isError?: boolean; +} + +export const CustomRadio = ({ + name, + value, + id, + onChange, + inputClassName, + labelClassName, + labelText, + isDisabled, + isChecked, + isPositionRight, + isError, +}: CustomRadioProps) => { + return ( + + ); +}; diff --git a/src/5_shared/ui/CustomToggle/CustomToggle.module.scss b/src/5_shared/ui/CustomToggle/CustomToggle.module.scss new file mode 100644 index 0000000..b4ce9f5 --- /dev/null +++ b/src/5_shared/ui/CustomToggle/CustomToggle.module.scss @@ -0,0 +1,104 @@ +@import '@styles/colors.scss'; + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + border: 0; + clip: rect(0 0 0 0); + overflow: hidden; +} + +.toggle { + position: relative; + display: flex; + align-items: center; + padding: 0; + + &--right { + justify-content: space-between; + } +} + +.toggle__icon { + position: relative; + margin-right: 10px; + justify-content: center; + align-items: center; + width: 48px; + height: 24px; + box-sizing: border-box; + background-color: $neutral-text-light-color; + border: 2px solid $neutral-text-light-color; + border-radius: 12px; + + &--right { + margin-right: 0; + } +} + +.toggle__icon::before { + content: ''; + position: absolute; + top: 2px; + left: 3px; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: $neutral-background-main-color; +} + +input:checked ~ .toggle__icon { + background-color: $primary-button-active-color; + border: 2px solid $primary-button-active-color; +} + +input:checked ~ .toggle__icon::before { + content: ''; + position: absolute; + top: 2px; + left: 26px; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: $neutral-background-main-color; +} + +input:disabled ~ .toggle__icon { + background-color: $neutral-line-color; + border: 2px solid $neutral-line-color; +} + +input:disabled ~ .toggle__icon::before { + content: ''; + position: absolute; + top: 2px; + left: 3px; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: $neutral-background-main-color; +} + +input:checked:disabled ~ .toggle__icon { + background-color: $neutral-line-color; + border: 2px solid$neutral-line-color; +} + +input:checked:disabled ~ .toggle__icon::before { + content: ''; + position: absolute; + top: 2px; + left: 26px; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: $neutral-background-main-color; +} + +.toggle__label { + font-size: 14px; + line-height: 16px; +} diff --git a/src/5_shared/ui/CustomToggle/CustomToggle.tsx b/src/5_shared/ui/CustomToggle/CustomToggle.tsx new file mode 100644 index 0000000..0139e5b --- /dev/null +++ b/src/5_shared/ui/CustomToggle/CustomToggle.tsx @@ -0,0 +1,59 @@ +import cx from 'classnames'; +import { ChangeEvent } from 'react'; + +import styles from './CustomToggle.module.scss'; + +interface CustomToggleProps { + name: string; + value?: string; + id?: string; + onChange?: (event: ChangeEvent) => void; + inputClassName?: string; + labelClassName?: string; + labelText?: string; + isDisabled?: boolean; + isChecked?: boolean; + isPositionRight?: boolean; +} + +export const CustomToggle = ({ + name, + value, + id, + onChange, + inputClassName, + labelClassName, + labelText, + isDisabled, + isChecked, + isPositionRight, +}: CustomToggleProps) => { + return ( + + ); +}; From 0fa8c386f9060fb3ed26258bd75b069a3248160a Mon Sep 17 00:00:00 2001 From: Elvira Date: Fri, 19 Jan 2024 16:26:03 +0300 Subject: [PATCH 2/5] feat: improves style naming in checkboxes and radio buttons --- .../CustomCheckbox/CustomCheckbox.module.scss | 14 ++++++------- .../ui/CustomCheckbox/CustomCheckbox.tsx | 16 +++++---------- .../ui/CustomRadio/CustomRadio.module.scss | 18 ++++++++--------- src/5_shared/ui/CustomRadio/CustomRadio.tsx | 16 +++++---------- .../ui/CustomToggle/CustomToggle.module.scss | 20 +++++++++---------- src/5_shared/ui/CustomToggle/CustomToggle.tsx | 10 +++++----- 6 files changed, 41 insertions(+), 53 deletions(-) diff --git a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss index 7ccd769..116e272 100644 --- a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss +++ b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.module.scss @@ -1,6 +1,6 @@ @import '@styles/colors.scss'; -.visually-hidden { +.visuallyHidden { position: absolute; width: 1px; height: 1px; @@ -22,7 +22,7 @@ } } -.checkbox__icon { +.icon { display: flex; margin-right: 10px; justify-content: center; @@ -43,28 +43,28 @@ } } -label:hover .checkbox__icon { +label:hover .icon { border-color: $primary-background-color; } -input:checked ~ .checkbox__icon { +input:checked ~ .icon { background-color: $primary-button-active-color; border: 2px solid $primary-button-active-color; color: $neutral-background-main-color; } -input:disabled ~ .checkbox__icon { +input:disabled ~ .icon { background-color: $neutral-background-second-color; border: 2px solid $neutral-line-color; } -input:checked:disabled ~ .checkbox__icon { +input:checked:disabled ~ .icon { background-color: $neutral-background-second-color; border: 2px solid $neutral-text-light-color; color: $neutral-text-light-color; } -.checkbox__label { +.label { font-size: 14px; line-height: 16px; } diff --git a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx index d727a6a..5026f07 100644 --- a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx +++ b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx @@ -41,7 +41,7 @@ export const CustomCheckbox = ({ value={value} name={name} id={id} - className={cx(styles['visually-hidden'], inputClassName)} + className={cx(styles.visuallyHidden, inputClassName)} onChange={onChange} disabled={isDisabled} checked={isChecked} @@ -49,25 +49,19 @@ export const CustomCheckbox = ({ {isPositionRight ? ( <> - {labelText} + {labelText} ) : ( <> - + - {labelText} + {labelText} )} diff --git a/src/5_shared/ui/CustomRadio/CustomRadio.module.scss b/src/5_shared/ui/CustomRadio/CustomRadio.module.scss index de91a1d..facb32e 100644 --- a/src/5_shared/ui/CustomRadio/CustomRadio.module.scss +++ b/src/5_shared/ui/CustomRadio/CustomRadio.module.scss @@ -1,6 +1,6 @@ @import '@styles/colors.scss'; -.visually-hidden { +.visuallyHidden { position: absolute; width: 1px; height: 1px; @@ -22,7 +22,7 @@ } } -.radio__icon { +.icon { display: flex; margin-right: 10px; justify-content: center; @@ -43,16 +43,16 @@ } } -label:hover .radio__icon { +label:hover .icon { border-color: $primary-background-color; } -input:checked ~ .radio__icon { +input:checked ~ .icon { background-color: $primary-button-active-color; border: 2px solid $primary-button-active-color; } -input:checked ~ .radio__icon::before { +input:checked ~ .icon::before { content: ''; width: 8px; height: 8px; @@ -60,17 +60,17 @@ input:checked ~ .radio__icon::before { background-color: $neutral-background-main-color; } -input:disabled ~ .radio__icon { +input:disabled ~ .icon { background-color: $neutral-background-second-color; border: 2px solid $neutral-line-color; } -input:checked:disabled ~ .radio__icon { +input:checked:disabled ~ .icon { background-color: $neutral-background-main-color; border: 2px solid $neutral-text-light-color; } -input:checked:disabled ~ .radio__icon::before { +input:checked:disabled ~ .icon::before { content: ''; width: 8px; height: 8px; @@ -78,7 +78,7 @@ input:checked:disabled ~ .radio__icon::before { background-color: $neutral-text-light-color; } -.radio__label { +.label { font-size: 14px; line-height: 16px; } diff --git a/src/5_shared/ui/CustomRadio/CustomRadio.tsx b/src/5_shared/ui/CustomRadio/CustomRadio.tsx index e863835..3310b93 100644 --- a/src/5_shared/ui/CustomRadio/CustomRadio.tsx +++ b/src/5_shared/ui/CustomRadio/CustomRadio.tsx @@ -37,7 +37,7 @@ export const CustomRadio = ({ name={name} value={value} id={id} - className={cx(styles['visually-hidden'], inputClassName)} + className={cx(styles.visuallyHidden, inputClassName)} onChange={onChange} disabled={isDisabled} checked={isChecked} @@ -45,21 +45,15 @@ export const CustomRadio = ({ {isPositionRight ? ( <> - {labelText} + {labelText} ) : ( <> - - {labelText} + + {labelText} )} diff --git a/src/5_shared/ui/CustomToggle/CustomToggle.module.scss b/src/5_shared/ui/CustomToggle/CustomToggle.module.scss index b4ce9f5..6b2fd6a 100644 --- a/src/5_shared/ui/CustomToggle/CustomToggle.module.scss +++ b/src/5_shared/ui/CustomToggle/CustomToggle.module.scss @@ -1,6 +1,6 @@ @import '@styles/colors.scss'; -.visually-hidden { +.visuallyHidden { position: absolute; width: 1px; height: 1px; @@ -22,7 +22,7 @@ } } -.toggle__icon { +.icon { position: relative; margin-right: 10px; justify-content: center; @@ -39,7 +39,7 @@ } } -.toggle__icon::before { +.icon::before { content: ''; position: absolute; top: 2px; @@ -50,12 +50,12 @@ background-color: $neutral-background-main-color; } -input:checked ~ .toggle__icon { +input:checked ~ .icon { background-color: $primary-button-active-color; border: 2px solid $primary-button-active-color; } -input:checked ~ .toggle__icon::before { +input:checked ~ .icon::before { content: ''; position: absolute; top: 2px; @@ -66,12 +66,12 @@ input:checked ~ .toggle__icon::before { background-color: $neutral-background-main-color; } -input:disabled ~ .toggle__icon { +input:disabled ~ .icon { background-color: $neutral-line-color; border: 2px solid $neutral-line-color; } -input:disabled ~ .toggle__icon::before { +input:disabled ~ .icon::before { content: ''; position: absolute; top: 2px; @@ -82,12 +82,12 @@ input:disabled ~ .toggle__icon::before { background-color: $neutral-background-main-color; } -input:checked:disabled ~ .toggle__icon { +input:checked:disabled ~ .icon { background-color: $neutral-line-color; border: 2px solid$neutral-line-color; } -input:checked:disabled ~ .toggle__icon::before { +input:checked:disabled ~ .icon::before { content: ''; position: absolute; top: 2px; @@ -98,7 +98,7 @@ input:checked:disabled ~ .toggle__icon::before { background-color: $neutral-background-main-color; } -.toggle__label { +.label { font-size: 14px; line-height: 16px; } diff --git a/src/5_shared/ui/CustomToggle/CustomToggle.tsx b/src/5_shared/ui/CustomToggle/CustomToggle.tsx index 0139e5b..2a2a697 100644 --- a/src/5_shared/ui/CustomToggle/CustomToggle.tsx +++ b/src/5_shared/ui/CustomToggle/CustomToggle.tsx @@ -37,7 +37,7 @@ export const CustomToggle = ({ name={name} value={value} id={id} - className={cx(styles['visually-hidden'], inputClassName)} + className={cx(styles.visuallyHidden, inputClassName)} onChange={onChange} disabled={isDisabled} checked={isChecked} @@ -45,13 +45,13 @@ export const CustomToggle = ({ {isPositionRight ? ( <> - {labelText} - + {labelText} + ) : ( <> - - {labelText} + + {labelText} )} From 278cec34d4155c9d989912898d724d49bbbfaaa4 Mon Sep 17 00:00:00 2001 From: Elvira Date: Fri, 19 Jan 2024 23:44:37 +0300 Subject: [PATCH 3/5] feat: optimizes classname use --- src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx | 8 +++++--- src/5_shared/ui/CustomRadio/CustomRadio.tsx | 8 +++++--- src/5_shared/ui/CustomToggle/CustomToggle.tsx | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx index 5026f07..3320a38 100644 --- a/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx +++ b/src/5_shared/ui/CustomCheckbox/CustomCheckbox.tsx @@ -34,7 +34,9 @@ export const CustomCheckbox = ({ }: CustomCheckboxProps) => { return (