diff --git a/utils/vara-ui/src/components/radio/helpers.ts b/utils/vara-ui/src/components/radio/helpers.ts new file mode 100644 index 0000000000..a06d2c89a1 --- /dev/null +++ b/utils/vara-ui/src/components/radio/helpers.ts @@ -0,0 +1,5 @@ +const radioSizes = ['default', 'small'] as const; +type IRadioSizes = (typeof radioSizes)[number]; + +export { radioSizes }; +export type { IRadioSizes }; diff --git a/utils/vara-ui/src/components/radio/radio.module.scss b/utils/vara-ui/src/components/radio/radio.module.scss index f2d6713bc1..aea1b2d610 100644 --- a/utils/vara-ui/src/components/radio/radio.module.scss +++ b/utils/vara-ui/src/components/radio/radio.module.scss @@ -1,24 +1,98 @@ .label { display: flex; align-items: center; + gap: 8px; cursor: pointer; + font-size: 14px; + line-height: 20px; + width: fit-content; + user-select: none; &.disabled { - pointer-events: none; - opacity: 0.3; + cursor: not-allowed; + } +} + +.wrapper { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + color: #d0d5dd; + + &::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: currentColor; + border-radius: 100%; + opacity: 0; + width: 35%; + height: 35%; + } + + &:has(:checked) { + color: #0ed3a3; + + &::before { + opacity: 1; + } + } + + &:has(:disabled) { + color: #eceded; } } .input { appearance: none; + flex-shrink: 0; + margin: 0; + width: 75%; + height: 75%; + + color: inherit; + border: 1px solid currentColor; + border-radius: 100%; cursor: inherit; - margin: 0 10px 0 0; +} + +.small { + font-size: 12px; + line-height: 22px; + + .wrapper { + width: 20px; + height: 20px; + } +} + +:global(.dark-theme) { + .label { + color: #ffffff; + } + + .wrapper { + color: #ffffff0a; + + .input { + background-color: #ffffff08; + } + + &:has(:checked) { + color: #00ffc4; - 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"); + .input { + background-color: transparent; + } + } - &: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"); + &:has(:disabled) { + color: #58696e1a; + } } } diff --git a/utils/vara-ui/src/components/radio/radio.stories.ts b/utils/vara-ui/src/components/radio/radio.stories.ts index d10c4065ba..7584d43578 100644 --- a/utils/vara-ui/src/components/radio/radio.stories.ts +++ b/utils/vara-ui/src/components/radio/radio.stories.ts @@ -1,5 +1,6 @@ import { Meta, StoryObj } from '@storybook/react'; import { Radio } from './radio'; +import { radioSizes } from './helpers'; type Type = typeof Radio; type Story = StoryObj; @@ -7,7 +8,19 @@ type Story = StoryObj; const meta: Meta = { title: 'Radio', component: Radio, - args: { label: 'Label' }, + args: { + label: 'Label', + disabled: false, + // checked: false, + }, + argTypes: { + size: { + options: radioSizes, + control: { type: 'select' }, + }, + disabled: { control: 'boolean' }, + // checked: { control: 'boolean' }, + }, }; const Default: Story = { diff --git a/utils/vara-ui/src/components/radio/radio.tsx b/utils/vara-ui/src/components/radio/radio.tsx index 1e604aa37f..b37ccb8457 100644 --- a/utils/vara-ui/src/components/radio/radio.tsx +++ b/utils/vara-ui/src/components/radio/radio.tsx @@ -1,17 +1,21 @@ import { InputHTMLAttributes, forwardRef } from 'react'; import cx from 'clsx'; import styles from './radio.module.scss'; +import type { IRadioSizes } from './helpers.ts'; -type Props = InputHTMLAttributes & { +type Props = Omit, 'size'> & { label: string; + size: IRadioSizes; }; -const Radio = forwardRef(({ label, className, ...attrs }, ref) => { +const Radio = forwardRef(({ label, className, size, ...attrs }, ref) => { const { disabled } = attrs; return ( -