chore(ui,icons,ui-preset,toolbox): Move design system packages to monorepo (#5470)
This commit is contained in:
committed by
GitHub
parent
71853eafdd
commit
e4ce2f4e07
@@ -0,0 +1,23 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import * as React from "react"
|
||||
|
||||
import { Button } from "./button"
|
||||
|
||||
describe("Button", () => {
|
||||
it("renders a button", () => {
|
||||
render(<Button>Click me</Button>)
|
||||
const button = screen.getByRole("button", { name: "Click me" })
|
||||
expect(button).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("renders a button as a link", () => {
|
||||
render(
|
||||
<Button asChild>
|
||||
<a href="https://www.medusajs.com">Go to website</a>
|
||||
</Button>
|
||||
)
|
||||
|
||||
const button = screen.getByRole("link", { name: "Go to website" })
|
||||
expect(button).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,78 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react"
|
||||
import * as React from "react"
|
||||
|
||||
import { PlusMini } from "@medusajs/icons"
|
||||
import { Button } from "./button"
|
||||
|
||||
const meta: Meta<typeof Button> = {
|
||||
title: "Components/Button",
|
||||
component: Button,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof Button>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
},
|
||||
}
|
||||
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
variant: "secondary",
|
||||
},
|
||||
}
|
||||
|
||||
export const Transparent: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
variant: "transparent",
|
||||
},
|
||||
}
|
||||
|
||||
export const Danger: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
variant: "danger",
|
||||
},
|
||||
}
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
disabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const WithIcon: Story = {
|
||||
args: {
|
||||
children: ["Action", <PlusMini key={1} />],
|
||||
},
|
||||
}
|
||||
|
||||
export const Loading: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
isLoading: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
size: "large",
|
||||
},
|
||||
}
|
||||
|
||||
export const XLarge: Story = {
|
||||
args: {
|
||||
children: "Action",
|
||||
size: "xlarge",
|
||||
},
|
||||
}
|
||||
118
packages/design-system/ui/src/components/button/button.tsx
Normal file
118
packages/design-system/ui/src/components/button/button.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
import * as React from "react"
|
||||
|
||||
import { clx } from "@/utils/clx"
|
||||
import { Spinner } from "@medusajs/icons"
|
||||
|
||||
const buttonVariants = cva(
|
||||
clx(
|
||||
"transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none",
|
||||
"disabled:bg-ui-bg-disabled disabled:border-ui-border-base disabled:text-ui-fg-disabled disabled:shadow-buttons-neutral disabled:after:hidden",
|
||||
"after:transition-fg after:absolute after:inset-0 after:content-['']"
|
||||
),
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
primary: clx(
|
||||
"shadow-buttons-inverted text-ui-fg-on-inverted bg-ui-button-inverted after:button-inverted-gradient",
|
||||
"hover:bg-ui-button-inverted-hover hover:after:button-inverted-hover-gradient",
|
||||
"active:bg-ui-button-inverted-pressed active:after:button-inverted-pressed-gradient",
|
||||
"focus:!shadow-buttons-inverted-focus"
|
||||
),
|
||||
secondary: clx(
|
||||
"shadow-buttons-neutral text-ui-fg-base bg-ui-button-neutral after:button-neutral-gradient",
|
||||
"hover:bg-ui-button-neutral-hover hover:after:button-neutral-hover-gradient",
|
||||
"active:bg-ui-button-neutral-pressed active:after:button-neutral-pressed-gradient",
|
||||
"focus:shadow-buttons-neutral-focus"
|
||||
),
|
||||
transparent: clx(
|
||||
"after:hidden",
|
||||
"text-ui-fg-base bg-ui-button-transparent",
|
||||
"hover:bg-ui-button-transparent-hover",
|
||||
"active:bg-ui-button-transparent-pressed",
|
||||
"focus:shadow-buttons-neutral-focus focus:bg-ui-bg-base",
|
||||
"disabled:!bg-transparent disabled:!shadow-none"
|
||||
),
|
||||
danger: clx(
|
||||
"shadow-buttons-colored shadow-buttons-danger text-ui-fg-on-color bg-ui-button-danger after:button-danger-gradient",
|
||||
"hover:bg-ui-button-danger-hover hover:after:button-danger-hover-gradient",
|
||||
"active:bg-ui-button-danger-pressed active:after:button-danger-pressed-gradient",
|
||||
"focus:shadow-buttons-danger-focus"
|
||||
),
|
||||
},
|
||||
size: {
|
||||
base: "txt-compact-small-plus gap-x-1.5 px-3 py-1.5",
|
||||
large: "txt-compact-medium-plus gap-x-1.5 px-4 py-2.5",
|
||||
xlarge: "txt-compact-large-plus gap-x-1.5 px-5 py-3.5",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "base",
|
||||
variant: "primary",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
interface ButtonProps
|
||||
extends React.ComponentPropsWithoutRef<"button">,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
isLoading?: boolean
|
||||
asChild?: boolean
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(
|
||||
{
|
||||
variant = "primary",
|
||||
size = "base",
|
||||
className,
|
||||
asChild = false,
|
||||
children,
|
||||
isLoading = false,
|
||||
disabled,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const Component = asChild ? Slot : "button"
|
||||
|
||||
/**
|
||||
* In the case of a button where asChild is true, and isLoading is true, we ensure that
|
||||
* only on element is passed as a child to the Slot component. This is because the Slot
|
||||
* component only accepts a single child.
|
||||
*/
|
||||
const renderInner = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<span className="pointer-events-none">
|
||||
<div
|
||||
className={clx(
|
||||
"bg-ui-bg-disabled absolute inset-0 flex items-center justify-center rounded-md"
|
||||
)}
|
||||
>
|
||||
<Spinner className="animate-spin" />
|
||||
</div>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return children
|
||||
}
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={clx(buttonVariants({ variant, size }), className)}
|
||||
disabled={disabled || isLoading}
|
||||
>
|
||||
{renderInner()}
|
||||
</Component>
|
||||
)
|
||||
}
|
||||
)
|
||||
Button.displayName = "Button"
|
||||
|
||||
export { Button, buttonVariants }
|
||||
1
packages/design-system/ui/src/components/button/index.ts
Normal file
1
packages/design-system/ui/src/components/button/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./button"
|
||||
Reference in New Issue
Block a user