feat(dashboard,ui): Streamline spacing and sizing (#6061)

This commit is contained in:
Kasper Fabricius Kristensen
2024-01-15 11:43:16 +01:00
committed by GitHub
parent 5dacd4ac9f
commit a2c149e7e5
266 changed files with 10738 additions and 4646 deletions

View File

@@ -10,14 +10,44 @@ const avatarVariants = cva({
base: "border-ui-border-strong flex shrink-0 items-center justify-center overflow-hidden border",
variants: {
variant: {
squared: "rounded-lg",
squared: "",
rounded: "rounded-full",
},
size: {
xsmall: "h-5 w-5",
small: "h-6 w-6",
base: "h-8 w-8",
large: "h-10 w-10",
xlarge: "h-12 w-12",
},
},
compoundVariants: [
{
variant: "squared",
size: "xsmall",
className: "rounded-[4px]",
},
{
variant: "squared",
size: "small",
className: "rounded-md",
},
{
variant: "squared",
size: "base",
className: "rounded-md",
},
{
variant: "squared",
size: "large",
className: "rounded-lg",
},
{
variant: "squared",
size: "xlarge",
className: "rounded-xl",
},
],
defaultVariants: {
variant: "rounded",
size: "base",
@@ -28,14 +58,44 @@ const innerVariants = cva({
base: "aspect-square object-cover object-center",
variants: {
variant: {
squared: "rounded-lg",
squared: "",
rounded: "rounded-full",
},
size: {
base: "txt-compact-small-plus h-6 w-6",
large: "txt-compact-medium-plus h-8 w-8",
xsmall: "txt-compact-xsmall-plus h-4 w-4",
small: "txt-compact-xsmall-plus h-5 w-5",
base: "txt-compact-small-plus h-7 w-7",
large: "txt-compact-medium-plus h-9 w-9",
xlarge: "txt-compact-large-plus h-11 w-11",
},
},
compoundVariants: [
{
variant: "squared",
size: "xsmall",
className: "rounded-sm",
},
{
variant: "squared",
size: "small",
className: "rounded-[4px]",
},
{
variant: "squared",
size: "base",
className: "rounded-[4px]",
},
{
variant: "squared",
size: "large",
className: "rounded-md",
},
{
variant: "squared",
size: "xlarge",
className: "rounded-[10px]",
},
],
defaultVariants: {
variant: "rounded",
size: "base",
@@ -60,24 +120,24 @@ const Avatar = React.forwardRef<
AvatarProps
>(
(
{
{
/**
* The URL of the image used in the Avatar.
*/
src,
src,
/**
* Text to show in the avatar if the URL provided in `src` can't be opened.
*/
fallback,
fallback,
/**
* The style of the avatar.
*/
variant = "rounded",
variant = "rounded",
/**
* The size of the avatar's border radius.
*/
size = "base",
className,
className,
...props
}: AvatarProps,
ref
@@ -86,7 +146,11 @@ const Avatar = React.forwardRef<
<Primitives.Root
ref={ref}
{...props}
className={clx(avatarVariants({ variant, size }), className)}
className={clx(
"rounded-x",
avatarVariants({ variant, size }),
className
)}
>
{src && (
<Primitives.Image

View File

@@ -17,30 +17,31 @@ const buttonVariants = cva({
"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"
"focus-visible:!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"
"focus-visible: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",
"focus-visible:shadow-buttons-neutral-focus focus-visible: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"
"focus-visible:shadow-buttons-danger-focus"
),
},
size: {
small: "txt-compact-small-plus gap-x-1 px-2 py-1",
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",

View File

@@ -1,6 +1,6 @@
"use client"
import { ChevronLeftMini, ChevronRightMini } from "@medusajs/icons"
import { TriangleLeftMini, TriangleRightMini } from "@medusajs/icons"
import * as React from "react"
import {
DayPicker,
@@ -38,7 +38,7 @@ type CalendarProps =
/**
* This component is based on the [react-date-picker](https://www.npmjs.com/package/react-date-picker) package.
*
*
* @excludeExternal
*/
const Calendar = ({
@@ -56,10 +56,16 @@ const Calendar = ({
mode = "single",
/**
* Whether to show days of previous and next months.
*
*
* @keep
*/
showOutsideDays = true,
/**
* The locale to use for formatting dates. To change the locale pass a date-fns locale object.
*
* @keep
*/
locale,
...props
}: CalendarProps) => {
return (
@@ -70,12 +76,12 @@ const Calendar = ({
classNames={{
months: "flex flex-col sm:flex-row",
month: "space-y-2 p-3",
caption: "flex justify-center relative items-center h-9",
caption: "flex justify-center relative items-center h-8",
caption_label:
"txt-compact-small-plus absolute bottom-0 left-0 right-0 top-1 flex items-center justify-center text-ui-fg-base",
"txt-compact-small-plus absolute bottom-0 left-0 right-0 top-0 flex items-center justify-center text-ui-fg-base",
nav: "space-x-1 flex items-center bg-ui-bg-base-pressed rounded-md w-full h-full justify-between p-0.5",
nav_button: clx(
iconButtonVariants({ variant: "primary", size: "base" })
iconButtonVariants({ variant: "transparent", size: "small" })
),
nav_button_previous: "!absolute left-0.5",
nav_button_next: "!absolute right-0.5",
@@ -86,9 +92,9 @@ const Calendar = ({
),
row: "flex w-full mt-2 gap-x-2",
cell: "txt-compact-small-plus relative rounded-md p-0 text-center focus-within:relative",
day: "txt-compact-small-plus text-ui-fg-base bg-ui-bg-base hover:bg-ui-bg-base-hover focus:shadow-borders-interactive-with-focus h-8 w-8 rounded-md p-0 text-center outline-none transition-all",
day: "txt-compact-small-plus text-ui-fg-base bg-ui-bg-base hover:bg-ui-bg-base-hover focus-visible:shadow-borders-interactive-with-focus h-8 w-8 rounded-md p-0 text-center outline-none transition-all",
day_selected:
"bg-ui-bg-interactive text-ui-fg-on-color hover:bg-ui-bg-interactive focus:bg-ui-bg-interactive",
"bg-ui-bg-interactive text-ui-fg-on-color hover:bg-ui-bg-interactive focus-visible:bg-ui-bg-interactive",
day_outside: "text-ui-fg-disabled aria-selected:text-ui-fg-on-color",
day_disabled: "text-ui-fg-disabled",
day_range_middle:
@@ -96,9 +102,10 @@ const Calendar = ({
day_hidden: "invisible",
...classNames,
}}
locale={locale}
components={{
IconLeft: () => <ChevronLeftMini />,
IconRight: () => <ChevronRightMini />,
IconLeft: () => <TriangleLeftMini />,
IconRight: () => <TriangleRightMini />,
Day: Day,
}}
{...(props as SingleProps & RangeProps)}

View File

@@ -23,7 +23,7 @@ const Checkbox = React.forwardRef<
className
)}
>
<div className="text-ui-fg-on-inverted bg-ui-bg-base shadow-borders-base group-hover:bg-ui-bg-base-hover group-focus:!shadow-borders-interactive-with-focus group-data-[state=checked]:bg-ui-bg-interactive group-data-[state=checked]:shadow-borders-interactive-with-shadow group-data-[state=indeterminate]:bg-ui-bg-interactive group-data-[state=indeterminate]:shadow-borders-interactive-with-shadow [&_path]:shadow-details-contrast-on-bg-interactive group-disabled:text-ui-fg-disabled group-disabled:!bg-ui-bg-disabled group-disabled:!shadow-borders-base transition-fg h-[14px] w-[14px] rounded-[3px]">
<div className="text-ui-fg-on-inverted bg-ui-bg-base shadow-borders-base group-hover:bg-ui-bg-base-hover group-focus-visible:!shadow-borders-interactive-with-focus group-data-[state=checked]:bg-ui-bg-interactive group-data-[state=checked]:shadow-borders-interactive-with-shadow group-data-[state=indeterminate]:bg-ui-bg-interactive group-data-[state=indeterminate]:shadow-borders-interactive-with-shadow [&_path]:shadow-details-contrast-on-bg-interactive group-disabled:text-ui-fg-disabled group-disabled:!bg-ui-bg-disabled group-disabled:!shadow-borders-base transition-fg h-[14px] w-[14px] rounded-[3px]">
<Primitives.Indicator className="absolute inset-0">
{checked === "indeterminate" ? <MinusMini /> : <CheckMini />}
</Primitives.Indicator>

View File

@@ -69,7 +69,7 @@ const Root = ({
Root.displayName = "CommandBar"
/**
* The value component of the command bar. This component is used to display a value,
* The value component of the command bar. This component is used to display a value,
* such as the number of selected items which the commands will act on.
*/
const Value = React.forwardRef<
@@ -143,24 +143,24 @@ interface CommandProps
const Command = React.forwardRef<HTMLButtonElement, CommandProps>(
(
{
className,
className,
/**
* @ignore
*/
type = "button",
type = "button",
/**
* The command's label.
*/
label,
label,
/**
* The function to execute when the command is triggered.
*/
action,
action,
/**
* The command's shortcut
*/
shortcut,
disabled,
shortcut,
disabled,
...props
}: CommandProps,
ref
@@ -188,7 +188,7 @@ const Command = React.forwardRef<HTMLButtonElement, CommandProps>(
ref={ref}
className={clx(
"bg-ui-contrast-bg-base txt-compact-small-plus transition-fg text-ui-contrast-fg-primary flex items-center gap-x-2 px-3 py-2.5 outline-none",
"focus:bg-ui-contrast-bg-highlight focus:hover:bg-ui-contrast-bg-base-hover hover:bg-ui-contrast-bg-base-hover active:bg-ui-contrast-bg-base-pressed focus:active:bg-ui-contrast-bg-base-pressed disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
"focus-visible:bg-ui-contrast-bg-highlight focus-visible:hover:bg-ui-contrast-bg-base-hover hover:bg-ui-contrast-bg-base-hover active:bg-ui-contrast-bg-base-pressed focus-visible:active:bg-ui-contrast-bg-base-pressed disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
"last-of-type:-mr-1 last-of-type:pr-4",
className
)}

View File

@@ -15,8 +15,8 @@ const currencyInputVariants = cva({
),
variants: {
size: {
base: "txt-compact-medium h-10 px-3",
small: "txt-compact-small h-8 px-2",
base: "txt-compact-medium h-8",
small: "txt-compact-small h-7",
},
},
defaultVariants: {
@@ -36,27 +36,27 @@ interface CurrencyInputProps
/**
* This component is based on the input element and supports all of its props
*
*
* @excludeExternal
*/
const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
(
{
{
/**
* The input's size.
*/
size = "base",
size = "base",
/**
* The symbol to show in the input.
*/
symbol,
symbol,
/**
* The currency code to show in the input.
*/
code,
disabled,
onInvalid,
className,
code,
disabled,
onInvalid,
className,
...props
}: CurrencyInputProps,
ref
@@ -101,7 +101,7 @@ const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
)}
>
<span
className={clx("w-fit", {
className={clx("w-fit min-w-[32px] border-r px-2", {
"py-[9px]": size === "base",
"py-[5px]": size === "small",
})}
@@ -126,10 +126,13 @@ const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
{...props}
/>
<span
className={clx("w-fit min-w-[16px] text-right", {
"py-[9px]": size === "base",
"py-[5px]": size === "small",
})}
className={clx(
"flex w-fit min-w-[32px] items-center justify-center border-l px-2 text-right",
{
"py-[9px]": size === "base",
"py-[5px]": size === "small",
}
)}
role="presentation"
>
<Text

View File

@@ -4,7 +4,7 @@ import { Time } from "@internationalized/date"
import { Calendar as CalendarIcon, Minus } from "@medusajs/icons"
import * as Primitives from "@radix-ui/react-popover"
import { TimeValue } from "@react-aria/datepicker"
import { format } from "date-fns"
import { format, type Locale } from "date-fns"
import * as React from "react"
import { Button } from "@/components/button"
@@ -19,14 +19,14 @@ const displayVariants = cva({
base: clx(
"text-ui-fg-base bg-ui-bg-field transition-fg shadow-buttons-neutral flex w-full items-center gap-x-2 rounded-md outline-none",
"hover:bg-ui-bg-field-hover",
"focus:shadow-borders-interactive-with-active data-[state=open]:shadow-borders-interactive-with-active",
"focus-visible:shadow-borders-interactive-with-active data-[state=open]:shadow-borders-interactive-with-active",
"disabled:bg-ui-bg-disabled disabled:text-ui-fg-disabled disabled:shadow-buttons-neutral",
"aria-[invalid=true]:!shadow-borders-error"
),
variants: {
size: {
base: "txt-compact-medium h-10 px-3 py-2.5",
small: "txt-compact-small h-8 px-2 py-1.5",
base: "txt-compact-small h-8 px-2 py-1.5",
small: "txt-compact-small h-7 px-2 py-1",
},
},
defaultVariants: {
@@ -39,41 +39,43 @@ interface DisplayProps extends React.ComponentProps<"button"> {
size?: "small" | "base"
}
const Display = React.forwardRef<
HTMLButtonElement,
DisplayProps
>(({
className,
children,
/**
* Placeholder of the date picker's input.
*/
placeholder,
/**
* The size of the date picker's input.
*/
size = "base",
...props
}: DisplayProps, ref) => {
return (
<Primitives.Trigger asChild>
<button
ref={ref}
className={clx(displayVariants({ size }), className)}
{...props}
>
<CalendarIcon className="text-ui-fg-muted" />
<span className="flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-left">
{children ? (
children
) : placeholder ? (
<span className="text-ui-fg-muted">{placeholder}</span>
) : null}
</span>
</button>
</Primitives.Trigger>
)
})
const Display = React.forwardRef<HTMLButtonElement, DisplayProps>(
(
{
className,
children,
/**
* Placeholder of the date picker's input.
*/
placeholder,
/**
* The size of the date picker's input.
*/
size = "base",
...props
}: DisplayProps,
ref
) => {
return (
<Primitives.Trigger asChild>
<button
ref={ref}
className={clx(displayVariants({ size }), className)}
{...props}
>
<CalendarIcon className="text-ui-fg-muted" />
<span className="flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-left">
{children ? (
children
) : placeholder ? (
<span className="text-ui-fg-muted">{placeholder}</span>
) : null}
</span>
</button>
</Primitives.Trigger>
)
}
)
Display.displayName = "DatePicker.Display"
const Flyout = React.forwardRef<
@@ -219,7 +221,7 @@ const PresetContainer = <TPreset extends Preset, TValue>({
className={clx(
"txt-compact-small-plus w-full overflow-hidden text-ellipsis whitespace-nowrap rounded-md p-2 text-left",
"text-ui-fg-subtle hover:bg-ui-bg-base-hover outline-none transition-all",
"focus:bg-ui-bg-base-hover",
"focus-visible:bg-ui-bg-base-hover",
{
"!bg-ui-bg-base-pressed": matchesCurrent(preset),
}
@@ -284,6 +286,18 @@ type CalendarProps = {
* The date to show dates to.
*/
toDate?: Date
/**
* Locale to use for formatting dates. To change the locale pass a `date-fns` locale object.
*/
locale?: Locale
}
type Translations = {
cancel?: string
apply?: string
start?: string
end?: string
range?: string
}
interface PickerProps extends CalendarProps {
@@ -299,6 +313,10 @@ interface PickerProps extends CalendarProps {
* Whether the date picker's input is required.
*/
required?: boolean
/**
* The date picker's placeholder.
*/
placeholder?: string
/**
* The date picker's size.
*/
@@ -307,6 +325,10 @@ interface PickerProps extends CalendarProps {
* Whether to show a time picker along with the date picker.
*/
showTimePicker?: boolean
/**
* Translation keys for the date picker. Use this to localize the date picker.
*/
translations?: Translations
id?: string
"aria-invalid"?: boolean
"aria-label"?: string
@@ -330,6 +352,8 @@ const SingleDatePicker = ({
showTimePicker,
disabled,
className,
placeholder,
translations,
...props
}: SingleProps) => {
const [open, setOpen] = React.useState(false)
@@ -458,7 +482,7 @@ const SingleDatePicker = ({
return (
<Primitives.Root open={open} onOpenChange={onOpenChange}>
<Display
placeholder="Pick a date"
placeholder={placeholder}
disabled={disabled}
className={className}
aria-required={props.required || props["aria-required"]}
@@ -507,19 +531,21 @@ const SingleDatePicker = ({
<div className="border-ui-border-base flex items-center gap-x-2 border-t p-3">
<Button
variant="secondary"
size="small"
className="w-full"
type="button"
onClick={onCancel}
>
Cancel
{translations?.cancel ?? "Cancel"}
</Button>
<Button
variant="primary"
size="small"
className="w-full"
type="button"
onClick={onApply}
>
Apply
{translations?.apply ?? "Apply"}
</Button>
</div>
</div>
@@ -558,6 +584,8 @@ const RangeDatePicker = ({
presets,
disabled,
className,
placeholder,
translations,
...props
}: RangeProps) => {
const [open, setOpen] = React.useState(false)
@@ -730,7 +758,7 @@ const RangeDatePicker = ({
return (
<Primitives.Root open={open} onOpenChange={onOpenChange}>
<Display
placeholder="Pick a date"
placeholder={placeholder}
disabled={disabled}
className={className}
aria-required={props.required || props["aria-required"]}
@@ -772,7 +800,9 @@ const RangeDatePicker = ({
{showTimePicker && (
<div className="border-ui-border-base flex items-center justify-evenly gap-x-3 border-t p-3">
<div className="flex flex-1 items-center gap-x-2">
<span className="text-ui-fg-subtle">Start:</span>
<span className="text-ui-fg-subtle">
{translations?.start ?? "Start"}:
</span>
<TimeInput
value={startTime}
onChange={(v) => onTimeChange(v, "start")}
@@ -783,7 +813,9 @@ const RangeDatePicker = ({
</div>
<Minus className="text-ui-fg-muted" />
<div className="flex flex-1 items-center gap-x-2">
<span className="text-ui-fg-subtle">End:</span>
<span className="text-ui-fg-subtle">
{translations?.end ?? "End"}:
</span>
<TimeInput
value={endTime}
onChange={(v) => onTimeChange(v, "end")}
@@ -796,15 +828,27 @@ const RangeDatePicker = ({
)}
<div className="flex items-center justify-between border-t p-3">
<p className={clx("text-ui-fg-subtle txt-compact-small-plus")}>
<span className="text-ui-fg-muted">Range:</span>{" "}
<span className="text-ui-fg-muted">
{translations?.range ?? "Range"}:
</span>{" "}
{displayRange}
</p>
<div className="flex items-center gap-x-2">
<Button variant="secondary" type="button" onClick={onCancel}>
Cancel
<Button
size="small"
variant="secondary"
type="button"
onClick={onCancel}
>
{translations?.cancel ?? "Cancel"}
</Button>
<Button variant="primary" type="button" onClick={onApply}>
Apply
<Button
size="small"
variant="primary"
type="button"
onClick={onApply}
>
{translations?.apply ?? "Apply"}
</Button>
</div>
</div>
@@ -818,7 +862,7 @@ const RangeDatePicker = ({
/**
* @interface
*
*
* @prop presets - Provide selectable preset configurations.
* @prop defaultValue - The date selected by default.
* @prop value - The selected date.
@@ -987,11 +1031,11 @@ const validatePresets = (
* This component is based on the [Calendar](https://docs.medusajs.com/ui/components/calendar)
* component and [Radix UI Popover](https://www.radix-ui.com/primitives/docs/components/popover).
*/
const DatePicker = ({
const DatePicker = ({
/**
* The date picker's mode.
*/
mode = "single",
mode = "single",
...props
}: DatePickerProps) => {
if (props.presets) {

View File

@@ -52,7 +52,11 @@ const DrawerOverlay = React.forwardRef<
return (
<DrawerPrimitives.Overlay
ref={ref}
className={clx("bg-ui-bg-overlay fixed inset-0", className)}
className={clx(
"bg-ui-bg-overlay fixed inset-0",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
)
@@ -69,8 +73,8 @@ const DrawerContent = React.forwardRef<
<DrawerPrimitives.Content
ref={ref}
className={clx(
"bg-ui-bg-base shadow-elevation-modal border-ui-border-base fixed inset-y-2 right-2 flex w-full max-w-[560px] flex-1 flex-col rounded-lg border focus:outline-none",
// "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:slide-out-to-right-1/2 data-[state=open]:slide-in-from-right-1/2 duration-200",
"bg-ui-bg-base shadow-elevation-modal border-ui-border-base fixed inset-y-2 flex flex-1 flex-col rounded-lg border focus-visible:outline-none max-sm:inset-x-2 sm:right-2 sm:max-w-[560px] md:w-full",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:slide-out-to-right-1/2 data-[state=open]:slide-in-from-right-1/2 duration-200",
className
)}
{...props}
@@ -87,14 +91,14 @@ const DrawerHeader = React.forwardRef<
return (
<div
ref={ref}
className="border-ui-border-base flex items-start justify-between gap-x-4 border-b px-8 py-6"
className="border-ui-border-base flex items-start justify-between gap-x-4 border-b px-6 py-4"
{...props}
>
<div className={clx("flex flex-col gap-y-1", className)}>{children}</div>
<div className="flex items-center gap-x-2">
<Kbd>esc</Kbd>
<DrawerPrimitives.Close asChild>
<IconButton variant="transparent">
<IconButton size="small" type="button" variant="transparent">
<XMark />
</IconButton>
</DrawerPrimitives.Close>
@@ -109,11 +113,7 @@ const DrawerBody = React.forwardRef<
React.ComponentPropsWithoutRef<"div">
>(({ className, ...props }, ref) => {
return (
<div
ref={ref}
className={clx("flex-1 px-8 pb-16 pt-6", className)}
{...props}
/>
<div ref={ref} className={clx("flex-1 px-6 py-4", className)} {...props} />
)
})
DrawerBody.displayName = "Drawer.Body"
@@ -125,7 +125,7 @@ const DrawerFooter = ({
return (
<div
className={clx(
"border-ui-border-base flex items-center justify-end space-x-2 overflow-y-scroll border-t px-8 pb-6 pt-4",
"border-ui-border-base flex items-center justify-end space-x-2 overflow-y-scroll border-t px-6 py-4",
className
)}
{...props}

View File

@@ -46,7 +46,7 @@ const SubMenuTrigger = React.forwardRef<
<Primitives.SubTrigger
ref={ref}
className={clx(
"focus:bg-ui-bg-base-pressed data-[state=open]:bg-ui-bg-base-pressed txt-compact-small flex cursor-default select-none items-center rounded-sm px-3 py-2 outline-none",
"focus-visible:bg-ui-bg-base-pressed data-[state=open]:bg-ui-bg-base-pressed txt-compact-small flex cursor-default select-none items-center rounded-sm px-2 py-1.5 outline-none",
className
)}
{...props}
@@ -69,7 +69,7 @@ const SubMenuContent = React.forwardRef<
ref={ref}
collisionPadding={collisionPadding}
className={clx(
"bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout max-h-[var(--radix-popper-available-height)] min-w-[8rem] overflow-hidden rounded-lg border p-1",
"bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout max-h-[var(--radix-popper-available-height)] min-w-[8rem] overflow-hidden rounded-lg p-1",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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",
className
)}
@@ -91,7 +91,7 @@ const Content = React.forwardRef<
className,
sideOffset = 8,
collisionPadding = 8,
align = "start",
align = "center",
...props
},
ref
@@ -124,7 +124,7 @@ const Item = React.forwardRef<
<Primitives.Item
ref={ref}
className={clx(
"bg-ui-bg-base focus:bg-ui-bg-base-pressed text-ui-fg-base data-[disabled]:text-ui-fg-disabled txt-compact-small relative flex cursor-pointer select-none items-center rounded-md px-3 py-2 outline-none transition-colors data-[disabled]:pointer-events-none",
"bg-ui-bg-base hover:bg-ui-bg-base-hover focus-visible:bg-ui-bg-base-pressed text-ui-fg-base data-[disabled]:text-ui-fg-disabled txt-compact-small relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 outline-none transition-colors data-[disabled]:pointer-events-none",
className
)}
{...props}
@@ -142,7 +142,7 @@ const CheckboxItem = React.forwardRef<
<Primitives.CheckboxItem
ref={ref}
className={clx(
"focus:bg-ui-bg-base-pressed text-ui-fg-base data-[disabled]:text-ui-fg-disabled relative flex cursor-pointer select-none items-center rounded-md py-2 pl-10 pr-3 text-sm outline-none transition-colors data-[disabled]:pointer-events-none",
"focus-visible:bg-ui-bg-base-pressed hover:bg-ui-bg-base-hover text-ui-fg-base data-[disabled]:text-ui-fg-disabled relative flex cursor-pointer select-none items-center rounded-md py-1.5 pl-9 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none",
className
)}
checked={checked}
@@ -168,7 +168,7 @@ const RadioItem = React.forwardRef<
<Primitives.RadioItem
ref={ref}
className={clx(
"focus:bg-ui-bg-base-pressed hover:bg-ui-base-hover bg-ui-bg-base txt-compact-small relative flex cursor-pointer select-none items-center rounded-md py-2 pl-10 pr-3 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[state=checked]:font-medium data-[disabled]:opacity-50",
"focus-visible:bg-ui-bg-base-pressed hover:bg-ui-base-hover bg-ui-bg-base txt-compact-small relative flex cursor-pointer select-none items-center rounded-md py-1.5 pl-9 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[state=checked]:font-medium data-[disabled]:opacity-50",
className
)}
{...props}
@@ -192,10 +192,7 @@ const Label = React.forwardRef<
>(({ className, ...props }, ref) => (
<Primitives.Label
ref={ref}
className={clx(
"text-ui-fg-subtle txt-compact-xsmall-plus px-2 py-1.5",
className
)}
className={clx("text-ui-fg-subtle txt-compact-xsmall-plus", className)}
{...props}
/>
))

View File

@@ -13,16 +13,13 @@ import { clx } from "@/utils/clx"
* @prop open - Whether the modal is opened.
* @prop onOpenChange - A function to handle when the modal is opened or closed.
*/
interface FocusModalRootProps
extends React.ComponentPropsWithoutRef<typeof FocusModalPrimitives.Root> {
}
interface FocusModalRootProps
extends React.ComponentPropsWithoutRef<typeof FocusModalPrimitives.Root> {}
/**
* This component is based on the [Radix UI Dialog](https://www.radix-ui.com/primitives/docs/components/dialog) primitives.
*/
const FocusModalRoot = (
props: FocusModalRootProps
) => {
const FocusModalRoot = (props: FocusModalRootProps) => {
return <FocusModalPrimitives.Root {...props} />
}
FocusModalRoot.displayName = "FocusModal"
@@ -35,6 +32,9 @@ const FocusModalTrigger = React.forwardRef<
})
FocusModalTrigger.displayName = "FocusModal.Trigger"
const FocusModalClose = FocusModalPrimitives.Close
FocusModalClose.displayName = "FocusModal.Close"
const FocusModalPortal = ({
className,
...props
@@ -54,7 +54,7 @@ const FocusModalOverlay = React.forwardRef<
ref={ref}
className={clx(
"bg-ui-bg-overlay fixed inset-0",
// "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
@@ -73,8 +73,8 @@ const FocusModalContent = React.forwardRef<
<FocusModalPrimitives.Content
ref={ref}
className={clx(
"bg-ui-bg-base shadow-elevation-modal fixed inset-2 flex flex-col overflow-hidden rounded-lg border focus:outline-none",
// "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 duration-200",
"bg-ui-bg-base shadow-elevation-modal fixed inset-2 flex flex-col overflow-hidden rounded-lg border focus-visible:outline-none",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-bottom-0 data-[state=closed]:slide-in-from-bottom-2 duration-200",
className
)}
{...props}
@@ -102,7 +102,7 @@ const FocusModalHeader = React.forwardRef<
>
<div className="flex items-center gap-x-2">
<FocusModalPrimitives.Close asChild>
<IconButton variant="transparent">
<IconButton size="small" type="button" variant="transparent">
<XMark />
</IconButton>
</FocusModalPrimitives.Close>
@@ -130,6 +130,7 @@ const FocusModal = Object.assign(FocusModalRoot, {
Content: FocusModalContent,
Header: FocusModalHeader,
Body: FocusModalBody,
Close: FocusModalClose,
})
export { FocusModal }

View File

@@ -1,11 +1,11 @@
import { ExclamationCircleSolid } from "@medusajs/icons"
import { VariantProps, cva } from "cva"
import * as React from "react"
import { ExclamationCircleSolid } from "@medusajs/icons"
import { clx } from "../../utils/clx"
const hintVariants = cva({
base: "txt-compact-xsmall inline-flex items-center gap-x-2",
base: "txt-small inline-flex items-center gap-x-2",
variants: {
variant: {
info: "text-ui-fg-subtle",
@@ -17,19 +17,23 @@ const hintVariants = cva({
},
})
interface HintProps extends VariantProps<typeof hintVariants>,
React.ComponentPropsWithoutRef<"span"> {}
interface HintProps
extends VariantProps<typeof hintVariants>,
React.ComponentPropsWithoutRef<"span"> {}
const Hint = React.forwardRef<HTMLSpanElement, HintProps>(
({
className,
/**
* The hint's style.
*/
variant = "info",
children,
...props
}: HintProps, ref) => {
(
{
className,
/**
* The hint's style.
*/
variant = "info",
children,
...props
}: HintProps,
ref
) => {
return (
<span
ref={ref}

View File

@@ -16,18 +16,19 @@ const iconButtonVariants = cva({
"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",
"focus-visible: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",
"focus-visible:shadow-buttons-neutral-focus focus-visible:bg-ui-bg-base",
"disabled:!bg-transparent disabled:!shadow-none"
),
},
size: {
small: "h-7 w-7 p-1",
base: "h-8 w-8 p-1.5",
large: "h-10 w-10 p-2.5",
xlarge: "h-12 w-12 p-3.5",

View File

@@ -8,7 +8,7 @@ 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",
"focus-visible: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"
)
@@ -20,8 +20,8 @@ const inputVariants = cva({
),
variants: {
size: {
base: "txt-compact-medium h-10 px-3 py-[9px]",
small: "txt-compact-small h-8 px-2 py-[5px]",
base: "txt-compact-small h-8 px-2 py-1.5",
small: "txt-compact-small h-7 px-2 py-1",
},
},
defaultVariants: {
@@ -29,87 +29,90 @@ const inputVariants = cva({
},
})
interface InputProps extends VariantProps<typeof inputVariants>,
Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {}
interface InputProps
extends VariantProps<typeof inputVariants>,
Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {}
/**
* This component is based on the `input` element and supports all of its props
*/
const Input = React.forwardRef<
HTMLInputElement,
InputProps
>(({
className,
type,
/**
* The input's size.
*/
size = "base",
...props
}: InputProps, ref) => {
const [typeState, setTypeState] = React.useState(type)
const Input = React.forwardRef<HTMLInputElement, InputProps>(
(
{
className,
type,
/**
* The input's size.
*/
size = "base",
...props
}: InputProps,
ref
) => {
const [typeState, setTypeState] = React.useState(type)
const isPassword = type === "password"
const isSearch = type === "search"
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
return (
<div className="relative">
<input
ref={ref}
type={isPassword ? typeState : type}
className={clx(
"text-ui-fg-muted absolute bottom-0 left-0 flex items-center justify-center",
inputVariants({ size: size }),
{
"h-10 w-11": size === "base",
"h-8 w-9": size === "small",
}
"pl-8": isSearch && size === "base",
"pr-8": isPassword && size === "base",
"pl-7": isSearch && size === "small",
"pr-7": isPassword && size === "small",
},
className
)}
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")
}}
{...props}
/>
{isSearch && (
<div
className={clx(
"text-ui-fg-muted pointer-events-none absolute bottom-0 left-0 flex items-center justify-center",
{
"h-8 w-8": size === "base",
"h-7 w-7": size === "small",
}
)}
role="img"
>
<span className="sr-only">
{typeState === "password" ? "Show password" : "Hide password"}
</span>
{typeState === "password" ? <Eye /> : <EyeSlash />}
</button>
</div>
)}
</div>
)
})
<MagnifyingGlassMini />
</div>
)}
{isPassword && (
<div
className={clx(
"absolute bottom-0 right-0 flex items-center justify-center border-l",
{
"h-8 w-8": size === "base",
"h-7 w-7": size === "small",
}
)}
>
<button
className="text-ui-fg-muted hover:text-ui-fg-base focus-visible:text-ui-fg-base focus-visible: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 }

View File

@@ -47,12 +47,12 @@ interface StatusIndicatorProps extends React.ComponentPropsWithoutRef<"span"> {
status: ProgressStatus
}
const ProgressIndicator = ({
const ProgressIndicator = ({
/**
* The current status.
*/
status,
...props
status,
...props
}: StatusIndicatorProps) => {
const Icon = React.useMemo(() => {
switch (status) {
@@ -81,21 +81,24 @@ ProgressIndicator.displayName = "ProgressAccordion.ProgressIndicator"
const Header = React.forwardRef<
React.ElementRef<typeof Primitves.Header>,
HeaderProps
>((
{
className,
/**
* The current status.
*/
status = "not-started",
children,
...props
}: HeaderProps, ref) => {
>(
(
{
className,
/**
* The current status.
*/
status = "not-started",
children,
...props
}: HeaderProps,
ref
) => {
return (
<Primitves.Header
ref={ref}
className={clx(
"h3-core text-ui-fg-base group flex w-full flex-1 items-center gap-4 px-8",
"h3-core text-ui-fg-base group flex w-full flex-1 items-center gap-4 px-6",
className
)}
{...props}
@@ -109,7 +112,8 @@ const Header = React.forwardRef<
</Primitves.Trigger>
</Primitves.Header>
)
})
}
)
Header.displayName = "ProgressAccordion.Header"
const Content = React.forwardRef<
@@ -121,7 +125,7 @@ const Content = React.forwardRef<
ref={ref}
className={clx(
"overflow-hidden",
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down pl-24 pr-8",
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down pl-[88px] pr-6",
className
)}
{...props}

View File

@@ -13,7 +13,7 @@ import { clx } from "@/utils/clx"
/**
* This component is based on the [Radix UI Tabs](https://radix-ui.com/primitives/docs/components/tabs) primitves.
*
*
* @excludeExternal
*/
const ProgressTabsRoot = (props: ProgressTabsPrimitives.TabsProps) => {
@@ -29,11 +29,7 @@ interface IndicatorProps
status?: ProgressStatus
}
const ProgressIndicator = ({
status,
className,
...props
}: IndicatorProps) => {
const ProgressIndicator = ({ status, className, ...props }: IndicatorProps) => {
const Icon = React.useMemo(() => {
switch (status) {
case "not-started":
@@ -72,24 +68,34 @@ interface ProgressTabsTriggerProps
const ProgressTabsTrigger = React.forwardRef<
React.ElementRef<typeof ProgressTabsPrimitives.Trigger>,
ProgressTabsTriggerProps
>(({ className, children, status = "not-started", ...props }: ProgressTabsTriggerProps, ref) => (
<ProgressTabsPrimitives.Trigger
ref={ref}
className={clx(
"txt-compact-small-plus transition-fg text-ui-fg-muted bg-ui-bg-subtle border-r-ui-border-base inline-flex h-14 w-full max-w-[200px] flex-1 items-center gap-x-2 border-r px-4 text-left outline-none",
"group/trigger overflow-hidden text-ellipsis whitespace-nowrap",
"disabled:bg-ui-bg-disabled disabled:text-ui-fg-muted",
"hover:bg-ui-bg-subtle-hover",
"focus:bg-ui-bg-base focus:z-[1]",
"data-[state=active]:text-ui-fg-base data-[state=active]:bg-ui-bg-base",
className
)}
{...props}
>
<ProgressIndicator status={status} />
{children}
</ProgressTabsPrimitives.Trigger>
))
>(
(
{
className,
children,
status = "not-started",
...props
}: ProgressTabsTriggerProps,
ref
) => (
<ProgressTabsPrimitives.Trigger
ref={ref}
className={clx(
"txt-compact-small-plus transition-fg text-ui-fg-muted bg-ui-bg-subtle border-r-ui-border-base inline-flex h-14 w-full max-w-[200px] flex-1 items-center gap-x-2 border-r px-4 text-left outline-none",
"group/trigger overflow-hidden text-ellipsis whitespace-nowrap",
"disabled:bg-ui-bg-disabled disabled:text-ui-fg-muted",
"hover:bg-ui-bg-subtle-hover",
"focus-visible:bg-ui-bg-base focus:z-[1]",
"data-[state=active]:text-ui-fg-base data-[state=active]:bg-ui-bg-base",
className
)}
{...props}
>
<ProgressIndicator status={status} />
{children}
</ProgressTabsPrimitives.Trigger>
)
)
ProgressTabsTrigger.displayName = "ProgressTabs.Trigger"
const ProgressTabsList = React.forwardRef<

View File

@@ -7,10 +7,50 @@ import { Button } from "@/components/button"
import { Heading } from "@/components/heading"
import { clx } from "@/utils/clx"
type PromptVariant = "danger" | "confirmation"
const PromptContext = React.createContext<{ variant: PromptVariant }>({
variant: "danger",
})
const usePromptContext = () => {
const context = React.useContext(PromptContext)
if (!context) {
throw new Error("usePromptContext must be used within a PromptProvider")
}
return context
}
type PromptProviderProps = React.PropsWithChildren<{
variant: PromptVariant
}>
const PromptProvider = ({ variant, children }: PromptProviderProps) => {
return (
<PromptContext.Provider value={{ variant }}>
{children}
</PromptContext.Provider>
)
}
/**
* This component is based on the [Radix UI Alert Dialog](https://www.radix-ui.com/primitives/docs/components/alert-dialog) primitives.
*/
const Root = Primitives.AlertDialog
const Root = ({
/**
* The variant of the prompt.
*/
variant = "danger",
...props
}: React.ComponentPropsWithoutRef<typeof Primitives.Root> & {
variant?: PromptVariant
}) => {
return (
<PromptProvider variant={variant}>
<Primitives.Root {...props} />
</PromptProvider>
)
}
Root.displayName = "Prompt"
const Trigger = Primitives.Trigger
@@ -30,7 +70,7 @@ const Overlay = React.forwardRef<
ref={ref}
className={clx(
"bg-ui-bg-overlay fixed inset-0",
// "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", // Re-enable when Admin UI has been cleaned up
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
@@ -63,8 +103,8 @@ const Content = React.forwardRef<
<Primitives.Content
ref={ref}
className={clx(
"bg-ui-bg-base shadow-elevation-flyout fixed left-[50%] top-[50%] flex w-full max-w-[400px] translate-x-[-50%] translate-y-[-50%] flex-col rounded-lg border focus:outline-none",
// "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] duration-200", // Re-enable when Admin UI has been cleaned up
"bg-ui-bg-base shadow-elevation-flyout fixed left-[50%] top-[50%] flex w-full max-w-[400px] translate-x-[-50%] translate-y-[-50%] flex-col rounded-lg border focus-visible:outline-none",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] duration-200",
className
)}
{...props}
@@ -92,9 +132,15 @@ const Action = React.forwardRef<
React.ElementRef<typeof Primitives.Action>,
Omit<React.ComponentPropsWithoutRef<typeof Primitives.Action>, "asChild">
>(({ className, children, type, ...props }, ref) => {
const { variant } = usePromptContext()
return (
<Primitives.Action ref={ref} className={className} {...props} asChild>
<Button type={type} variant="danger">
<Button
size="small"
type={type}
variant={variant === "danger" ? "danger" : "primary"}
>
{children}
</Button>
</Primitives.Action>
@@ -108,7 +154,9 @@ const Cancel = React.forwardRef<
>(({ className, children, ...props }, ref) => {
return (
<Primitives.Cancel ref={ref} className={clx(className)} {...props} asChild>
<Button variant="secondary">{children}</Button>
<Button size="small" variant="secondary">
{children}
</Button>
</Primitives.Cancel>
)
})

View File

@@ -62,7 +62,7 @@ const Item = React.forwardRef<
"shadow-borders-base bg-ui-bg-base transition-fg flex h-[14px] w-[14px] items-center justify-center rounded-full",
"group-hover:bg-ui-bg-base-hover",
"group-data-[state=checked]:bg-ui-bg-interactive group-data-[state=checked]:shadow-borders-interactive-with-shadow",
"group-focus:!shadow-borders-interactive-with-focus",
"group-focus-visible:!shadow-borders-interactive-with-focus",
"group-disabled:!bg-ui-bg-disabled group-disabled:!shadow-borders-base"
)}
>
@@ -95,7 +95,7 @@ const ChoiceBox = React.forwardRef<
<Primitives.Item
ref={ref}
className={clx(
"shadow-borders-base bg-ui-bg-base focus:shadow-borders-interactive-with-focus transition-fg disabled:bg-ui-bg-disabled group flex items-start gap-x-2 rounded-lg p-3 disabled:cursor-not-allowed",
"shadow-borders-base bg-ui-bg-base focus-visible:shadow-borders-interactive-with-focus transition-fg disabled:bg-ui-bg-disabled group flex items-start gap-x-2 rounded-lg p-3 disabled:cursor-not-allowed",
className
)}
{...props}

View File

@@ -1,6 +1,6 @@
"use client"
import { ChevronUpDown, EllipseMiniSolid } from "@medusajs/icons"
import { EllipseMiniSolid, TrianglesMini } from "@medusajs/icons"
import * as SelectPrimitive from "@radix-ui/react-select"
import { cva } from "cva"
import * as React from "react"
@@ -33,11 +33,11 @@ const useSelectContext = () => {
* It also accepts all props of the HTML `select` component.
*/
const Root = ({
children,
children,
/**
* The select's size.
*/
size = "base",
size = "base",
...props
}: SelectProps) => {
return (
@@ -63,10 +63,10 @@ Value.displayName = "Select.Value"
const triggerVariants = cva({
base: 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",
"bg-ui-bg-field 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",
"focus-visible: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",
@@ -74,8 +74,8 @@ const triggerVariants = cva({
),
variants: {
size: {
base: "h-10 px-3 py-[9px]",
small: "h-8 px-2 py-[5px]",
base: "h-8 px-2 py-1.5 txt-compact-small",
small: "h-7 px-2 py-1 txt-compact-small",
},
},
})
@@ -97,7 +97,7 @@ const Trigger = React.forwardRef<
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronUpDown className="text-ui-fg-muted group-disabled/trigger:text-ui-fg-disabled" />
<TrianglesMini className="text-ui-fg-muted group-disabled/trigger:text-ui-fg-disabled" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
)
@@ -186,7 +186,7 @@ const Item = React.forwardRef<
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",
"hover:bg-ui-bg-base-hover focus-visible:bg-ui-bg-base-hover",
{
"txt-compact-medium data-[state=checked]:txt-compact-medium-plus":
size === "base",

View File

@@ -1,14 +1,6 @@
import * as React from "react"
import { clx } from "@/utils/clx"
import {
EllipseBlueSolid,
EllipseGreenSolid,
EllipseGreySolid,
EllipseOrangeSolid,
EllipsePurpleSolid,
EllipseRedSolid,
} from "@medusajs/icons"
interface StatusBadgeProps
extends Omit<React.ComponentPropsWithoutRef<"span">, "color"> {
@@ -19,34 +11,47 @@ interface StatusBadgeProps
* This component is based on the span element and supports all of its props
*/
const StatusBadge = React.forwardRef<HTMLSpanElement, StatusBadgeProps>(
({
children,
className,
/**
* The status's color.
*/
color = "grey",
...props
}: StatusBadgeProps, ref) => {
const StatusIndicator = {
green: EllipseGreenSolid,
red: EllipseRedSolid,
orange: EllipseOrangeSolid,
blue: EllipseBlueSolid,
purple: EllipsePurpleSolid,
grey: EllipseGreySolid,
}[color]
(
{
children,
className,
/**
* The status's color.
*/
color = "grey",
...props
}: StatusBadgeProps,
ref
) => {
return (
<span
ref={ref}
className={clx(
"bg-ui-bg-base border-ui-border-base txt-compact-small text-ui-fg-base inline-flex items-center justify-center rounded-full border py-1 pl-1 pr-3",
"bg-ui-bg-base border-ui-border-base txt-compact-small text-ui-fg-base inline-flex items-center justify-center rounded-full border py-[3px] pl-1 pr-2.5",
className
)}
{...props}
>
<StatusIndicator className="mr-0.5" />
<span
role="presentation"
className="mr-0.5 flex h-5 w-5 items-center justify-center"
>
<span
role="presentation"
className="bg-ui-bg-base shadow-borders-base flex h-2.5 w-2.5 items-center justify-center rounded-full"
>
<span
className={clx("h-1.5 w-1.5 rounded-full", {
"bg-ui-tag-neutral-icon": color === "grey",
"bg-ui-tag-green-icon": color === "green",
"bg-ui-tag-red-icon": color === "red",
"bg-ui-tag-orange-icon": color === "orange",
"bg-ui-tag-blue-icon": color === "blue",
"bg-ui-tag-purple-icon": color === "purple",
})}
/>
</span>
</span>
{children}
</span>
)

View File

@@ -7,7 +7,7 @@ import * as React from "react"
import { clx } from "@/utils/clx"
const switchVariants = cva({
base: "bg-ui-bg-switch-off hover:bg-ui-bg-switch-off-hover data-[state=unchecked]:hover:after:bg-switch-off-hover-gradient before:shadow-details-switch-background focus:shadow-details-switch-background-focus data-[state=checked]:bg-ui-bg-interactive disabled:!bg-ui-bg-disabled group relative inline-flex items-center rounded-full outline-none transition-all before:absolute before:inset-0 before:rounded-full before:content-[''] after:absolute after:inset-0 after:rounded-full after:content-[''] disabled:cursor-not-allowed",
base: "bg-ui-bg-switch-off hover:bg-ui-bg-switch-off-hover data-[state=unchecked]:hover:after:bg-switch-off-hover-gradient before:shadow-details-switch-background focus-visible:shadow-details-switch-background-focus data-[state=checked]:bg-ui-bg-interactive disabled:!bg-ui-bg-disabled group relative inline-flex items-center rounded-full outline-none transition-all before:absolute before:inset-0 before:rounded-full before:content-[''] after:absolute after:inset-0 after:rounded-full after:content-[''] disabled:cursor-not-allowed",
variants: {
size: {
small: "h-[16px] w-[28px]",
@@ -46,22 +46,27 @@ interface SwitchProps
const Switch = React.forwardRef<
React.ElementRef<typeof Primitives.Root>,
SwitchProps
>(({
className,
/**
* The switch's size.
*/
size = "base",
...props
}: SwitchProps, ref) => (
<Primitives.Root
className={clx(switchVariants({ size }), className)}
{...props}
ref={ref}
>
<Primitives.Thumb className={clx(thumbVariants({ size }))} />
</Primitives.Root>
))
>(
(
{
className,
/**
* The switch's size.
*/
size = "base",
...props
}: SwitchProps,
ref
) => (
<Primitives.Root
className={clx(switchVariants({ size }), className)}
{...props}
ref={ref}
>
<Primitives.Thumb className={clx(thumbVariants({ size }))} />
</Primitives.Root>
)
)
Switch.displayName = "Switch"
export { Switch }

View File

@@ -6,14 +6,14 @@ import { clx } from "@/utils/clx"
/**
* This component is based on the table element and its various children:
*
*
* - `Table`: `table`
* - `Table.Header`: `thead`
* - `Table.Row`: `tr`
* - `Table.HeaderCell`: `th`
* - `Table.Body`: `tbody`
* - `Table.Cell`: `td`
*
*
* Each component supports the props or attributes of its equivalent HTML element.
*/
const Root = React.forwardRef<
@@ -36,8 +36,8 @@ const Row = React.forwardRef<
ref={ref}
className={clx(
"bg-ui-bg-base hover:bg-ui-bg-base-hover border-ui-border-base transition-fg border-b",
"[&_td:last-child]:pr-8 [&_th:last-child]:pr-8",
"[&_td:first-child]:pl-8 [&_th:first-child]:pl-8",
"[&_td:last-child]:pr-6 [&_th:last-child]:pr-6",
"[&_td:first-child]:pl-6 [&_th:first-child]:pl-6",
className
)}
{...props}
@@ -72,7 +72,7 @@ const HeaderCell = React.forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<th ref={ref} className={clx("h-12 pr-3 text-left", className)} {...props} />
<th ref={ref} className={clx("h-10 pr-3 text-left", className)} {...props} />
))
HeaderCell.displayName = "Table.HeaderCell"
@@ -95,6 +95,13 @@ interface TablePaginationProps extends React.HTMLAttributes<HTMLDivElement> {
pageCount: number
canPreviousPage: boolean
canNextPage: boolean
translations?: {
of?: string
results?: string
pages?: string
prev?: string
next?: string
}
previousPage: () => void
nextPage: () => void
}
@@ -140,6 +147,17 @@ const Pagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(
* This function should handle retrieving data for the previous page.
*/
previousPage,
/**
* An optional object of words to use in the pagination component.
* Use this to override the default words, or translate them into another language.
*/
translations = {
of: "of",
results: "results",
pages: "pages",
prev: "Prev",
next: "Next",
},
...props
}: TablePaginationProps,
ref
@@ -155,7 +173,7 @@ const Pagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(
<div
ref={ref}
className={clx(
"text-ui-fg-subtle txt-compact-small-plus flex w-full items-center justify-between px-5 pb-6 pt-4",
"text-ui-fg-subtle txt-compact-small-plus flex w-full items-center justify-between px-3 py-4",
className
)}
{...props}
@@ -163,27 +181,30 @@ const Pagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(
<div className="inline-flex items-center gap-x-1 px-3 py-[5px]">
<p>{from}</p>
<Minus className="text-ui-fg-muted" />
<p>{`${to} of ${count} results`}</p>
<p>{`${to} ${translations.of} ${count} ${translations.results}`}</p>
</div>
<div className="flex items-center gap-x-2">
<div className="inline-flex items-center gap-x-1 px-3 py-[5px]">
<p>
{pageIndex + 1} of {Math.max(pageCount, 1)}
{pageIndex + 1} {translations.of} {Math.max(pageCount, 1)}{" "}
{translations.pages}
</p>
</div>
<Button
type="button"
variant={"transparent"}
onClick={previousPage}
disabled={!canPreviousPage}
>
Prev
{translations.prev}
</Button>
<Button
type="button"
variant={"transparent"}
onClick={nextPage}
disabled={!canNextPage}
>
Next
{translations.next}
</Button>
</div>
</div>

View File

@@ -22,9 +22,9 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitives.Trigger
ref={ref}
className={clx(
"txt-compact-small-plus transition-fg text-ui-fg-subtle inline-flex items-center justify-center rounded-full border border-transparent bg-transparent px-3 py-1.5 outline-none",
"txt-compact-small-plus transition-fg text-ui-fg-subtle inline-flex items-center justify-center rounded-full border border-transparent bg-transparent px-2.5 py-1 outline-none",
"hover:text-ui-fg-base",
"focus:border-ui-border-interactive focus:!shadow-borders-focus focus:bg-ui-bg-base",
"focus-visible:border-ui-border-interactive focus-visible:!shadow-borders-focus focus-visible:bg-ui-bg-base",
"data-[state=active]:text-ui-fg-base data-[state=active]:bg-ui-bg-base data-[state=active]:shadow-elevation-card-rest",
className
)}

View File

@@ -15,7 +15,7 @@ const Textarea = React.forwardRef<
ref={ref}
className={clx(
inputBaseStyles,
"txt-medium min-h-[70px] w-full px-3 py-[7px]",
"txt-small min-h-[60px] w-full px-2 py-1.5",
className
)}
{...props}

View File

@@ -36,7 +36,7 @@ const TimeSegment = ({ segment, state }: TimeSegmentProps) => {
{...segmentProps}
ref={ref}
className={clx(
"txt-compact-medium w-full rounded-md px-2 py-[5px] text-left uppercase tabular-nums",
"txt-compact-small w-full rounded-md px-2 py-1 text-left uppercase tabular-nums",
inputBaseStyles,
"group-aria-[invalid=true]/time-input:!shadow-borders-error group-invalid/time-input:!shadow-borders-error",
{
@@ -52,7 +52,7 @@ const TimeSegment = ({ segment, state }: TimeSegmentProps) => {
<span
aria-hidden="true"
className={clx(
"txt-compact-medium text-ui-fg-muted pointer-events-none block w-full text-left",
"txt-compact-small text-ui-fg-muted pointer-events-none block w-full text-left",
{
hidden: !segment.isPlaceholder,
"h-0": !segment.isPlaceholder,
@@ -75,14 +75,17 @@ type TimeInputProps = Omit<
* This component is based on the `div` element and supports all of its props.
*/
const TimeInput = React.forwardRef<HTMLDivElement, TimeInputProps>(
({
/**
* The time's format. If no value is specified, the format is
* set based on the user's locale.
*/
hourCycle,
...props
}: TimeInputProps, ref) => {
(
{
/**
* The time's format. If no value is specified, the format is
* set based on the user's locale.
*/
hourCycle,
...props
}: TimeInputProps,
ref
) => {
const innerRef = React.useRef<HTMLDivElement>(null)
React.useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(

View File

@@ -19,7 +19,7 @@ interface TooltipProps
/**
* This component is based on the [Radix UI Tooltip](https://www.radix-ui.com/primitives/docs/components/tooltip) primitive.
*
*
* @excludeExternal
*/
const Tooltip = ({
@@ -56,7 +56,7 @@ const Tooltip = ({
sideOffset={sideOffset}
align="center"
className={clx(
"txt-compact-xsmall-plus text-ui-fg-subtle bg-ui-bg-base shadow-elevation-tooltip rounded-lg px-3 py-2",
"txt-compact-xsmall text-ui-fg-subtle bg-ui-bg-base shadow-elevation-tooltip rounded-lg px-2.5 py-1",
"animate-in fade-in-0 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",
className
)}