Skip to content

Commit

Permalink
feat(radio)!: remove top level subcomponents (#1690)
Browse files Browse the repository at this point in the history
* feat(radio)!: remove top level subcomponents

* refactor(radio): use size tokens
  • Loading branch information
jinlee93 authored and booc0mtaco committed Jul 19, 2023
1 parent b4b9276 commit 82da617
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 195 deletions.
86 changes: 86 additions & 0 deletions src/components/Radio/Radio.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
90 changes: 84 additions & 6 deletions src/components/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -17,7 +15,7 @@ export type RadioProps = RadioInputProps & {
/**
* Size of the radio label.
*/
size?: RadioLabelProps['size'];
size?: InputLabelProps['size'];
} & EitherInclusive<
{
/**
Expand All @@ -32,6 +30,86 @@ export type RadioProps = RadioInputProps & {
'aria-label': string;
}
>;
type RadioInputProps = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'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 (
<Icon
className={iconClassName}
name={checked ? 'radio-selected' : 'radio-unselected'}
purpose="decorative"
size="1.625rem"
/>
);
};

/**
* 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 (
<span
className={clsx(
styles['input__wrapper'],
disabled && styles['input__wrapper--disabled'],
)}
>
<input
checked={checked}
className={clsx(className, styles['radio__input'])}
disabled={disabled}
type="radio"
{...other}
/>
<RadioSvg checked={checked} disabled={disabled} />
</span>
);
};

/**
* 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 <InputLabel className={componentClassName} size={size} {...other} />;
};

/**
* `import {Radio} from "@chanzuckerberg/eds";`
Expand Down
70 changes: 0 additions & 70 deletions src/components/RadioInput/RadioInput.module.css

This file was deleted.

68 changes: 0 additions & 68 deletions src/components/RadioInput/RadioInput.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/RadioInput/index.ts

This file was deleted.

21 changes: 0 additions & 21 deletions src/components/RadioLabel/RadioLabel.module.css

This file was deleted.

24 changes: 0 additions & 24 deletions src/components/RadioLabel/RadioLabel.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/RadioLabel/index.ts

This file was deleted.

Loading

0 comments on commit 82da617

Please sign in to comment.