Skip to content

Commit

Permalink
feat(vara-ui): add transitions, dark mode and error state to Radio (#…
Browse files Browse the repository at this point in the history
…1697)

Co-authored-by: Nikita Yutanov <[email protected]>
  • Loading branch information
ereburg and nikitayutanov authored Jan 15, 2025
1 parent ac15549 commit 27b6da3
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 18 deletions.
2 changes: 2 additions & 0 deletions utils/vara-ui/src/components/checkbox/checkbox.stories.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Meta, StoryObj } from '@storybook/react';

import { Checkbox } from './checkbox';

type Type = typeof Checkbox;
Expand All @@ -23,6 +24,7 @@ const meta: Meta<Type> = {
options: ['checkbox', 'switch'],
control: { type: 'select' },
},
error: { control: 'text' },
},
};

Expand Down
4 changes: 2 additions & 2 deletions utils/vara-ui/src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InputHTMLAttributes, forwardRef } from 'react';
import { InputHTMLAttributes, ReactNode, forwardRef } from 'react';
import cx from 'clsx';

import styles from './checkbox.module.scss';
Expand All @@ -7,7 +7,7 @@ type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> & {
label: string;
type?: 'switch' | 'checkbox';
size?: 'small' | 'default';
error?: string;
error?: ReactNode;
};

const Checkbox = forwardRef<HTMLInputElement, Props>(
Expand Down
83 changes: 75 additions & 8 deletions utils/vara-ui/src/components/radio/radio.module.scss
Original file line number Diff line number Diff line change
@@ -1,24 +1,91 @@
@use '../../utils.scss' as *;

.label {
@include lightDark(color, #000, #fff);

display: flex;
align-items: center;
cursor: pointer;

&.disabled {
font-size: var(--font-size);
font-weight: 400;
line-height: var(--line-height);

&:has(:disabled) {
pointer-events: none;
opacity: 0.3;
}
}

.input {
appearance: none;
cursor: inherit;
margin: 0 10px 0 0;
margin: 0;
}

.box {
@include lightDark(background-color, transparent, rgba(255, 255, 255, 0.03));
@include lightDark(--border-color, #d0d5dd, rgba(255, 255, 255, 0.04));
@include lightDark(--checked-color, #0ed3a3, #00ffc4);
@include lightDark(--error-color, rgba(255, 50, 49, 0.8), #d73b4f);
@include lightDark(--disabled-color, #eceded, rgba(40, 44, 48, 0.1));

width: var(--size);
height: var(--size);
margin-right: 10px;

display: flex;
align-items: center;
justify-content: center;

border: 1px solid var(--border-color);
border-radius: 50%;

transition: background-color 0.25s ease, border-color 0.25s ease;

&::before {
content: '';

width: 7px;
height: 7px;

width: 15px;
height: 15px;
background-image: url("data:image/svg+xml,%3Csvg width='15' height='15' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='7.5' cy='7.5' r='7' stroke='%23909090'/%3E%3C/svg%3E");
border-radius: 50%;

&:checked {
background-image: url("data:image/svg+xml,%3Csvg width='15' height='15' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='7.5' cy='7.5' r='3.5' fill='%230ED3A3'/%3E%3Ccircle cx='7.5' cy='7.5' r='7' stroke='%230ED3A3'/%3E%3C/svg%3E");
transition: background-color 0.25s ease;

.input:not(:disabled):checked + & {
background-color: var(--checked-color);
}

.input:not(:disabled):checked[aria-invalid='true'] + & {
background-color: var(--error-color);
}

.input:disabled:checked + & {
background-color: var(--border-color);
}
}

.input:not(:disabled):checked + & {
border-color: var(--checked-color);
}

.input:not(:disabled)[aria-invalid='true'] + & {
border-color: var(--error-color);
}

.input:disabled:not(:checked) + & {
background-color: var(--disabled-color);
}
}

.small {
--size: 15px;
--font-size: 12px;
--line-height: 22px;
}

.default {
--size: 18px;
--font-size: 14px;
--line-height: 24px;
}
15 changes: 14 additions & 1 deletion utils/vara-ui/src/components/radio/radio.stories.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Meta, StoryObj } from '@storybook/react';

import { Radio } from './radio';

type Type = typeof Radio;
Expand All @@ -7,7 +8,19 @@ type Story = StoryObj<Type>;
const meta: Meta<Type> = {
title: 'Radio',
component: Radio,
args: { label: 'Label' },
args: {
label: 'Label',
disabled: false,
error: undefined,
},
argTypes: {
size: {
options: ['small', 'default'],
control: { type: 'select' },
},
disabled: { control: 'boolean' },
error: { control: 'text' },
},
};

const Default: Story = {
Expand Down
16 changes: 9 additions & 7 deletions utils/vara-ui/src/components/radio/radio.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { InputHTMLAttributes, forwardRef } from 'react';
import { InputHTMLAttributes, ReactNode, forwardRef } from 'react';
import cx from 'clsx';

import styles from './radio.module.scss';

type Props = InputHTMLAttributes<HTMLInputElement> & {
type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> & {
label: string;
size?: 'small' | 'default';
error?: ReactNode;
};

const Radio = forwardRef<HTMLInputElement, Props>(({ label, className, ...attrs }, ref) => {
const { disabled } = attrs;

const Radio = forwardRef<HTMLInputElement, Props>(({ label, className, size = 'default', error, ...attrs }, ref) => {
return (
<label className={cx(styles.label, className, disabled && styles.disabled)}>
<input type="radio" className={styles.input} ref={ref} {...attrs} />
<label className={cx(styles.label, className, styles[size])}>
<input type="radio" className={styles.input} ref={ref} aria-invalid={Boolean(error)} {...attrs} />
<span className={styles.box} />

{label}
</label>
Expand Down

0 comments on commit 27b6da3

Please sign in to comment.