-
Notifications
You must be signed in to change notification settings - Fork 220
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2072 from cprussin/form-components
feat(component-library): add first round of form components
- Loading branch information
Showing
11 changed files
with
416 additions
and
4 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
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,37 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { Checkbox as CheckboxComponent } from "./index.js"; | ||
|
||
const meta = { | ||
component: CheckboxComponent, | ||
argTypes: { | ||
children: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
isDisabled: { | ||
control: "boolean", | ||
table: { | ||
category: "State", | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
(Story) => ( | ||
<div className="max-w-sm"> | ||
<Story /> | ||
</div> | ||
), | ||
], | ||
} satisfies Meta<typeof CheckboxComponent>; | ||
export default meta; | ||
|
||
export const Checkbox = { | ||
args: { | ||
children: | ||
"By clicking here you agree that this is a checkbox and it's super duper checkboxy", | ||
isDisabled: false, | ||
}, | ||
} satisfies StoryObj<typeof CheckboxComponent>; |
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,42 @@ | ||
import clsx from "clsx"; | ||
import type { ComponentProps } from "react"; | ||
import { Checkbox as BaseCheckbox } from "react-aria-components"; | ||
|
||
export const Checkbox = ({ | ||
children, | ||
className, | ||
...props | ||
}: ComponentProps<typeof BaseCheckbox>) => ( | ||
<BaseCheckbox | ||
className={clsx( | ||
"group/checkbox inline-flex cursor-pointer flex-row gap-2 py-1 text-sm data-[disabled]:cursor-not-allowed", | ||
className, | ||
)} | ||
{...props} | ||
> | ||
{(args) => ( | ||
<> | ||
<div className="relative top-[0.0625rem] mx-1 size-4 flex-none"> | ||
<div className="size-full rounded border border-stone-300 bg-white outline-4 outline-violet-500/40 transition duration-100 group-data-[hovered]/checkbox:border-2 group-data-[disabled]/checkbox:border-none group-data-[hovered]/checkbox:border-stone-400 group-data-[pressed]/checkbox:border-stone-500 group-data-[disabled]/checkbox:bg-stone-200 group-data-[focus-visible]/checkbox:outline dark:border-steel-700 dark:bg-steel-800 dark:group-data-[hovered]/checkbox:border-steel-600 dark:group-data-[pressed]/checkbox:border-steel-500 dark:group-data-[disabled]/checkbox:bg-steel-600" /> | ||
<div className="absolute inset-0 grid place-content-center rounded bg-violet-500 stroke-white p-1 opacity-0 transition duration-100 group-data-[disabled]/checkbox:bg-transparent group-data-[disabled]/checkbox:stroke-stone-400 group-data-[selected]/checkbox:opacity-100 dark:bg-violet-600 dark:stroke-steel-950 dark:group-data-[disabled]/checkbox:stroke-steel-400"> | ||
<svg | ||
className="w-full" | ||
viewBox="0 0 8 6" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M1 3L2.76471 5L7 1" | ||
strokeWidth="2" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
/> | ||
</svg> | ||
</div> | ||
<div className="pointer-events-none absolute -inset-1.5 -z-10 rounded-full bg-black/20 opacity-0 transition duration-100 group-data-[focus-visible]/checkbox:opacity-0 group-data-[hovered]/checkbox:opacity-50 group-data-[pressed]/checkbox:opacity-100 dark:bg-white/20" /> | ||
</div> | ||
{typeof children === "function" ? children(args) : children} | ||
</> | ||
)} | ||
</BaseCheckbox> | ||
); |
66 changes: 66 additions & 0 deletions
66
packages/component-library/src/CheckboxGroup/index.stories.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,66 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { | ||
ORIENTATIONS, | ||
CheckboxGroup as CheckboxGroupComponent, | ||
} from "./index.js"; | ||
import { Checkbox } from "../Checkbox/index.js"; | ||
|
||
const meta = { | ||
component: CheckboxGroupComponent, | ||
argTypes: { | ||
label: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
description: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
isDisabled: { | ||
control: "boolean", | ||
table: { | ||
category: "State", | ||
}, | ||
}, | ||
orientation: { | ||
control: "inline-radio", | ||
options: ORIENTATIONS, | ||
table: { | ||
category: "Layout", | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
(Story) => ( | ||
<div className="max-w-sm"> | ||
<Story /> | ||
</div> | ||
), | ||
], | ||
render: (args) => ( | ||
<CheckboxGroupComponent {...args}> | ||
<Checkbox value="one"> | ||
{ | ||
"By clicking here you agree that this is a checkbox and it's super duper checkboxy" | ||
} | ||
</Checkbox> | ||
<Checkbox value="two">Second</Checkbox> | ||
<Checkbox value="three">Third</Checkbox> | ||
</CheckboxGroupComponent> | ||
), | ||
} satisfies Meta<typeof CheckboxGroupComponent>; | ||
export default meta; | ||
|
||
export const CheckboxGroup = { | ||
args: { | ||
label: "This is a checkbox group!", | ||
description: "", | ||
isDisabled: false, | ||
orientation: "vertical", | ||
}, | ||
} satisfies StoryObj<typeof CheckboxGroupComponent>; |
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,44 @@ | ||
import clsx from "clsx"; | ||
import type { ComponentProps } from "react"; | ||
import { | ||
CheckboxGroup as BaseCheckboxGroup, | ||
Label, | ||
Text, | ||
} from "react-aria-components"; | ||
|
||
export const ORIENTATIONS = ["vertical", "horizontal"] as const; | ||
|
||
type CheckboxGroupProps = ComponentProps<typeof BaseCheckboxGroup> & { | ||
label: ComponentProps<typeof Label>["children"]; | ||
description?: ComponentProps<typeof Text>["children"] | undefined; | ||
orientation?: (typeof ORIENTATIONS)[number] | undefined; | ||
}; | ||
|
||
export const CheckboxGroup = ({ | ||
children, | ||
className, | ||
label, | ||
description, | ||
orientation = "vertical", | ||
...props | ||
}: CheckboxGroupProps) => ( | ||
<BaseCheckboxGroup | ||
data-orientation={orientation} | ||
className={clsx("group/checkbox-group", className)} | ||
{...props} | ||
> | ||
{(args) => ( | ||
<> | ||
<Label className="mb-1 text-sm font-medium">{label}</Label> | ||
<div className="flex group-data-[orientation=horizontal]/checkbox-group:flex-row group-data-[orientation=vertical]/checkbox-group:flex-col group-data-[orientation=horizontal]/checkbox-group:gap-6"> | ||
{typeof children === "function" ? children(args) : children} | ||
</div> | ||
{description && description !== "" && ( | ||
<Text slot="description" className="text-xs font-light"> | ||
{description} | ||
</Text> | ||
)} | ||
</> | ||
)} | ||
</BaseCheckboxGroup> | ||
); |
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,43 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { Link as LinkComponent } from "./index.js"; | ||
|
||
const meta = { | ||
component: LinkComponent, | ||
argTypes: { | ||
children: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
href: { | ||
control: "text", | ||
table: { | ||
category: "Link", | ||
}, | ||
}, | ||
target: { | ||
control: "text", | ||
table: { | ||
category: "Link", | ||
}, | ||
}, | ||
isDisabled: { | ||
control: "boolean", | ||
table: { | ||
category: "State", | ||
}, | ||
}, | ||
}, | ||
} satisfies Meta<typeof LinkComponent>; | ||
export default meta; | ||
|
||
export const Link = { | ||
args: { | ||
children: "Link", | ||
href: "https://www.pyth.network", | ||
target: "_blank", | ||
isDisabled: false, | ||
}, | ||
} satisfies StoryObj<typeof LinkComponent>; |
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,16 @@ | ||
import clsx from "clsx"; | ||
import type { ComponentProps } from "react"; | ||
import { Link as BaseLink } from "react-aria-components"; | ||
|
||
export const Link = ({ | ||
className, | ||
...props | ||
}: ComponentProps<typeof BaseLink>) => ( | ||
<BaseLink | ||
className={clsx( | ||
"underline outline-0 outline-offset-4 outline-inherit data-[disabled]:cursor-not-allowed data-[disabled]:text-stone-400 data-[disabled]:no-underline data-[focus-visible]:outline-2 hover:no-underline dark:data-[disabled]:text-steel-400", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
); |
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,38 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import { RadioGroup } from "react-aria-components"; | ||
|
||
import { Radio as RadioComponent } from "./index.js"; | ||
|
||
const meta = { | ||
component: RadioComponent, | ||
argTypes: { | ||
children: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
isDisabled: { | ||
control: "boolean", | ||
table: { | ||
category: "State", | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
(Story) => ( | ||
<RadioGroup className="max-w-sm"> | ||
<Story /> | ||
</RadioGroup> | ||
), | ||
], | ||
} satisfies Meta<typeof RadioComponent>; | ||
export default meta; | ||
|
||
export const Radio = { | ||
args: { | ||
children: | ||
"This is a radio button, check out how radioish it is and how it handles multiline labels", | ||
isDisabled: false, | ||
}, | ||
} satisfies StoryObj<typeof RadioComponent>; |
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,28 @@ | ||
import clsx from "clsx"; | ||
import type { ComponentProps } from "react"; | ||
import { Radio as BaseRadio } from "react-aria-components"; | ||
|
||
export const Radio = ({ | ||
children, | ||
className, | ||
...props | ||
}: ComponentProps<typeof BaseRadio>) => ( | ||
<BaseRadio | ||
className={clsx( | ||
"group/radio inline-flex cursor-pointer flex-row gap-2 py-1 text-sm data-[disabled]:cursor-not-allowed data-[selected]:cursor-default", | ||
className, | ||
)} | ||
{...props} | ||
> | ||
{(args) => ( | ||
<> | ||
<div className="relative top-[0.0625rem] mx-1 size-4 flex-none"> | ||
<div className="size-full rounded-full border border-stone-300 bg-white outline-4 outline-violet-500/40 transition duration-100 group-data-[hovered]/radio:border-2 group-data-[disabled]/radio:border-none group-data-[hovered]/radio:border-stone-400 group-data-[pressed]/radio:border-stone-500 group-data-[disabled]/radio:bg-stone-200 group-data-[focus-visible]/radio:outline dark:border-steel-700 dark:bg-steel-800 dark:group-data-[hovered]/radio:border-steel-600 dark:group-data-[pressed]/radio:border-steel-500 dark:group-data-[disabled]/radio:bg-steel-600" /> | ||
<div className="absolute inset-0 rounded-full border-[0.3rem] border-violet-500 bg-white opacity-0 transition duration-100 group-data-[disabled]/radio:border-transparent group-data-[disabled]/radio:bg-stone-400 group-data-[selected]/radio:opacity-100 dark:border-violet-600 dark:bg-steel-950 dark:group-data-[disabled]/radio:bg-steel-400" /> | ||
<div className="pointer-events-none absolute -inset-1.5 -z-10 rounded-full bg-black/20 opacity-0 transition duration-100 group-data-[focus-visible]/radio:opacity-0 group-data-[hovered]/radio:opacity-50 group-data-[pressed]/radio:opacity-100 group-data-[selected]/radio:opacity-0 dark:bg-white/20" /> | ||
</div> | ||
{typeof children === "function" ? children(args) : children} | ||
</> | ||
)} | ||
</BaseRadio> | ||
); |
62 changes: 62 additions & 0 deletions
62
packages/component-library/src/RadioGroup/index.stories.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,62 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { RadioGroup as RadioGroupComponent } from "./index.js"; | ||
import { Radio } from "../Radio/index.js"; | ||
|
||
const meta = { | ||
component: RadioGroupComponent, | ||
argTypes: { | ||
label: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
description: { | ||
control: "text", | ||
table: { | ||
category: "Contents", | ||
}, | ||
}, | ||
isDisabled: { | ||
control: "boolean", | ||
table: { | ||
category: "State", | ||
}, | ||
}, | ||
orientation: { | ||
control: "inline-radio", | ||
options: ["vertical", "horizontal"], | ||
table: { | ||
category: "Layout", | ||
}, | ||
}, | ||
}, | ||
decorators: [ | ||
(Story) => ( | ||
<div className="max-w-sm"> | ||
<Story /> | ||
</div> | ||
), | ||
], | ||
render: (args) => ( | ||
<RadioGroupComponent {...args}> | ||
<Radio value="one"> | ||
This is a radio button, check out how radioish it is and how it handles | ||
multiline labels | ||
</Radio> | ||
<Radio value="two">Second</Radio> | ||
<Radio value="three">Third</Radio> | ||
</RadioGroupComponent> | ||
), | ||
} satisfies Meta<typeof RadioGroupComponent>; | ||
export default meta; | ||
|
||
export const RadioGroup = { | ||
args: { | ||
label: "This is a radio group!", | ||
description: "", | ||
isDisabled: false, | ||
orientation: "vertical", | ||
}, | ||
} satisfies StoryObj<typeof RadioGroupComponent>; |
Oops, something went wrong.