From 2ac2b4f1e374da739f820e8f14fd8518b92f974f Mon Sep 17 00:00:00 2001 From: Connor Prussin Date: Sun, 27 Oct 2024 22:46:44 -0700 Subject: [PATCH] feat(component-library): add first round of form components --- .../component-library/.storybook/preview.tsx | 8 +-- .../src/Checkbox/index.stories.tsx | 37 +++++++++++ .../component-library/src/Checkbox/index.tsx | 42 ++++++++++++ .../src/CheckboxGroup/index.stories.tsx | 66 +++++++++++++++++++ .../src/CheckboxGroup/index.tsx | 44 +++++++++++++ .../src/Link/index.stories.tsx | 43 ++++++++++++ packages/component-library/src/Link/index.tsx | 16 +++++ .../src/Radio/index.stories.tsx | 38 +++++++++++ .../component-library/src/Radio/index.tsx | 28 ++++++++ .../src/RadioGroup/index.stories.tsx | 62 +++++++++++++++++ .../src/RadioGroup/index.tsx | 36 ++++++++++ 11 files changed, 416 insertions(+), 4 deletions(-) create mode 100644 packages/component-library/src/Checkbox/index.stories.tsx create mode 100644 packages/component-library/src/Checkbox/index.tsx create mode 100644 packages/component-library/src/CheckboxGroup/index.stories.tsx create mode 100644 packages/component-library/src/CheckboxGroup/index.tsx create mode 100644 packages/component-library/src/Link/index.stories.tsx create mode 100644 packages/component-library/src/Link/index.tsx create mode 100644 packages/component-library/src/Radio/index.stories.tsx create mode 100644 packages/component-library/src/Radio/index.tsx create mode 100644 packages/component-library/src/RadioGroup/index.stories.tsx create mode 100644 packages/component-library/src/RadioGroup/index.tsx diff --git a/packages/component-library/.storybook/preview.tsx b/packages/component-library/.storybook/preview.tsx index 9a0fe5bf05..6ea18c32ea 100644 --- a/packages/component-library/.storybook/preview.tsx +++ b/packages/component-library/.storybook/preview.tsx @@ -38,10 +38,10 @@ export const decorators: Decorator[] = [ withRootClasses("font-sans antialiased", sans.variable), withThemeByClassName({ themes: { - white: "light bg-white", - light: "light bg-beige-50", - dark: "dark bg-steel-800", - darker: "dark bg-steel-900", + white: "light bg-white text-steel-900", + light: "light bg-beige-100 text-steel-900", + dark: "dark bg-steel-800 text-steel-50", + darker: "dark bg-steel-900 text-steel-50", }, defaultTheme: "light", }), diff --git a/packages/component-library/src/Checkbox/index.stories.tsx b/packages/component-library/src/Checkbox/index.stories.tsx new file mode 100644 index 0000000000..09abe61c0a --- /dev/null +++ b/packages/component-library/src/Checkbox/index.stories.tsx @@ -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) => ( +
+ +
+ ), + ], +} satisfies Meta; +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; diff --git a/packages/component-library/src/Checkbox/index.tsx b/packages/component-library/src/Checkbox/index.tsx new file mode 100644 index 0000000000..083d9a44f1 --- /dev/null +++ b/packages/component-library/src/Checkbox/index.tsx @@ -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) => ( + + {(args) => ( + <> +
+
+
+ + + +
+
+
+ {typeof children === "function" ? children(args) : children} + + )} + +); diff --git a/packages/component-library/src/CheckboxGroup/index.stories.tsx b/packages/component-library/src/CheckboxGroup/index.stories.tsx new file mode 100644 index 0000000000..75992d401a --- /dev/null +++ b/packages/component-library/src/CheckboxGroup/index.stories.tsx @@ -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) => ( +
+ +
+ ), + ], + render: (args) => ( + + + { + "By clicking here you agree that this is a checkbox and it's super duper checkboxy" + } + + Second + Third + + ), +} satisfies Meta; +export default meta; + +export const CheckboxGroup = { + args: { + label: "This is a checkbox group!", + description: "", + isDisabled: false, + orientation: "vertical", + }, +} satisfies StoryObj; diff --git a/packages/component-library/src/CheckboxGroup/index.tsx b/packages/component-library/src/CheckboxGroup/index.tsx new file mode 100644 index 0000000000..76b4786584 --- /dev/null +++ b/packages/component-library/src/CheckboxGroup/index.tsx @@ -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 & { + label: ComponentProps["children"]; + description?: ComponentProps["children"] | undefined; + orientation?: (typeof ORIENTATIONS)[number] | undefined; +}; + +export const CheckboxGroup = ({ + children, + className, + label, + description, + orientation = "vertical", + ...props +}: CheckboxGroupProps) => ( + + {(args) => ( + <> + +
+ {typeof children === "function" ? children(args) : children} +
+ {description && description !== "" && ( + + {description} + + )} + + )} +
+); diff --git a/packages/component-library/src/Link/index.stories.tsx b/packages/component-library/src/Link/index.stories.tsx new file mode 100644 index 0000000000..f58cd0ea55 --- /dev/null +++ b/packages/component-library/src/Link/index.stories.tsx @@ -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; +export default meta; + +export const Link = { + args: { + children: "Link", + href: "https://www.pyth.network", + target: "_blank", + isDisabled: false, + }, +} satisfies StoryObj; diff --git a/packages/component-library/src/Link/index.tsx b/packages/component-library/src/Link/index.tsx new file mode 100644 index 0000000000..3fd21345e2 --- /dev/null +++ b/packages/component-library/src/Link/index.tsx @@ -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) => ( + +); diff --git a/packages/component-library/src/Radio/index.stories.tsx b/packages/component-library/src/Radio/index.stories.tsx new file mode 100644 index 0000000000..800eea208b --- /dev/null +++ b/packages/component-library/src/Radio/index.stories.tsx @@ -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) => ( + + + + ), + ], +} satisfies Meta; +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; diff --git a/packages/component-library/src/Radio/index.tsx b/packages/component-library/src/Radio/index.tsx new file mode 100644 index 0000000000..2c82ca6027 --- /dev/null +++ b/packages/component-library/src/Radio/index.tsx @@ -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) => ( + + {(args) => ( + <> +
+
+
+
+
+ {typeof children === "function" ? children(args) : children} + + )} + +); diff --git a/packages/component-library/src/RadioGroup/index.stories.tsx b/packages/component-library/src/RadioGroup/index.stories.tsx new file mode 100644 index 0000000000..596ab40f1d --- /dev/null +++ b/packages/component-library/src/RadioGroup/index.stories.tsx @@ -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) => ( +
+ +
+ ), + ], + render: (args) => ( + + + This is a radio button, check out how radioish it is and how it handles + multiline labels + + Second + Third + + ), +} satisfies Meta; +export default meta; + +export const RadioGroup = { + args: { + label: "This is a radio group!", + description: "", + isDisabled: false, + orientation: "vertical", + }, +} satisfies StoryObj; diff --git a/packages/component-library/src/RadioGroup/index.tsx b/packages/component-library/src/RadioGroup/index.tsx new file mode 100644 index 0000000000..cfa176230f --- /dev/null +++ b/packages/component-library/src/RadioGroup/index.tsx @@ -0,0 +1,36 @@ +import clsx from "clsx"; +import type { ComponentProps } from "react"; +import { + RadioGroup as BaseRadioGroup, + Label, + Text, +} from "react-aria-components"; + +type CheckboxGroupProps = ComponentProps & { + label: ComponentProps["children"]; + description?: ComponentProps["children"] | undefined; +}; + +export const RadioGroup = ({ + children, + className, + label, + description, + ...props +}: CheckboxGroupProps) => ( + + {(args) => ( + <> + +
+ {typeof children === "function" ? children(args) : children} +
+ {description && description !== "" && ( + + {description} + + )} + + )} +
+);