diff --git a/.changeset/full-memes-enter.md b/.changeset/full-memes-enter.md new file mode 100644 index 000000000..d7953015d --- /dev/null +++ b/.changeset/full-memes-enter.md @@ -0,0 +1,5 @@ +--- +'@radix-ui/react-radio-group': minor +--- + +Add unstable `ItemRoot` `ItemTrigger` and parts to RadioGroup (#3519) diff --git a/apps/storybook/stories/radio-group-legacy.stories.tsx b/apps/storybook/stories/radio-group-legacy.stories.tsx new file mode 100644 index 000000000..fda848fe5 --- /dev/null +++ b/apps/storybook/stories/radio-group-legacy.stories.tsx @@ -0,0 +1,420 @@ +import * as React from 'react'; +import type { Meta } from '@storybook/react'; +import { Direction, Label as LabelPrimitive, RadioGroup } from 'radix-ui'; +import styles from './radio-group.stories.module.css'; + +export default { + title: 'Components/RadioGroup (legacy API)', + component: RadioGroup.Root, +} satisfies Meta; + +export const Styled = () => ( + +); + +export const Controlled = () => { + const [value, setValue] = React.useState('2'); + + return ( + + + + + + + + + + + + ); +}; + +export const Unset = () => ( + +); + +export const WithinForm = () => { + const [data, setData] = React.useState({ optional: '', required: '', stopprop: '' }); + + return ( +
event.preventDefault()} + onChange={(event) => { + const radio = event.target as HTMLInputElement; + setData((prevData) => ({ ...prevData, [radio.name]: radio.value })); + }} + > +
+ optional value: {data.optional} + + + + + + + + + + + +
+ +
+
+ +
+ required value: {data.required} + + + + + + + + + + + +
+ +
+
+ +
+ stop propagation value: {data.stopprop} + + event.stopPropagation()} + > + + + event.stopPropagation()} + > + + + event.stopPropagation()} + > + + + +
+ +
+
+ + +
+ ); +}; + +export const Animated = () => { + const indicatorClass = [styles.indicator, styles.animatedIndicator].join(' '); + return ( + + ); +}; + +export const Chromatic = () => { + const manualFocusRef = React.useRef>(null); + + React.useEffect(() => { + manualFocusRef.current?.focus(); + }, []); + + return ( + <> +

Uncontrolled

+

Unset

+ + + + + + + + + + + + +

Set

+ + + + + + + + + + + + +

Controlled

+

Unset

+ + + + + + + + + + + + +

Set

+ + + + + + + + + + + + +

Disabled item

+ + + + + + + + + + + + +

Disabled root

+ + + + + {/* Not possible to set `disabled` back to `false` since it's set on the root (this item + should still be disabled). */} + + + + + + + + +

All items disabled

+ + + + + + + + + + + + +

Manual focus into group

+ + + + + + + + + + + + +

Force mounted indicator

+ + + + + + + + + + + + +

Direction

+

Prop

+ + + + + + + + + + + + +

Inherited

+ + + + + + + + + + + + + + +

State attributes

+

Default

+ + + + + + + + + + + + +

Disabled item

+ + + + + + + + + + + + + + + + + + + + + + + + +

Disabled root

+ + + + + + + + + + + + +

All items disabled

+ + + + + + + + + + + + + ); +}; +Chromatic.parameters = { chromatic: { disable: false } }; + +const Label = (props: any) => ; diff --git a/apps/storybook/stories/radio-group.stories.tsx b/apps/storybook/stories/radio-group.stories.tsx index 77ba95650..fef7850df 100644 --- a/apps/storybook/stories/radio-group.stories.tsx +++ b/apps/storybook/stories/radio-group.stories.tsx @@ -1,183 +1,134 @@ +/* eslint-disable react/jsx-pascal-case */ import * as React from 'react'; +import type { Meta } from '@storybook/react'; import { Direction, Label as LabelPrimitive, RadioGroup } from 'radix-ui'; import styles from './radio-group.stories.module.css'; -export default { title: 'Components/RadioGroup' }; +export default { + title: 'Components/RadioGroup', + component: RadioGroup.Root, +} satisfies Meta; -export const LegacyStyled = () => ( +export const Styled = () => ( ); -export const LegacyControlled = () => { +export const Controlled = () => { const [value, setValue] = React.useState('2'); return ( - - - - - - - - - + + + + + + + + + + + + + + + ); }; -export const LegacyUnset = () => ( +export const Unset = () => ( ); -export const LegacyWithinForm = () => { - const [data, setData] = React.useState({ optional: '', required: '', stopprop: '' }); - - return ( -
event.preventDefault()} - onChange={(event) => { - const radio = event.target as HTMLInputElement; - setData((prevData) => ({ ...prevData, [radio.name]: radio.value })); - }} - > -
- optional value: {data.optional} - - - - - - - - - - - -
- -
-
- -
- required value: {data.required} - - - - - - - - - - - -
- -
-
- -
- stop propagation value: {data.stopprop} - - event.stopPropagation()} - > - - - event.stopPropagation()} - > - - - event.stopPropagation()} - > - - - -
- -
-
- - -
- ); +export const WithinForm = () => { + return

TODO

; }; -export const LegacyAnimated = () => { +export const Animated = () => { const indicatorClass = [styles.indicator, styles.animatedIndicator].join(' '); return (