-
Notifications
You must be signed in to change notification settings - Fork 469
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
6ca2f4b
commit 20a4e45
Showing
5 changed files
with
223 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,41 @@ | ||
"use client"; | ||
import { RadioGroup as HeadlessRadioGroup } from "@headlessui/react"; | ||
import { makeClassName, tremorTwMerge } from "lib"; | ||
import React from "react"; | ||
|
||
const makeRadioGroupClassName = makeClassName("RadioGroup"); | ||
|
||
export interface RadioGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> { | ||
defaultValue?: string[]; | ||
value?: string[]; | ||
onChange?: (value: any) => void; // @SEV: does this need to be declared here? see e.g. BaseInput | ||
disabled?: boolean; | ||
name?: string; | ||
id?: string; | ||
} | ||
|
||
const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref) => { | ||
const { defaultValue, value, onChange, children, disabled, name, id, className, ...other } = | ||
props; | ||
|
||
return ( | ||
<HeadlessRadioGroup | ||
as="div" | ||
ref={ref} | ||
defaultValue={defaultValue} | ||
value={value} | ||
onChange={onChange} | ||
disabled={disabled} | ||
name={name} | ||
id={id} | ||
className={tremorTwMerge(makeRadioGroupClassName("root"), className)} | ||
{...other} | ||
> | ||
{children} | ||
</HeadlessRadioGroup> | ||
); | ||
}); | ||
|
||
RadioGroup.displayName = "RadioGroup"; | ||
|
||
export default RadioGroup; |
32 changes: 32 additions & 0 deletions
32
src/components/input-elements/RadioGroup/RadioGroupOption.tsx
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,32 @@ | ||
"use client"; | ||
import { RadioGroup as HeadlessRadioGroup } from "@headlessui/react"; | ||
import { makeClassName, tremorTwMerge } from "lib"; | ||
import React from "react"; | ||
|
||
const makeRadioGroupOptionClassName = makeClassName("RadioGroup"); | ||
|
||
export interface RadioGroupOptionProps extends React.HTMLAttributes<HTMLDivElement> { | ||
value?: string[]; | ||
disabled?: boolean; | ||
} | ||
|
||
const RadioGroupOption = React.forwardRef<HTMLDivElement, RadioGroupOptionProps>((props, ref) => { | ||
const { value, children, disabled, className, ...other } = props; | ||
|
||
return ( | ||
<HeadlessRadioGroup.Option | ||
as="div" | ||
ref={ref} | ||
value={value} | ||
disabled={disabled} | ||
className={tremorTwMerge(makeRadioGroupOptionClassName("root"), className)} | ||
{...other} | ||
> | ||
{children} | ||
</HeadlessRadioGroup.Option> | ||
); | ||
}); | ||
|
||
RadioGroupOption.displayName = "RadioGroupOption"; | ||
|
||
export default RadioGroupOption; |
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,4 @@ | ||
export { default as RadioGroup } from "./RadioGroup"; | ||
export type { RadioGroupProps } from "./RadioGroup"; | ||
export { default as RadioGroupOption } from "./RadioGroupOption"; | ||
export type { RadioGroupOptionProps } from "./RadioGroupOption"; |
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
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,145 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
// import { RadioGroup, RadioGroupOption } from "components"; | ||
import { RadioGroup } from "@headlessui/react"; | ||
import { CheckCircleIcon } from "@heroicons/react/solid"; | ||
import React, { useState } from "react"; | ||
|
||
const platformPrices = [ | ||
{ id: 0, title: "Starter", description: "Up to 300 requests per day" }, | ||
{ | ||
id: 2, | ||
title: "Premium", | ||
description: "Unlimited requests per month", | ||
}, | ||
{ id: 3, title: "Enterprise", description: "Based on your specific needs" }, | ||
]; | ||
|
||
interface StringJoiner { | ||
(...classes: string[]): string; | ||
} | ||
const classNames: StringJoiner = (...classes: string[]): string => | ||
classes.filter(Boolean).join(" "); | ||
|
||
const meta: Meta<typeof RadioGroup> = { | ||
title: "Components/Input/RadioGroup", | ||
component: RadioGroup, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof RadioGroup>; | ||
|
||
function CardTemplate() { | ||
const [selectedPlatform, setSelectedPlatform] = useState(platformPrices[0]); | ||
return ( | ||
<div className="p-10"> | ||
{/* <RadioGroup value={selectedPlatform} onChange={setSelectedPlatform} name="platform"> | ||
<div className="mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-3 sm:gap-x-4"> | ||
{platformPrices.map((priceTier) => ( | ||
<RadioGroupOption | ||
key={priceTier.id} | ||
value={priceTier.id} | ||
className={({ active }) => | ||
classNames( | ||
active | ||
? "border border-blue-400 ring-2 ring-blue-200 transition-all" | ||
: "ring-1 ring-gray-200 border-transparent", | ||
"relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm transition-all", | ||
) | ||
} | ||
> | ||
{({ checked, active }) => ( | ||
<> | ||
<span className="flex flex-1"> | ||
<span className="flex flex-col"> | ||
<span className="block text-sm font-medium text-slate-900"> | ||
{priceTier.title} | ||
</span> | ||
<span className="mt-1 flex items-center text-sm text-slate-500"> | ||
{priceTier.description} | ||
</span> | ||
</span> | ||
</span> | ||
<CheckCircleIcon | ||
className={classNames(!checked ? "invisible" : "", "h-5 w-5 text-blue-500")} | ||
aria-hidden="true" | ||
/> | ||
<span | ||
className={classNames( | ||
active ? "border" : "", | ||
checked | ||
? "border border-blue-400 ring-2 ring-blue-200" | ||
: "border-transparent", | ||
"pointer-events-none absolute -inset-px rounded-lg", | ||
)} | ||
aria-hidden="true" | ||
/> | ||
</> | ||
)} | ||
</RadioGroupOption> | ||
))} | ||
</div> | ||
</RadioGroup> */} | ||
<RadioGroup value={selectedPlatform} onChange={setSelectedPlatform} name="platform"> | ||
<div className="mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-3 sm:gap-x-4"> | ||
{platformPrices.map((priceTier) => ( | ||
<RadioGroup.Option | ||
key={priceTier.id} | ||
value={priceTier} | ||
className={({ active }) => | ||
classNames( | ||
active | ||
? "border border-blue-400 ring-2 ring-blue-200 transition-all" | ||
: "ring-1 ring-gray-200 border-transparent ", | ||
"relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm transition-all", | ||
) | ||
} | ||
> | ||
{({ checked, active }) => ( | ||
<> | ||
<span className="flex flex-1"> | ||
<span className="flex flex-col"> | ||
<RadioGroup.Label | ||
as="span" | ||
className="block text-sm font-medium text-slate-900" | ||
> | ||
{priceTier.title} | ||
</RadioGroup.Label> | ||
<RadioGroup.Description | ||
as="span" | ||
className="mt-1 flex items-center text-sm text-slate-500" | ||
> | ||
{priceTier.description} | ||
</RadioGroup.Description> | ||
</span> | ||
</span> | ||
<CheckCircleIcon | ||
className={classNames(!checked ? "invisible" : "", "h-5 w-5 text-blue-500")} | ||
aria-hidden="true" | ||
/> | ||
<span | ||
className={classNames( | ||
active ? "border" : "", | ||
checked | ||
? "border border-blue-400 ring-2 ring-blue-200" | ||
: "border-transparent", | ||
"pointer-events-none absolute -inset-px rounded-lg", | ||
)} | ||
aria-hidden="true" | ||
/> | ||
</> | ||
)} | ||
</RadioGroup.Option> | ||
))} | ||
</div> | ||
</RadioGroup> | ||
</div> | ||
); | ||
} | ||
|
||
const Cards: Story = { | ||
render: CardTemplate, | ||
}; | ||
|
||
export const CardsCustomStyled: Story = { | ||
...Cards, | ||
}; |