Skip to content

Commit

Permalink
Merge pull request #81 from aversini/feat!-introducing-Buttons-size-p…
Browse files Browse the repository at this point in the history
…rop-and-refactor

feat!: introducing Buttons size prop and refactor
  • Loading branch information
aversini authored Nov 26, 2023
2 parents 3ec2ef0 + 27613b2 commit 23383fe
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 44 deletions.
7 changes: 6 additions & 1 deletion packages/documentation/src/stories/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const meta: Meta<typeof Button> = {
kind: "dark",
focus: "light",
slim: false,
size: "medium",
type: "button",
raw: false,
noBorder: false,
Expand All @@ -31,6 +32,10 @@ const meta: Meta<typeof Button> = {
noBorder: {
control: "boolean",
},
size: {
options: ["small", "medium", "large"],
control: { type: "radio" },
},
slim: {
control: "boolean",
},
Expand All @@ -52,7 +57,7 @@ type Story = StoryObj<typeof Button>;

export const Basic: Story = {
render: (args) => (
<div className="flex gap-2">
<div className="flex flex-wrap gap-2">
<Button {...args}>Button</Button>
<Button {...args}>Button</Button>
<Button {...args}>Button</Button>
Expand Down
13 changes: 9 additions & 4 deletions packages/documentation/src/stories/ButtonIcon.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react";
import { ButtonIcon, IconSettings } from "@versini/ui-components";
import { ButtonIcon, IconEdit, IconSettings } from "@versini/ui-components";

const meta: Meta<typeof ButtonIcon> = {
component: ButtonIcon,
Expand All @@ -14,6 +14,7 @@ const meta: Meta<typeof ButtonIcon> = {
type: "button",
raw: false,
noBorder: false,
size: "medium",
},
argTypes: {
className: {
Expand All @@ -39,6 +40,10 @@ const meta: Meta<typeof ButtonIcon> = {
raw: {
control: "boolean",
},
size: {
options: ["small", "medium", "large"],
control: { type: "radio" },
},
},
};

Expand All @@ -48,18 +53,18 @@ type Story = StoryObj<typeof ButtonIcon>;

export const Basic: Story = {
render: (args) => (
<div className="flex gap-2">
<div className="flex flex-wrap gap-2">
<ButtonIcon {...args}>
<IconSettings />
</ButtonIcon>
<ButtonIcon {...args}>
<IconSettings />
</ButtonIcon>
<ButtonIcon {...args}>
<IconSettings />
<IconEdit className="h-3 w-3" />
</ButtonIcon>
<ButtonIcon {...args}>
<IconSettings />
<IconEdit />
</ButtonIcon>
</div>
),
Expand Down
18 changes: 14 additions & 4 deletions packages/documentation/src/stories/ButtonLink.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const meta: Meta<typeof ButtonLink> = {
link: "https://www.google.com",
noBorder: false,
slim: false,
size: "small",
},
argTypes: {
className: {
Expand All @@ -39,6 +40,13 @@ const meta: Meta<typeof ButtonLink> = {
slim: {
control: "boolean",
},
size: {
options: ["small", "medium", "large"],
control: { type: "radio" },
},
maxLabelLength: {
control: "number",
},
},
};

Expand All @@ -48,11 +56,13 @@ type Story = StoryObj<typeof ButtonLink>;

export const Basic: Story = {
render: (args) => (
<div className="flex gap-2">
<ButtonLink {...args}>Button as a link</ButtonLink>
<ButtonLink {...args}>Button as a link</ButtonLink>
<ButtonLink {...args}>Button as a link</ButtonLink>
<div className="flex flex-wrap gap-2">
<ButtonLink {...args}>Button as a link</ButtonLink>
<ButtonLink {...args}>Button as a link lorem ipsum</ButtonLink>
<ButtonLink {...args}>Button as a link lorem ipsum dolor</ButtonLink>
<ButtonLink {...args}>
Button as a link lorem ipsum dolor sit amet
</ButtonLink>
</div>
),
};
2 changes: 2 additions & 0 deletions packages/ui-components/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
fullWidth = false,
className,
slim = false,
size = "medium",
type = "button",
raw = false,
noBorder = false,
Expand All @@ -30,6 +31,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
raw,
className,
slim,
size,
noBorder,
});

Expand Down
2 changes: 2 additions & 0 deletions packages/ui-components/src/components/Button/ButtonIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const ButtonIcon = React.forwardRef<HTMLButtonElement, ButtonIconProps>(
noBorder = false,
"aria-label": ariaLabel,
label,
size = "medium",
},
ref,
) => {
Expand All @@ -30,6 +31,7 @@ export const ButtonIcon = React.forwardRef<HTMLButtonElement, ButtonIconProps>(
raw,
className,
noBorder,
size,
});

return (
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-components/src/components/Button/ButtonLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const ButtonLink = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
fullWidth = false,
className,
slim = false,
size = "small",
raw = false,
noBorder = false,
"aria-label": ariaLabel,
Expand All @@ -31,6 +32,7 @@ export const ButtonLink = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
raw,
className,
slim,
size,
noBorder,
});

Expand Down
18 changes: 11 additions & 7 deletions packages/ui-components/src/components/Button/ButtonTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ export type CommonButtonProps = {
focus?: "dark" | "light";
fullWidth?: boolean;
className?: string;
slim?: boolean;
raw?: boolean;
noBorder?: boolean;
};
Expand All @@ -12,20 +11,25 @@ export type ButtonProps = {
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
type?: "button" | "submit" | "reset";
slim?: boolean;
size?: "small" | "medium" | "large";
} & CommonButtonProps & {
children?: React.ReactNode;
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

export type ButtonIconProps = {
label?: string;
children: React.ReactNode;
} & CommonButtonProps &
React.ButtonHTMLAttributes<HTMLButtonElement>;

export type ButtonLinkProps = {
children?: React.ReactNode;
link?: string;
target?: string;
maxLabelLength?: number;
slim?: boolean;
size?: "small" | "medium" | "large";
} & ButtonProps &
React.AnchorHTMLAttributes<HTMLAnchorElement>;

export type ButtonIconProps = {
label?: string;
children: React.ReactNode;
size?: "small" | "medium" | "large";
} & CommonButtonProps &
React.ButtonHTMLAttributes<HTMLButtonElement>;
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ describe("Button modifiers", () => {
"px-4",
"py-1",
"max-h-9",
"text-sm",
"text-base",
"font-medium",
"sm:text-base",
"bg-action-dark",
"text-copy-light",
"hover:bg-action-dark-hover",
Expand All @@ -38,10 +37,28 @@ describe("Button modifiers", () => {
]);
});

it("should render a slim button", async () => {
it("should render a slim (legacy) button", async () => {
render(<Button slim>hello</Button>);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["px-2", "py-0", "sm:px-4", "max-h-8"]);
expectToHaveClasses(button, ["px-4", "py-0", "max-h-8"]);
});

it("should render a size small button", async () => {
render(<Button size="small">hello</Button>);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["px-4", "py-0", "max-h-8"]);
});

it("should render a size medium button", async () => {
render(<Button size="medium">hello</Button>);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["px-4", "py-1", "max-h-9"]);
});

it("should render a size large button", async () => {
render(<Button size="large">hello</Button>);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["px-4", "py-2", "max-h-12"]);
});

it("should render a dark button", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { render, screen } from "@testing-library/react";

import { expectToHaveClasses } from "../../../common/__tests__/helpers";
import { ButtonIcon, IconSettings } from "../..";

describe("ButtonIcon (exceptions)", () => {
Expand All @@ -16,7 +17,15 @@ describe("ButtonIcon modifiers", () => {
</ButtonIcon>,
);
const button = await screen.findByRole("button");
expect(button.className).toContain("p-2");
expect(button.className).toContain("p-1");
expectToHaveClasses(button, [
"flex",
"items-center",
"justify-center",
"rounded-full",
"focus:outline-none",
"focus:ring-2",
]);
});

it("should render a dark button", async () => {
Expand Down Expand Up @@ -76,4 +85,34 @@ describe("ButtonIcon modifiers", () => {
const button = await screen.findByRole("button");
expect(button.className).toContain("w-full");
});

it("should render a size small button", async () => {
render(
<ButtonIcon size="small">
<IconSettings />
</ButtonIcon>,
);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["w-6", "p-0"]);
});

it("should render a size medium button", async () => {
render(
<ButtonIcon size="medium">
<IconSettings />
</ButtonIcon>,
);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["w-8", "p-1"]);
});

it("should render a size large button", async () => {
render(
<ButtonIcon size="large">
<IconSettings />
</ButtonIcon>,
);
const button = await screen.findByRole("button");
expectToHaveClasses(button, ["w-10", "p-2"]);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { render, screen } from "@testing-library/react";

import { expectToHaveClasses } from "../../../common/__tests__/helpers";
import { ButtonLink } from "../..";

describe("ButtonLink (exceptions)", () => {
Expand All @@ -12,10 +13,10 @@ describe("ButtonLink modifiers", () => {
it("should render a default anchor", async () => {
render(<ButtonLink link="toto">hello</ButtonLink>);
const button = await screen.findByRole("link");
expect(button.className).toContain("py-1");
expect(button.className).toContain("py-0");
});

it("should render a slim anchor", async () => {
it("should render a slim (legacy) anchor", async () => {
render(
<ButtonLink slim link="toto">
hello
Expand All @@ -25,6 +26,36 @@ describe("ButtonLink modifiers", () => {
expect(button.className).toContain("py-0");
});

it("should render a size small anchor", async () => {
render(
<ButtonLink size="small" link="toto">
hello
</ButtonLink>,
);
const button = await screen.findByRole("link");
expectToHaveClasses(button, ["px-4", "py-0", "max-h-8"]);
});

it("should render a size medium anchor", async () => {
render(
<ButtonLink size="medium" link="toto">
hello
</ButtonLink>,
);
const button = await screen.findByRole("link");
expectToHaveClasses(button, ["px-4", "py-1", "max-h-9"]);
});

it("should render a size large anchor", async () => {
render(
<ButtonLink size="large" link="toto">
hello
</ButtonLink>,
);
const button = await screen.findByRole("link");
expectToHaveClasses(button, ["px-4", "py-2", "max-h-12"]);
});

it("should render a dark link", async () => {
render(
<ButtonLink kind="dark" link="toto">
Expand Down Expand Up @@ -66,7 +97,7 @@ describe("ButtonLink modifiers", () => {
</ButtonLink>,
);
const button = await screen.findByRole("link");
expect(button.className).toContain("py-1");
expect(button.className).toContain("py-0");
const label = await screen.findByText("hello...");
expect(label).toBeDefined();
});
Expand All @@ -78,7 +109,7 @@ describe("ButtonLink modifiers", () => {
</ButtonLink>,
);
const button = await screen.findByRole("link");
expect(button.className).toContain("py-1");
expect(button.className).toContain("py-0");
const label = await screen.findByText("hello world");
expect(label).toBeDefined();
});
Expand Down
Loading

0 comments on commit 23383fe

Please sign in to comment.