Skip to content

Commit

Permalink
feat(react-formio): add button molecule
Browse files Browse the repository at this point in the history
  • Loading branch information
Romakita committed Jan 18, 2025
1 parent 86ddca3 commit 828c292
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 0 deletions.
106 changes: 106 additions & 0 deletions packages/react-formio/src/molecules/button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Meta, StoryObj } from "@storybook/react";

import { Icon } from "../../atoms/icon/Icon";
import { Button, BUTTON_VARIANTS } from "./Button";

/**
* Button component with a label and an onClick handler.
*
* ```ts
* import {Button} from "@tsed/react-formio/molecules/button/Button";
* ```
*
* ## Override Button
*
* This component is registered with the name `Button` and can be overridden with the following code:
*
* ```ts
* registerComponent("Button", MyCustomButtonComponent);
* ```
*/
export default {
title: "Button",
component: Button,
argTypes: {
onClick: { action: "clicked" },
variant: {
control: "select",
options: BUTTON_VARIANTS
},
disabled: {
control: "boolean"
}
},
parameters: {
children: "Text",
variant: "primary"
}
} satisfies Meta<typeof Button>;

type Story = StoryObj<typeof Button>;

export const Usage: Story = {
args: {
children: "Text",
variant: "primary"
}
};

export const Variant: Story = {
args: {
children: "Text"
},
render(args) {
return (
<div className='flex flex-wrap gap-3'>
{BUTTON_VARIANTS.map((variant) => (
<div key={variant}>
<Button {...args} variant={variant as any}>
{variant}
</Button>
</div>
))}
</div>
);
}
};

export const Disabled: Story = {
args: {
children: "Text",
disabled: true
},
render(args) {
return (
<div className='flex flex-wrap gap-3'>
{BUTTON_VARIANTS.map((variant) => (
<div key={variant}>
<Button {...args} variant={variant as any}>
{variant}
</Button>
</div>
))}
</div>
);
}
};

export const WithIcon: Story = {
args: {
children: "Text"
},
render(args) {
return (
<div className='flex flex-wrap gap-3'>
{BUTTON_VARIANTS.map((variant) => (
<div key={variant}>
<Button {...args} variant={variant as any}>
<Icon name='save' />
{variant}
</Button>
</div>
))}
</div>
);
}
};
54 changes: 54 additions & 0 deletions packages/react-formio/src/molecules/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import cx from "classnames";
import { type ButtonHTMLAttributes, forwardRef, type LegacyRef, type PropsWithChildren } from "react";

import { registerComponent } from "../../registries/components";

export const BUTTON_VARIANTS = [
"primary",
"secondary",
"success",
"danger",
"warning",
"info",
"light",
"dark",
"link",
"outline-primary",
"outline-secondary",
"outline-success",
"outline-danger",
"outline-warning",
"outline-info",
"outline-light",
"outline-dark",
"outline-link"
];

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: (typeof BUTTON_VARIANTS)[keyof typeof BUTTON_VARIANTS] | string;
}

export const Button = forwardRef(
({ variant, className, children, ...props }: PropsWithChildren<ButtonProps>, ref: LegacyRef<HTMLButtonElement>) => {
return (
<button
{...props}
ref={ref}
className={cx(
"btn flex gap-1",
{
disabled: props.disabled
},
`btn-${variant}`,
className
)}
disabled={props.disabled}
onClick={(evt) => !props.disabled && props.onClick?.(evt)}
>
{children}
</button>
);
}
);

registerComponent("Button", Button);

0 comments on commit 828c292

Please sign in to comment.