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/select/index.ts
Normal file
1
packages/design-system/ui/src/components/select/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./select"
|
||||
@@ -0,0 +1,219 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react"
|
||||
import * as React from "react"
|
||||
|
||||
import { Select } from "./select"
|
||||
|
||||
const meta: Meta<typeof Select> = {
|
||||
title: "Components/Select",
|
||||
component: Select,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof Select>
|
||||
|
||||
const data = [
|
||||
{
|
||||
label: "Shirts",
|
||||
items: [
|
||||
{
|
||||
value: "dress-shirt-striped",
|
||||
label: "Striped Dress Shirt",
|
||||
},
|
||||
{
|
||||
value: "relaxed-button-down",
|
||||
label: "Relaxed Fit Button Down",
|
||||
},
|
||||
{
|
||||
value: "slim-button-down",
|
||||
label: "Slim Fit Button Down",
|
||||
},
|
||||
{
|
||||
value: "dress-shirt-solid",
|
||||
label: "Solid Dress Shirt",
|
||||
},
|
||||
{
|
||||
value: "dress-shirt-check",
|
||||
label: "Check Dress Shirt",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "T-Shirts",
|
||||
items: [
|
||||
{
|
||||
value: "v-neck",
|
||||
label: "V-Neck",
|
||||
},
|
||||
{
|
||||
value: "crew-neck",
|
||||
label: "Crew Neck",
|
||||
},
|
||||
{
|
||||
value: "henley",
|
||||
label: "Henley",
|
||||
},
|
||||
{
|
||||
value: "polo",
|
||||
label: "Polo",
|
||||
},
|
||||
{
|
||||
value: "mock-neck",
|
||||
label: "Mock Neck",
|
||||
},
|
||||
{
|
||||
value: "turtleneck",
|
||||
label: "Turtleneck",
|
||||
},
|
||||
{
|
||||
value: "scoop-neck",
|
||||
label: "Scoop Neck",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<div className="w-[250px]">
|
||||
<Select>
|
||||
<Select.Trigger>
|
||||
<Select.Value placeholder="Select" />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{data.map((group) => (
|
||||
<Select.Group key={group.label}>
|
||||
<Select.Label>{group.label}</Select.Label>
|
||||
{group.items.map((item) => (
|
||||
<Select.Item key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Group>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export const Disabled: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<div className="w-[250px]">
|
||||
<Select>
|
||||
<Select.Trigger disabled={true}>
|
||||
<Select.Value placeholder="Select" />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{data.map((group) => (
|
||||
<Select.Group key={group.label}>
|
||||
<Select.Label>{group.label}</Select.Label>
|
||||
{group.items.map((item) => (
|
||||
<Select.Item key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Group>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export const Small: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<div className="w-[250px]">
|
||||
<Select size="small">
|
||||
<Select.Trigger>
|
||||
<Select.Value placeholder="Select" />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{data.map((group) => (
|
||||
<Select.Group key={group.label}>
|
||||
<Select.Label>{group.label}</Select.Label>
|
||||
{group.items.map((item) => (
|
||||
<Select.Item key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Group>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
// const InModalDemo = () => {
|
||||
// const [open, setOpen] = React.useState(false)
|
||||
// const prompt = usePrompt()
|
||||
|
||||
// const onClose = async () => {
|
||||
// const res = await prompt({
|
||||
// title: "Are you sure?",
|
||||
// description: "You have unsaved changes. Are you sure you want to close?",
|
||||
// confirmText: "Yes",
|
||||
// cancelText: "Cancel",
|
||||
// })
|
||||
|
||||
// if (!res) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// setOpen(false)
|
||||
// }
|
||||
|
||||
// return (
|
||||
// <Drawer open={open} onOpenChange={setOpen}>
|
||||
// <Drawer.Trigger asChild>
|
||||
// <Button>Edit Variant</Button>
|
||||
// </Drawer.Trigger>
|
||||
// <Drawer.Content>
|
||||
// <Drawer.Header>
|
||||
// <Drawer.Title>Edit Variant</Drawer.Title>
|
||||
// </Drawer.Header>
|
||||
// <Drawer.Body>
|
||||
// <Select size="small">
|
||||
// <Select.Trigger>
|
||||
// <Select.Value placeholder="Select" />
|
||||
// </Select.Trigger>
|
||||
// <Select.Content>
|
||||
// {data.map((group) => (
|
||||
// <Select.Group key={group.label}>
|
||||
// <Select.Label>{group.label}</Select.Label>
|
||||
// {group.items.map((item) => (
|
||||
// <Select.Item key={item.value} value={item.value}>
|
||||
// {item.label}
|
||||
// </Select.Item>
|
||||
// ))}
|
||||
// </Select.Group>
|
||||
// ))}
|
||||
// </Select.Content>
|
||||
// </Select>
|
||||
// </Drawer.Body>
|
||||
// <Drawer.Footer>
|
||||
// <Button variant="secondary" onClick={onClose}>
|
||||
// Cancel
|
||||
// </Button>
|
||||
// <Button>Save</Button>
|
||||
// </Drawer.Footer>
|
||||
// </Drawer.Content>
|
||||
// </Drawer>
|
||||
// )
|
||||
// }
|
||||
|
||||
// export const InModal: Story = {
|
||||
// render: () => {
|
||||
// return <InModalDemo />
|
||||
// },
|
||||
// }
|
||||
206
packages/design-system/ui/src/components/select/select.tsx
Normal file
206
packages/design-system/ui/src/components/select/select.tsx
Normal file
@@ -0,0 +1,206 @@
|
||||
"use client"
|
||||
|
||||
import { ChevronUpDown, EllipseMiniSolid } from "@medusajs/icons"
|
||||
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||
import { cva } from "class-variance-authority"
|
||||
import * as React from "react"
|
||||
|
||||
import { clx } from "@/utils/clx"
|
||||
|
||||
interface SelectProps
|
||||
extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> {
|
||||
size?: "base" | "small"
|
||||
}
|
||||
|
||||
type SelectContextValue = {
|
||||
size: "base" | "small"
|
||||
}
|
||||
|
||||
const SelectContext = React.createContext<SelectContextValue | null>(null)
|
||||
|
||||
const useSelectContext = () => {
|
||||
const context = React.useContext(SelectContext)
|
||||
|
||||
if (context === null) {
|
||||
throw new Error("useSelectContext must be used within a SelectProvider")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
const Root = ({ children, size = "base", ...props }: SelectProps) => {
|
||||
return (
|
||||
<SelectContext.Provider value={React.useMemo(() => ({ size }), [size])}>
|
||||
<SelectPrimitive.Root {...props}>{children}</SelectPrimitive.Root>
|
||||
</SelectContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
const Group = SelectPrimitive.Group
|
||||
|
||||
const Value = SelectPrimitive.Value
|
||||
|
||||
const triggerVariants = cva(
|
||||
clx(
|
||||
"bg-ui-bg-field txt-compact-medium shadow-buttons-neutral transition-fg flex w-full select-none items-center justify-between rounded-md outline-none",
|
||||
"data-[placeholder]:text-ui-fg-muted text-ui-fg-base",
|
||||
"hover:bg-ui-bg-field-hover",
|
||||
"focus:shadow-borders-interactive-with-active data-[state=open]:!shadow-borders-interactive-with-active",
|
||||
"aria-[invalid=true]:border-ui-border-error aria-[invalid=true]:shadow-borders-error",
|
||||
"invalid::border-ui-border-error invalid:shadow-borders-error",
|
||||
"disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
|
||||
"group/trigger"
|
||||
),
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
base: "h-10 px-3 py-[9px]",
|
||||
small: "h-8 px-2 py-[5px]",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const Trigger = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
||||
>(({ className, children, ...props }, ref) => {
|
||||
const { size } = useSelectContext()
|
||||
|
||||
return (
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={clx(triggerVariants({ size }), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<SelectPrimitive.Icon asChild>
|
||||
<ChevronUpDown className="text-ui-fg-muted group-disabled/trigger:text-ui-fg-disabled" />
|
||||
</SelectPrimitive.Icon>
|
||||
</SelectPrimitive.Trigger>
|
||||
)
|
||||
})
|
||||
Trigger.displayName = SelectPrimitive.Trigger.displayName
|
||||
|
||||
const Content = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
||||
>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
position = "popper",
|
||||
sideOffset = 8,
|
||||
collisionPadding = 24,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={clx(
|
||||
"bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout relative max-h-[200px] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded-lg",
|
||||
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
||||
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
||||
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
{
|
||||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1":
|
||||
position === "popper",
|
||||
},
|
||||
className
|
||||
)}
|
||||
position={position}
|
||||
sideOffset={sideOffset}
|
||||
collisionPadding={collisionPadding}
|
||||
{...props}
|
||||
>
|
||||
<SelectPrimitive.Viewport
|
||||
className={clx(
|
||||
"p-1",
|
||||
position === "popper" &&
|
||||
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</SelectPrimitive.Viewport>
|
||||
</SelectPrimitive.Content>
|
||||
</SelectPrimitive.Portal>
|
||||
)
|
||||
)
|
||||
Content.displayName = SelectPrimitive.Content.displayName
|
||||
|
||||
const Label = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Label
|
||||
ref={ref}
|
||||
className={clx(
|
||||
"txt-compact-xsmall-plus text-ui-fg-subtle px-3 py-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Label.displayName = SelectPrimitive.Label.displayName
|
||||
|
||||
const Item = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||
>(({ className, children, ...props }, ref) => {
|
||||
const { size } = useSelectContext()
|
||||
|
||||
return (
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={clx(
|
||||
"txt-compact-medium bg-ui-bg-base grid cursor-pointer grid-cols-[20px_1fr] gap-x-2 rounded-md px-3 py-2 outline-none transition-colors",
|
||||
"hover:bg-ui-bg-base-hover focus:bg-ui-bg-base-hover",
|
||||
{
|
||||
"txt-compact-medium data-[state=checked]:txt-compact-medium-plus":
|
||||
size === "base",
|
||||
"txt-compact-small data-[state=checked]:txt-compact-medium-plus":
|
||||
size === "small",
|
||||
},
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="flex h-5 w-5 items-center justify-center">
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<EllipseMiniSolid />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
<SelectPrimitive.ItemText className="flex-1 truncate">
|
||||
{children}
|
||||
</SelectPrimitive.ItemText>
|
||||
</SelectPrimitive.Item>
|
||||
)
|
||||
})
|
||||
Item.displayName = SelectPrimitive.Item.displayName
|
||||
|
||||
const Separator = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Separator
|
||||
ref={ref}
|
||||
className={clx("bg-ui-border-base -mx-1 my-1 h-px", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Separator.displayName = SelectPrimitive.Separator.displayName
|
||||
|
||||
const Select = Object.assign(Root, {
|
||||
Group,
|
||||
Value,
|
||||
Trigger,
|
||||
Content,
|
||||
Label,
|
||||
Item,
|
||||
Separator,
|
||||
})
|
||||
|
||||
export { Select }
|
||||
Reference in New Issue
Block a user