chore(ui,icons,ui-preset,toolbox): Move design system packages to monorepo (#5470)

This commit is contained in:
Kasper Fabricius Kristensen
2023-11-07 22:17:44 +01:00
committed by GitHub
parent 71853eafdd
commit e4ce2f4e07
722 changed files with 30300 additions and 186 deletions

View File

@@ -0,0 +1,30 @@
import { render, screen } from "@testing-library/react"
import * as React from "react"
import { Plus } from "@medusajs/icons"
import { IconButton } from "./icon-button"
describe("IconButton", () => {
it("renders a IconButton", () => {
render(
<IconButton>
<Plus />
</IconButton>
)
const button = screen.getByRole("button")
expect(button).toBeInTheDocument()
})
it("renders a button as a link", () => {
render(
<IconButton asChild>
<a href="https://www.medusajs.com">
<Plus />
</a>
</IconButton>
)
const button = screen.getByRole("link")
expect(button).toBeInTheDocument()
})
})

View File

@@ -0,0 +1,83 @@
import type { Meta, StoryObj } from "@storybook/react"
import * as React from "react"
import { Plus } from "@medusajs/icons"
import { IconButton } from "./icon-button"
const meta: Meta<typeof IconButton> = {
title: "Components/IconButton",
component: IconButton,
parameters: {
layout: "centered",
},
}
export default meta
type Story = StoryObj<typeof IconButton>
export const BasePrimary: Story = {
args: {
variant: "primary",
size: "base",
children: <Plus />,
},
}
export const BaseTransparent: Story = {
args: {
variant: "transparent",
size: "base",
children: <Plus />,
},
}
export const LargePrimary: Story = {
args: {
variant: "primary",
size: "large",
children: <Plus />,
},
}
export const LargeTransparent: Story = {
args: {
variant: "transparent",
size: "large",
children: <Plus />,
},
}
export const XLargePrimary: Story = {
args: {
variant: "primary",
size: "xlarge",
children: <Plus />,
},
}
export const XLargeTransparent: Story = {
args: {
variant: "transparent",
size: "xlarge",
children: <Plus />,
},
}
export const Disabled: Story = {
args: {
variant: "primary",
size: "base",
children: <Plus />,
disabled: true,
},
}
export const IsLoading: Story = {
args: {
variant: "primary",
size: "base",
children: <Plus />,
isLoading: true,
},
}

View File

@@ -0,0 +1,105 @@
import { Spinner } from "@medusajs/icons"
import { Slot } from "@radix-ui/react-slot"
import { VariantProps, cva } from "class-variance-authority"
import * as React from "react"
import { clx } from "@/utils/clx"
const iconButtonVariants = 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:shadow-buttons-neutral disabled:text-ui-fg-disabled disabled:after:hidden"
),
{
variants: {
variant: {
primary: clx(
"shadow-buttons-neutral text-ui-fg-subtle 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",
"after:absolute after:inset-0 after:content-['']"
),
transparent: clx(
"text-ui-fg-subtle 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"
),
},
size: {
base: "h-8 w-8 p-1.5",
large: "h-10 w-10 p-2.5",
xlarge: "h-12 w-12 p-3.5",
},
},
defaultVariants: {
variant: "primary",
size: "base",
},
}
)
interface IconButtonProps
extends React.ComponentPropsWithoutRef<"button">,
VariantProps<typeof iconButtonVariants> {
asChild?: boolean
isLoading?: boolean
}
const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
(
{
variant = "primary",
size = "base",
asChild = false,
className,
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(iconButtonVariants({ variant, size }), className)}
disabled={disabled || isLoading}
>
{renderInner()}
</Component>
)
}
)
IconButton.displayName = "IconButton"
export { IconButton, iconButtonVariants }

View File

@@ -0,0 +1 @@
export * from "./icon-button"