Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/component-library/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}),
Expand Down
37 changes: 37 additions & 0 deletions packages/component-library/src/Checkbox/index.stories.tsx
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>;
42 changes: 42 additions & 0 deletions packages/component-library/src/Checkbox/index.tsx
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 packages/component-library/src/CheckboxGroup/index.stories.tsx
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>;
44 changes: 44 additions & 0 deletions packages/component-library/src/CheckboxGroup/index.tsx
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>
);
43 changes: 43 additions & 0 deletions packages/component-library/src/Link/index.stories.tsx
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>;
16 changes: 16 additions & 0 deletions packages/component-library/src/Link/index.tsx
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}
/>
);
38 changes: 38 additions & 0 deletions packages/component-library/src/Radio/index.stories.tsx
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>;
28 changes: 28 additions & 0 deletions packages/component-library/src/Radio/index.tsx
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 packages/component-library/src/RadioGroup/index.stories.tsx
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>;
Loading
Loading