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
1
packages/design-system/ui/src/components/input/index.ts
Normal file
1
packages/design-system/ui/src/components/input/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./input"
|
||||
@@ -0,0 +1,11 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import * as React from "react"
|
||||
|
||||
import { Input } from "./input"
|
||||
|
||||
describe("Input", () => {
|
||||
it("should render the component", () => {
|
||||
render(<Input />)
|
||||
expect(screen.getByRole("textbox")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,55 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react"
|
||||
|
||||
import { Input } from "./input"
|
||||
|
||||
const meta: Meta<typeof Input> = {
|
||||
title: "Components/Input",
|
||||
component: Input,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof Input>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
placeholder: "Placeholder",
|
||||
},
|
||||
}
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
value: "Floyd Mayweather",
|
||||
disabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const Invalid: Story = {
|
||||
args: {
|
||||
placeholder: "Placeholder",
|
||||
required: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const Password: Story = {
|
||||
args: {
|
||||
type: "password",
|
||||
},
|
||||
}
|
||||
|
||||
export const Search: Story = {
|
||||
args: {
|
||||
type: "search",
|
||||
placeholder: "Search",
|
||||
},
|
||||
}
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
size: "small",
|
||||
placeholder: "Placeholder",
|
||||
},
|
||||
}
|
||||
104
packages/design-system/ui/src/components/input/input.tsx
Normal file
104
packages/design-system/ui/src/components/input/input.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client"
|
||||
|
||||
import { Eye, EyeSlash, MagnifyingGlassMini } from "@medusajs/icons"
|
||||
import { VariantProps, cva } from "class-variance-authority"
|
||||
import * as React from "react"
|
||||
|
||||
import { clx } from "@/utils/clx"
|
||||
|
||||
const inputBaseStyles = clx(
|
||||
"caret-ui-fg-base bg-ui-bg-field hover:bg-ui-bg-field-hover shadow-borders-base placeholder-ui-fg-muted text-ui-fg-base transition-fg relative w-full appearance-none rounded-md outline-none",
|
||||
"focus:shadow-borders-interactive-with-active",
|
||||
"disabled:text-ui-fg-disabled disabled:!bg-ui-bg-disabled disabled:placeholder-ui-fg-disabled disabled:cursor-not-allowed",
|
||||
"aria-[invalid=true]:!shadow-borders-error invalid:!shadow-borders-error"
|
||||
)
|
||||
|
||||
const inputVariants = cva(
|
||||
clx(
|
||||
inputBaseStyles,
|
||||
"[&::--webkit-search-cancel-button]:hidden [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
||||
),
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
base: "txt-compact-medium h-10 px-3 py-[9px]",
|
||||
small: "txt-compact-small h-8 px-2 py-[5px]",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "base",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const Input = React.forwardRef<
|
||||
HTMLInputElement,
|
||||
VariantProps<typeof inputVariants> &
|
||||
Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">
|
||||
>(({ className, type, size = "base", ...props }, ref) => {
|
||||
const [typeState, setTypeState] = React.useState(type)
|
||||
|
||||
const isPassword = type === "password"
|
||||
const isSearch = type === "search"
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<input
|
||||
ref={ref}
|
||||
type={isPassword ? typeState : type}
|
||||
className={clx(
|
||||
inputVariants({ size: size }),
|
||||
{
|
||||
"pr-11": isPassword && size === "base",
|
||||
"pl-11": isSearch && size === "base",
|
||||
"pr-9": isPassword && size === "small",
|
||||
"pl-9": isSearch && size === "small",
|
||||
},
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
{isSearch && (
|
||||
<div
|
||||
className={clx(
|
||||
"text-ui-fg-muted absolute bottom-0 left-0 flex items-center justify-center",
|
||||
{
|
||||
"h-10 w-11": size === "base",
|
||||
"h-8 w-9": size === "small",
|
||||
}
|
||||
)}
|
||||
role="img"
|
||||
>
|
||||
<MagnifyingGlassMini />
|
||||
</div>
|
||||
)}
|
||||
{isPassword && (
|
||||
<div
|
||||
className={clx(
|
||||
"absolute bottom-0 right-0 flex w-11 items-center justify-center",
|
||||
{
|
||||
"h-10 w-11": size === "base",
|
||||
"h-8 w-9": size === "small",
|
||||
}
|
||||
)}
|
||||
>
|
||||
<button
|
||||
className="text-ui-fg-muted hover:text-ui-fg-base focus:text-ui-fg-base focus:shadow-borders-interactive-w-focus active:text-ui-fg-base h-fit w-fit rounded-sm outline-none transition-all"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setTypeState(typeState === "password" ? "text" : "password")
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">
|
||||
{typeState === "password" ? "Show password" : "Hide password"}
|
||||
</span>
|
||||
{typeState === "password" ? <Eye /> : <EyeSlash />}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
Input.displayName = "Input"
|
||||
|
||||
export { Input, inputBaseStyles }
|
||||
Reference in New Issue
Block a user