diff --git a/src/components/Radio/Radio.module.css b/src/components/Radio/Radio.module.css index 3a8cc3ca3..8b4a9cb76 100755 --- a/src/components/Radio/Radio.module.css +++ b/src/components/Radio/Radio.module.css @@ -9,3 +9,89 @@ display: flex; gap: var(--eds-size-1); } + +/** + * Wraps the visually hidden radio input element and the visible sibling svg element. + */ +.input__wrapper { + position: relative; + /* Centers the radio icon in the wrapper. */ + display: inline-flex; + align-items: center; + /* Aligns the radio with the first line of the label. */ + align-self: flex-start; +} +/** + * The visually hidden input element for the radio. The visual radio is provided by an svg element. + */ +.radio__input { + /* Removes default margins placed by browser for radioes. */ + margin: 0; + /* Remove the radio from the page flow, positioning it on top of the SVG. */ + position: absolute; + left: var(--eds-size-half); + /* Set same dimensions as the RadioSvg element. */ + height: var(--eds-size-2); + width: var(--eds-size-2); + /** + * Hide the input element visually. + * This ensures the radio is still "physically" present so that all users, + * especially on touch screen readers, still interact with the real radio element + * where it would naturally be present. + */ + opacity: 0; +} + +/** + * The visible radio svg icon element. + */ +.radio__icon { + color: var(--eds-theme-color-radio-brand-background); + /* Creates space for the border so that there's no jitter when the focus border is visible. */ + border: var(--eds-border-width-sm) solid transparent; +} +.radio__input:focus-visible + .radio__icon { + border: var(--eds-border-width-sm) solid var(--eds-theme-color-focus-ring); + border-radius: var(--eds-border-radius-full); +} + +@supports not selector(:focus-visible) { + .radio__input:focus + .radio__icon { + border: var(--eds-border-width-sm) solid var(--eds-theme-color-focus-ring); + border-radius: var(--eds-border-radius-full); + } +} + +/** + * The disabled variant of the visible radio svg icon. + */ +.radio__icon--disabled { + color: var(--eds-theme-color-icon-disabled); +} + +/** + * The disabled status of the visually hidden input element. + */ +.radio__input:disabled { + /* Needed since the input element overlays the visible svg icon for user input and cursor. */ + cursor: not-allowed; +} + +/** + * Text that labels a radio input. + */ +.radio__label { + position: relative; +} + +/** + * Radio label size variants. + * Used for centering the label with the radio input button. + */ +.radio__label--md { + top: var(--eds-size-quarter); +} +.radio__label--lg { + /* This is a 1px increase in top spacing from the md variant. Size is too specific to have a token. */ + top: 0.0625rem; +} diff --git a/src/components/Radio/Radio.tsx b/src/components/Radio/Radio.tsx index 202a56040..8a5878a8f 100644 --- a/src/components/Radio/Radio.tsx +++ b/src/components/Radio/Radio.tsx @@ -2,13 +2,11 @@ import clsx from 'clsx'; import React from 'react'; import { useId } from '../../util/useId'; import type { EitherInclusive } from '../../util/utility-types'; -import type { RadioInputProps } from '../RadioInput'; -import RadioInput from '../RadioInput'; -import type { RadioLabelProps } from '../RadioLabel'; -import RadioLabel from '../RadioLabel'; +import Icon from '../Icon'; +import { InputLabel, type InputLabelProps } from '../InputLabel/InputLabel'; import styles from './Radio.module.css'; -export type RadioProps = RadioInputProps & { +type RadioProps = RadioInputProps & { /** * HTML id attribute. If not passed, this component * will generate an id to use for accessibility. @@ -17,7 +15,7 @@ export type RadioProps = RadioInputProps & { /** * Size of the radio label. */ - size?: RadioLabelProps['size']; + size?: InputLabelProps['size']; } & EitherInclusive< { /** @@ -32,6 +30,86 @@ export type RadioProps = RadioInputProps & { 'aria-label': string; } >; +type RadioInputProps = Omit< + React.InputHTMLAttributes, + 'id' | 'size' +> & { + /** + * Additional classnames passed in for styling. + */ + className?: string; + /** + * Radio ID. Used to connect the input with a label for accessibility purposes. + */ + id?: string; +}; + +const RadioSvg = ({ + checked, + disabled, +}: { + checked?: boolean; + disabled?: boolean; +}) => { + const iconClassName = clsx( + styles['radio__icon'], + disabled && styles['radio__icon--disabled'], + ); + return ( + + ); +}; + +/** + * Radio input element, exported for greater flexibility. + * You must provide an `id` prop and connect it to a visible label. + */ +export const RadioInput = ({ + checked = false, + className, + disabled, + ...other +}: RadioInputProps) => { + return ( + + + + + ); +}; + +/** + * Radio label element, styles and relies on the InputLabel component. + */ +export const RadioLabel = ({ + className, + size = 'lg', + ...other +}: InputLabelProps) => { + const componentClassName = clsx( + styles['radio__label'], + styles[`radio__label--${size}`], + className, + ); + + return ; +}; /** * `import {Radio} from "@chanzuckerberg/eds";` diff --git a/src/components/RadioInput/RadioInput.module.css b/src/components/RadioInput/RadioInput.module.css deleted file mode 100644 index ed514f032..000000000 --- a/src/components/RadioInput/RadioInput.module.css +++ /dev/null @@ -1,70 +0,0 @@ -/*------------------------------------*\ - # RADIO INPUT -\*------------------------------------*/ - -/** - * Wraps the visually hidden radio input element and the visible sibling svg element. - */ -.input__wrapper { - position: relative; - /* Centers the radio icon in the wrapper. */ - display: inline-flex; - align-items: center; - /* Aligns the radio with the first line of the label. */ - align-self: flex-start; -} -/** - * The visually hidden input element for the radio. The visual radio is provided by an svg element. - */ -.radio__input { - /* Removes default margins placed by browser for radioes. */ - margin: 0; - /* Remove the radio from the page flow, positioning it on top of the SVG. */ - position: absolute; - left: 0.25rem; - /* Set same dimensions as the RadioSvg element. */ - height: var(--eds-size-2); - width: var(--eds-size-2); - /** - * Hide the input element visually. - * This ensures the radio is still "physically" present so that all users, - * especially on touch screen readers, still interact with the real radio element - * where it would naturally be present. - */ - opacity: 0; -} - -/** - * The visible radio svg icon element. - */ -.radio__icon { - color: var(--eds-theme-color-radio-brand-background); - /* Creates space for the border so that there's no jitter when the focus border is visible. */ - border: var(--eds-border-width-sm) solid transparent; -} -.radio__input:focus-visible + .radio__icon { - border: var(--eds-border-width-sm) solid var(--eds-theme-color-focus-ring); - border-radius: var(--eds-border-radius-full); -} - -@supports not selector(:focus-visible) { - .radio__input:focus + .radio__icon { - border: var(--eds-border-width-sm) solid var(--eds-theme-color-focus-ring); - border-radius: var(--eds-border-radius-full); - } -} - -/** - * The disabled variant of the visible radio svg icon. - */ -.radio__icon--disabled { - color: var(--eds-theme-color-icon-disabled); -} - -/** - * The disabled status of the visually hidden input element. - */ -.radio__input:disabled { - /* Needed since the input element overlays the visible svg icon for user input and cursor. */ - cursor: not-allowed; -} diff --git a/src/components/RadioInput/RadioInput.tsx b/src/components/RadioInput/RadioInput.tsx deleted file mode 100644 index a6b98e3be..000000000 --- a/src/components/RadioInput/RadioInput.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import clsx from 'clsx'; -import React from 'react'; -import Icon from '../Icon'; -import styles from './RadioInput.module.css'; - -export type RadioInputProps = Omit< - React.InputHTMLAttributes, - 'id' | 'size' -> & { - /** - * Additional classnames passed in for styling. - */ - className?: string; - /** - * Radio ID. Used to connect the input with a label for accessibility purposes. - */ - id?: string; -}; - -const RadioSvg = ({ - checked, - disabled, -}: { - checked?: boolean; - disabled?: boolean; -}) => { - const iconClassName = clsx( - styles['radio__icon'], - disabled && styles['radio__icon--disabled'], - ); - return ( - - ); -}; - -/** - * Radio input element, exported for greater flexibility. - * You must provide an `id` prop and connect it to a visible label. - */ -export const RadioInput = ({ - checked = false, - className, - disabled, - ...other -}: RadioInputProps) => { - return ( - - - - - ); -}; diff --git a/src/components/RadioInput/index.ts b/src/components/RadioInput/index.ts deleted file mode 100644 index cfeec0a58..000000000 --- a/src/components/RadioInput/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { RadioInput as default } from './RadioInput'; -export type { RadioInputProps } from './RadioInput'; diff --git a/src/components/RadioLabel/RadioLabel.module.css b/src/components/RadioLabel/RadioLabel.module.css deleted file mode 100644 index f36d5130a..000000000 --- a/src/components/RadioLabel/RadioLabel.module.css +++ /dev/null @@ -1,21 +0,0 @@ -/*------------------------------------*\ - # RADIO LABEL -\*------------------------------------*/ - -/** - * Text that labels a radio input. - */ -.radio__label { - position: relative; -} - -/** - * Radio label size variants. - * Used for centering the label with the radio input button. - */ -.radio__label--md { - top: 0.125rem; -} -.radio__label--lg { - top: 0.0625rem; -} diff --git a/src/components/RadioLabel/RadioLabel.tsx b/src/components/RadioLabel/RadioLabel.tsx deleted file mode 100644 index 5cab68c28..000000000 --- a/src/components/RadioLabel/RadioLabel.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import clsx from 'clsx'; -import React from 'react'; -import type { InputLabelProps } from '../InputLabel/InputLabel'; -import { InputLabel } from '../InputLabel/InputLabel'; -import styles from './RadioLabel.module.css'; - -export type RadioLabelProps = InputLabelProps; - -/** - * Radio label element, styles and relies on the InputLabel component. - */ -export const RadioLabel = ({ - className, - size = 'lg', - ...other -}: RadioLabelProps) => { - const componentClassName = clsx( - styles['radio__label'], - styles[`radio__label--${size}`], - className, - ); - - return ; -}; diff --git a/src/components/RadioLabel/index.ts b/src/components/RadioLabel/index.ts deleted file mode 100644 index dec6014c4..000000000 --- a/src/components/RadioLabel/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { RadioLabel as default } from './RadioLabel'; -export type { RadioLabelProps } from './RadioLabel'; diff --git a/src/index.ts b/src/index.ts index 7d2c97594..5738eae20 100644 --- a/src/index.ts +++ b/src/index.ts @@ -67,8 +67,6 @@ export { default as Popover } from './components/Popover'; export { default as PopoverListItem } from './components/PopoverListItem'; export { default as ProgressBar } from './components/ProgressBar'; export { default as Radio } from './components/Radio'; -export { default as RadioInput } from './components/RadioInput'; -export { default as RadioLabel } from './components/RadioLabel'; export { default as Score } from './components/Score'; export { default as SearchBar } from './components/SearchBar'; export { default as Section } from './components/Section';