-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b5abb62
commit 83d5711
Showing
4 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { render, screen } from '@testing-library/react' | ||
|
||
import { RadioTileGroup } from './RadioTileGroup' | ||
|
||
describe('Card', () => { | ||
it('renders', async () => { | ||
render( | ||
<RadioTileGroup> | ||
<RadioTileGroup.Item value="asdf" label="Asdf" /> | ||
<RadioTileGroup.Item value="jkl;" label="Jkl;" /> | ||
</RadioTileGroup> | ||
) | ||
const item1 = await screen.findByText('Asdf') | ||
expect(item1).toBeInTheDocument() | ||
const item2 = await screen.findByText('Jkl;') | ||
expect(item2).toBeInTheDocument() | ||
}) | ||
|
||
describe('Item description', () => { | ||
it('renders', async () => { | ||
render( | ||
<RadioTileGroup> | ||
<RadioTileGroup.Item | ||
value="asdf" | ||
label="Asdf" | ||
description="This is a description." | ||
/> | ||
</RadioTileGroup> | ||
) | ||
const description = await screen.findByText('This is a description.') | ||
expect(description).toBeInTheDocument() | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Meta, StoryObj } from '@storybook/react' | ||
|
||
import { RadioTileGroup } from './RadioTileGroup' | ||
|
||
type RadioTileGroupStory = React.ComponentProps<typeof RadioTileGroup> & { | ||
flex: 1 | 'none' | ||
} | ||
|
||
const meta: Meta<RadioTileGroupStory> = { | ||
title: 'Components/RadioTileGroup', | ||
component: RadioTileGroup, | ||
argTypes: { | ||
direction: { | ||
description: 'Controls the flex direction of the RadioTileGroup', | ||
control: 'radio', | ||
options: ['row', 'col'], | ||
}, | ||
flex: { | ||
description: 'Toggles between the item flexing and not', | ||
control: 'radio', | ||
options: [1, 'none'], | ||
}, | ||
}, | ||
} | ||
export default meta | ||
|
||
type Story = StoryObj<RadioTileGroupStory> | ||
|
||
export const Default: Story = { | ||
args: { | ||
direction: 'row', | ||
flex: 1, | ||
}, | ||
render: (args) => ( | ||
<RadioTileGroup className="w-full" direction={args.direction}> | ||
<RadioTileGroup.Item value="radio" label="Radio" flex={args.flex} /> | ||
<RadioTileGroup.Item value="tile" label="Tile" flex={args.flex} /> | ||
<RadioTileGroup.Item value="group" label="Group" flex={args.flex} /> | ||
</RadioTileGroup> | ||
), | ||
} | ||
|
||
export const WithDescription: Story = { | ||
args: { | ||
direction: 'row', | ||
flex: 1, | ||
}, | ||
render: (args) => ( | ||
<RadioTileGroup className="w-full" direction={args.direction}> | ||
<RadioTileGroup.Item | ||
value="description" | ||
label="Description" | ||
description="A RadioTileGroup Item can optionally have a description" | ||
/> | ||
<RadioTileGroup.Item value="noDescription" label="No Description" /> | ||
</RadioTileGroup> | ||
), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group' | ||
import { cva, VariantProps } from 'cva' | ||
import React from 'react' | ||
|
||
const group = cva(['flex', 'gap-4'], { | ||
variants: { | ||
direction: { | ||
row: 'flex-row', | ||
col: 'flex-col', | ||
}, | ||
}, | ||
defaultVariants: { | ||
direction: 'row', | ||
}, | ||
}) | ||
interface GroupProps | ||
extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>, | ||
VariantProps<typeof group> {} | ||
|
||
const Group = React.forwardRef< | ||
React.ElementRef<typeof RadioGroupPrimitive.Root>, | ||
GroupProps | ||
>(({ className, direction, ...props }, ref) => { | ||
return ( | ||
<RadioGroupPrimitive.Root | ||
className={group({ className, direction })} | ||
{...props} | ||
ref={ref} | ||
/> | ||
) | ||
}) | ||
Group.displayName = RadioGroupPrimitive.Root.displayName | ||
|
||
const item = cva(['relative'], { | ||
variants: { | ||
flex: { | ||
1: 'flex-1', | ||
none: 'flex-none', | ||
}, | ||
}, | ||
defaultVariants: { | ||
flex: 1, | ||
}, | ||
}) | ||
interface ItemProps | ||
extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>, | ||
VariantProps<typeof item> { | ||
label: string | ||
description?: string | ||
} | ||
|
||
const Item = React.forwardRef< | ||
React.ElementRef<typeof RadioGroupPrimitive.Item>, | ||
ItemProps | ||
>(({ className, label, description, flex, ...props }, ref) => { | ||
return ( | ||
<RadioGroupPrimitive.Item | ||
ref={ref} | ||
className={item({ className, flex })} | ||
{...props} | ||
> | ||
<div className="flex h-full flex-col gap-2 rounded-md border border-ds-gray-quaternary p-4"> | ||
<div className="flex items-center justify-between gap-4"> | ||
<p className="font-medium">{label}</p> | ||
<RadioButtonCircle /> | ||
</div> | ||
{description ? ( | ||
<p className="text-left text-ds-gray-quinary">{description}</p> | ||
) : null} | ||
</div> | ||
<RadioGroupPrimitive.Indicator className="absolute right-0 top-0 flex h-full w-full justify-end"> | ||
<div className="absolute h-full w-full rounded-md border-2 border-ds-blue" /> | ||
<div className="h-full w-full rounded-md border border-ds-blue p-4"> | ||
<div className="flex h-5 w-full items-center justify-end"> | ||
<RadioButtonCircle selected /> | ||
</div> | ||
</div> | ||
</RadioGroupPrimitive.Indicator> | ||
</RadioGroupPrimitive.Item> | ||
) | ||
}) | ||
Item.displayName = RadioGroupPrimitive.Item.displayName | ||
|
||
export const RadioTileGroup = Object.assign(Group, { | ||
Item, | ||
}) | ||
|
||
function RadioButtonCircle({ selected = false }: { selected?: boolean }) { | ||
return selected ? ( | ||
<div className="flex h-4 w-4 items-center justify-center rounded-full bg-ds-blue"> | ||
<div className="h-1 w-1 rounded-full bg-white " /> | ||
</div> | ||
) : ( | ||
<div className="h-4 w-4 rounded-full border border-ds-gray-quaternary" /> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { RadioTileGroup } from './RadioTileGroup' |