UNPKG

@plone/components

Version:

ReactJS components for Plone

1,751 lines (1,727 loc) 63.8 kB
"use client" import { AlignWidget, CustomRadio, Description, Field, FieldError, FieldGroup, FieldWrapper, Input, Label, Radio, RadioGroup, SizeWidget, WidthWidget, composeTailwindRenderProps, fieldBorderStyles, fieldGroupStyles, focusRing, getMenuTriggerChildren, inputStyles } from "../chunk-YWREOUAG.js"; import { CalendarIcon, CheckboxIcon, ChevrondownIcon, ChevronleftIcon, ChevronrightIcon, CloseIcon, DashIcon } from "../chunk-V3F5PCGN.js"; // src/components/Button/Button.quanta.tsx import "react"; import { composeRenderProps, Button as RACButton } from "react-aria-components"; import { tv } from "tailwind-variants"; import { jsx } from "react/jsx-runtime"; var button = tv({ extend: focusRing, base: ` cursor-default rounded-md px-3 py-1.5 text-center text-base font-medium transition hover:shadow-sm focus:shadow-sm active:shadow-md has-[svg]:rounded-full has-[svg]:p-1.5 has-[svg]:text-xs `, variants: { variant: { neutral: ` bg-quanta-air text-quanta-iron hover:bg-quanta-snow focus:bg-quanta-snow active:bg-quanta-silver has-[svg]:text-quanta-iron pressed:bg-quanta-silver `, primary: ` focus:bg-quanta-artic focus:text-quanta-royal bg-quanta-air text-quanta-sapphire hover:bg-quanta-arctic hover:text-quanta-royal active:bg-quanta-sky active:text-quanta-royal pressed:bg-quanta-cobalt `, destructive: ` bg-quanta-air text-quanta-candy hover:bg-quanta-ballet hover:text-quanta-wine focus:bg-quanta-ballet focus:text-quanta-wine active:bg-quanta-flamingo active:text-quanta-wine pressed:bg-quanta-rose `, icon: ` focus:bg-quanta-artic flex items-center justify-center border-0 bg-quanta-air p-1 text-quanta-iron hover:bg-quanta-snow active:bg-quanta-silver has-[svg]:text-quanta-iron pressed:bg-quanta-cobalt pressed:[&_svg]:text-white ` }, accent: { true: "" }, size: { S: ` text-xs has-[svg]:p-1.5 [&_svg]:size-5 `, L: ` px-4.5 py-3 text-xl/6 has-[svg]:p-3 has-[svg]:text-xs ` }, isDisabled: { true: ` cursor-not-allowed bg-quanta-air text-quanta-smoke hover:bg-quanta-air hover:text-quanta-silver has-[svg]:text-quanta-smoke has-[svg]:hover:text-quanta-silver ` } }, compoundVariants: [ { variant: "neutral", accent: true, class: ` bg-quanta-snow text-quanta-iron hover:bg-quanta-smoke focus:bg-quanta-smoke active:bg-quanta-silver pressed:bg-quanta-smoke ` }, { variant: "primary", accent: true, class: ` bg-quanta-sapphire text-quanta-air hover:bg-quanta-royal hover:text-quanta-air focus:bg-quanta-royal focus:text-quanta-air active:bg-quanta-cobalt active:text-quanta-air pressed:bg-quanta-cobalt ` }, { variant: "icon", accent: true, class: ` focus:bg-quanta-artic flex items-center justify-center border-0 bg-quanta-air p-1 text-quanta-iron hover:bg-quanta-snow active:bg-quanta-silver has-[svg]:text-quanta-iron pressed:bg-quanta-cobalt pressed:[&_svg]:text-white ` }, { variant: "destructive", accent: true, class: ` bg-quanta-candy text-quanta-air hover:bg-quanta-wine hover:text-quanta-air focus:bg-quanta-wine focus:text-quanta-air active:bg-quanta-rose active:text-quanta-air pressed:bg-quanta-rose ` }, { isDisabled: true, accent: true, class: ` bg-quanta-snow text-quanta-silver hover:bg-quanta-smoke ` } ], defaultVariants: { variant: "neutral" } }); function Button(props) { return /* @__PURE__ */ jsx( RACButton, { ...props, className: composeRenderProps( props.className, (className, renderProps) => button({ ...renderProps, variant: props.variant, size: props.size, accent: props.accent, className }) ) } ); } // src/components/Breadcrumbs/Breadcrumbs.quanta.tsx import "react"; import { Breadcrumbs as RACBreadcrumbs, Breadcrumb as RACBreadcrumb } from "react-aria-components"; import { twMerge } from "tailwind-merge"; // src/components/Link/Link.quanta.tsx import "react"; import { Link as AriaLink, composeRenderProps as composeRenderProps2 } from "react-aria-components"; import { tv as tv2 } from "tailwind-variants"; import { jsx as jsx2 } from "react/jsx-runtime"; var styles = tv2({ extend: focusRing, base: ` rounded-xs underline transition disabled:cursor-default disabled:no-underline forced-colors:disabled:text-[GrayText] `, variants: { variant: { primary: ` text-quanta-sapphire underline decoration-quanta-sapphire/40 hover:text-quanta-royal hover:decoration-quanta-royal focus:text-quanta-royal focus:decoration-quanta-royal active:text-quanta-cobalt active:decoration-quanta-cobalt `, secondary: ` text-gray-700 underline decoration-gray-700/50 hover:decoration-gray-700 ` } }, defaultVariants: { variant: "primary" } }); function Link(props) { return /* @__PURE__ */ jsx2( AriaLink, { ...props, className: composeRenderProps2( props.className, (className, renderProps) => styles({ ...renderProps, className, variant: props.variant }) ) } ); } // src/components/Breadcrumbs/Breadcrumbs.quanta.tsx import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime"; function Breadcrumb(props) { return /* @__PURE__ */ jsx3( RACBreadcrumb, { ...props, className: composeTailwindRenderProps( props.className, ` flex items-center gap-1 [&_a>svg]:mx-1 [&_a>svg]:inline [&_a>svg]:align-text-top ` ), children: ({ isCurrent }) => /* @__PURE__ */ jsxs(Fragment, { children: [ props.value?.icon && props.value?.icon, /* @__PURE__ */ jsx3(Link, { variant: "secondary", ...props }), !isCurrent && (props.separator ?? /* @__PURE__ */ jsx3(ChevronrightIcon, { className: "h-3 w-3 text-gray-600" })) ] }) } ); } function Breadcrumbs(props) { const { root, items, homeIcon } = props; let itemsWithRoot; if (root && items) { const icon = null; const rootItem = { "@id": root["@id"] || "/", title: "Home", icon }; itemsWithRoot = [rootItem, ...items]; } return /* @__PURE__ */ jsx3( RACBreadcrumbs, { ...props, items: itemsWithRoot || items, className: twMerge("flex gap-1", props.className) } ); } // src/components/Accordion/Accordion.quanta.tsx import "react"; import { DisclosureGroup, Button as Button2, Disclosure, DisclosurePanel, Heading } from "react-aria-components"; import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime"; var Accordion = ({ children, ref, className, ...props }) => { return /* @__PURE__ */ jsx4( DisclosureGroup, { ref, "data-slot": "disclosure-group", ...props, className: composeTailwindRenderProps( className, ` peer cursor-pointer disabled:cursor-not-allowed disabled:opacity-75 ` ), children: (values) => /* @__PURE__ */ jsx4("div", { "data-slot": "disclosure-content", children: typeof children === "function" ? children(values) : children }) } ); }; var AccordionItem = ({ className, ref, ...props }) => { return /* @__PURE__ */ jsx4( Disclosure, { ref, "data-slot": "disclosure", ...props, className: composeTailwindRenderProps( className, ` peer group/disclosure w-full min-w-60 border-b border-border disabled:opacity-60 ` ), children: props.children } ); }; var AccordionItemTrigger = ({ className, ref, ...props }) => { return /* @__PURE__ */ jsx4(Heading, { children: /* @__PURE__ */ jsx4( Button2, { ref, slot: "trigger", className: composeTailwindRenderProps( className, ` group/trigger flex w-full items-center justify-between gap-x-2 py-3 text-left font-medium open:text-fg focus:text-fg focus:outline-hidden **:data-[slot=icon]:text-muted-fg **:data-[slot=icon]:-mx-0.5 **:data-[slot=icon]:shrink-0 disabled:cursor-default disabled:opacity-50 **:data-[slot=disclosure-chevron]:size-5 sm:text-sm forced-colors:disabled:text-[GrayText] **:[span]:flex **:[span]:items-center **:[span]:gap-x-1 **:[span]:*:data-[slot=icon]:mr-1 [&[aria-expanded=true]_[data-slot=disclosure-chevron]]:-rotate-90 ` ), ...props, children: (values) => /* @__PURE__ */ jsxs2(Fragment2, { children: [ typeof props.children === "function" ? props.children(values) : props.children, /* @__PURE__ */ jsx4( ChevronleftIcon, { "data-slot": "disclosure-chevron", className: "internal-chevron ml-auto size-4 shrink-0 transition duration-300" } ) ] }) } ) }); }; var AccordionPanel = ({ className, ref, ...props }) => { return /* @__PURE__ */ jsx4( DisclosurePanel, { ref, "data-slot": "disclosure-panel", className: composeTailwindRenderProps( className, ` text-muted-fg overflow-hidden text-sm transition-all **:data-[slot=disclosure-group]:border-t **:data-[slot=disclosure-group]:**:[.internal-chevron]:hidden has-data-[slot=disclosure-group]:**:[button]:px-4 ` ), ...props, children: /* @__PURE__ */ jsx4( "div", { "data-slot": "disclosure-panel-content", className: ` pt-0 not-has-data-[slot=disclosure-group]:group-data-expanded/disclosure:pb-3 [&:has([data-slot=disclosure-group])_&]:px-11 `, children: props.children } ) } ); }; // src/components/Calendar/Calendar.quanta.tsx import "react"; import { Calendar as AriaCalendar, CalendarGridHeader as AriaCalendarGridHeader, CalendarCell, CalendarGrid, CalendarGridBody, CalendarHeaderCell, Heading as Heading2, Text, useLocale } from "react-aria-components"; import { tv as tv3 } from "tailwind-variants"; import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime"; var cellStyles = tv3({ extend: focusRing, base: ` m-px flex h-9 w-9 cursor-default items-center justify-center rounded-full text-sm forced-color-adjust-none `, variants: { isSelected: { false: ` text-zinc-900 hover:bg-gray-100 dark:text-zinc-200 dark:hover:bg-zinc-700 pressed:bg-gray-200 dark:pressed:bg-zinc-600 `, true: ` bg-blue-600 text-white invalid:bg-red-600 forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] forced-colors:invalid:bg-[Mark] ` }, isDisabled: { true: ` text-gray-300 dark:text-zinc-600 forced-colors:text-[GrayText] ` } } }); function Calendar({ errorMessage, ...props }) { return /* @__PURE__ */ jsxs3(AriaCalendar, { ...props, children: [ /* @__PURE__ */ jsx5(CalendarHeader, {}), /* @__PURE__ */ jsxs3(CalendarGrid, { children: [ /* @__PURE__ */ jsx5(CalendarGridHeader, {}), /* @__PURE__ */ jsx5(CalendarGridBody, { children: (date) => /* @__PURE__ */ jsx5(CalendarCell, { date, className: cellStyles }) }) ] }), errorMessage && /* @__PURE__ */ jsx5(Text, { slot: "errorMessage", className: "text-sm text-red-600", children: errorMessage }) ] }); } function CalendarHeader() { const { direction } = useLocale(); return /* @__PURE__ */ jsxs3("header", { className: "flex w-full items-center gap-1 px-1 pb-4", children: [ /* @__PURE__ */ jsx5(Button, { slot: "previous", children: direction === "rtl" ? /* @__PURE__ */ jsx5(ChevronrightIcon, { "aria-hidden": true }) : /* @__PURE__ */ jsx5(ChevronleftIcon, { "aria-hidden": true }) }), /* @__PURE__ */ jsx5( Heading2, { className: ` mx-2 flex-1 text-center text-xl font-semibold text-zinc-900 dark:text-zinc-200 ` } ), /* @__PURE__ */ jsx5(Button, { slot: "next", children: direction === "rtl" ? /* @__PURE__ */ jsx5(ChevronleftIcon, { "aria-hidden": true }) : /* @__PURE__ */ jsx5(ChevronrightIcon, { "aria-hidden": true }) }) ] }); } function CalendarGridHeader() { return /* @__PURE__ */ jsx5(AriaCalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx5(CalendarHeaderCell, { className: "text-xs font-semibold text-gray-500", children: day }) }); } // src/components/Checkbox/Checkbox.quanta.tsx import "react"; import { Checkbox as AriaCheckbox, CheckboxGroup as AriaCheckboxGroup, composeRenderProps as composeRenderProps3 } from "react-aria-components"; import { tv as tv4 } from "tailwind-variants"; import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime"; function CheckboxGroup(props) { return /* @__PURE__ */ jsxs4( AriaCheckboxGroup, { ...props, className: composeTailwindRenderProps( props.className, "flex flex-col gap-2" ), children: [ /* @__PURE__ */ jsx6(Label, { children: props.label }), props.children, props.description && /* @__PURE__ */ jsx6(Description, { children: props.description }), /* @__PURE__ */ jsx6(FieldError, { children: props.errorMessage }) ] } ); } var checkboxStyles = tv4({ base: "group flex items-center gap-2 text-sm transition", variants: { isDisabled: { false: "text-quanta-cobalt", true: ` text-quanta-iron forced-colors:text-[GrayText] ` } } }); var boxStyles = tv4({ extend: focusRing, base: "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded border-2 transition", variants: { isSelected: { false: ` border-quanta-pigeon bg-quanta-snow group-pressed:border-quanta-silver `, true: ` border-quanta-sapphire bg-quanta-sapphire group-pressed:border-quanta-sapphire forced-colors:![--color:Highlight] ` }, isInvalid: { true: ` group-pressed:border-quanta-ruby border-quanta-ruby forced-colors:![--color:Mark] ` }, isDisabled: { true: ` border-quanta-silver bg-quanta-smoke forced-colors:![--color:GrayText] ` } } }); var iconStyles = "w-4 h-4 text-white group-disabled:text-quanta-iron forced-colors:text-[HighlightText]"; function Checkbox(props) { return /* @__PURE__ */ jsx6( AriaCheckbox, { ...props, className: composeRenderProps3( props.className, (className, renderProps) => checkboxStyles({ ...renderProps, className }) ), children: ({ isSelected, isIndeterminate, ...renderProps }) => /* @__PURE__ */ jsxs4(Fragment3, { children: [ /* @__PURE__ */ jsx6( "div", { className: boxStyles({ isSelected: isSelected || isIndeterminate, ...renderProps }), children: isIndeterminate ? /* @__PURE__ */ jsx6(DashIcon, { "aria-hidden": true, className: iconStyles }) : isSelected ? /* @__PURE__ */ jsx6(CheckboxIcon, { "aria-hidden": true, className: iconStyles }) : null } ), props.children ] }) } ); } // src/components/Container/Container.quanta.tsx import "react"; import { tv as tv5 } from "tailwind-variants"; import { twMerge as twMerge2 } from "tailwind-merge"; import { jsx as jsx7 } from "react/jsx-runtime"; var Container = (props) => { const { as: Component = "div", children, width, ...rest } = props; const container = tv5({ base: "@container mx-auto", variants: { width: { layout: "max-w-(--layout-container-width)", default: "max-w-(--default-container-width)", narrow: "max-w-(--narrow-container-width)", full: "w-full" } }, defaultVariants: { width: "full" } }); return /* @__PURE__ */ jsx7( Component, { ...rest, className: twMerge2(props.className, container({ width })), children } ); }; // src/components/Menu/Menu.quanta.tsx import "react"; import { Header, Menu as AriaMenu, MenuItem as AriaMenuItem, MenuSection as AriaMenuSection, MenuTrigger as AriaMenuTrigger, Separator as AriaSeparator, SubmenuTrigger as AriaSubmenuTrigger, composeRenderProps as composeRenderProps5 } from "react-aria-components"; import { tv as tv7 } from "tailwind-variants"; import { twMerge as twMerge3 } from "tailwind-merge"; // src/components/Popover/Popover.quanta.tsx import "react"; import { Popover as AriaPopover, composeRenderProps as composeRenderProps4, OverlayArrow, PopoverContext, useSlottedContext } from "react-aria-components"; import { tv as tv6 } from "tailwind-variants"; import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime"; var styles2 = tv6({ base: ` rounded-xl border border-black/10 bg-white bg-clip-padding text-slate-700 shadow-2xl dark:border-white/[15%] dark:bg-zinc-900/70 dark:text-zinc-300 dark:backdrop-blur-2xl dark:backdrop-saturate-200 forced-colors:bg-[Canvas] `, variants: { isEntering: { true: ` duration-200 ease-out animate-in fade-in placement-left:slide-in-from-right-1 placement-right:slide-in-from-left-1 placement-top:slide-in-from-bottom-1 placement-bottom:slide-in-from-top-1 ` }, isExiting: { true: ` duration-150 ease-in animate-out fade-out placement-left:slide-out-to-right-1 placement-right:slide-out-to-left-1 placement-top:slide-out-to-bottom-1 placement-bottom:slide-out-to-top-1 ` } } }); function Popover({ children, showArrow, className, ...props }) { const popoverContext = useSlottedContext(PopoverContext); const isSubmenu = popoverContext?.trigger === "SubmenuTrigger"; let offset = showArrow ? 12 : 8; offset = isSubmenu ? offset - 6 : offset; return /* @__PURE__ */ jsxs5( AriaPopover, { offset, ...props, className: composeRenderProps4( className, (className2, renderProps) => styles2({ ...renderProps, className: className2 }) ), children: [ showArrow && /* @__PURE__ */ jsx8(OverlayArrow, { className: "group", children: /* @__PURE__ */ jsx8( "svg", { width: 12, height: 12, viewBox: "0 0 12 12", className: ` block fill-white stroke-black/10 stroke-1 group-placement-left:-rotate-90 group-placement-right:rotate-90 group-placement-bottom:rotate-180 dark:fill-[#1f1f21] dark:stroke-zinc-600 forced-colors:fill-[Canvas] forced-colors:stroke-[ButtonBorder] `, children: /* @__PURE__ */ jsx8("path", { d: "M0 0 L6 6 L12 0" }) } ) }), children ] } ); } // src/components/Menu/Menu.quanta.tsx import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime"; function Menu(props) { return /* @__PURE__ */ jsx9( AriaMenu, { ...props, className: composeTailwindRenderProps( props.className, ` max-h-[inherit] overflow-auto p-1 font-sans [clip-path:inset(0_0_0_0_round_.75rem)] empty:pb-2 empty:text-center ` ) } ); } var menuItemStyles = tv7({ extend: focusRing, base: ` group relative flex cursor-default items-center gap-4 rounded-lg py-2 pr-3 pl-3 text-sm no-underline forced-color-adjust-none select-none [-webkit-tap-highlight-color:transparent] selected:pr-1 [&[href]]:cursor-pointer `, variants: { isDisabled: { false: ` text-neutral-900 dark:text-neutral-100 `, true: ` text-neutral-300 dark:text-neutral-600 forced-colors:text-[GrayText] ` }, isPressed: { true: ` bg-neutral-100 dark:bg-neutral-800 ` }, isFocused: { true: ` bg-blue-600 text-white forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] ` } }, compoundVariants: [ { isFocused: false, isOpen: true, className: ` bg-neutral-100 dark:bg-neutral-700/60 ` } ] }); function MenuItem(props) { const textValue = props.textValue || (typeof props.children === "string" ? props.children : void 0); return /* @__PURE__ */ jsx9( AriaMenuItem, { ...props, textValue, className: composeRenderProps5( props.className, (className, renderProps) => menuItemStyles({ ...renderProps, className }) ), children: composeRenderProps5( props.children, (children, { selectionMode, isSelected, hasSubmenu }) => /* @__PURE__ */ jsxs6(Fragment4, { children: [ selectionMode !== "none" && /* @__PURE__ */ jsx9("span", { className: "flex w-4 items-center", children: isSelected && /* @__PURE__ */ jsx9(CheckboxIcon, { "aria-hidden": true, className: "h-4 w-4" }) }), children, hasSubmenu && /* @__PURE__ */ jsx9( ChevronrightIcon, { "aria-hidden": true, className: "absolute right-2 h-4 w-4" } ) ] }) ) } ); } function MenuSeparator(props) { return /* @__PURE__ */ jsx9( AriaSeparator, { ...props, className: twMerge3( ` mx-3 my-1 border-b border-neutral-300 dark:border-neutral-700 `, props.className ) } ); } function MenuSection(props) { return /* @__PURE__ */ jsx9( AriaMenuSection, { ...props, className: twMerge3( ` after:block after:h-[5px] after:content-[''] first:-mt-[5px] last:after:hidden `, props.className ), children: props.children } ); } function MenuSectionHeader(props) { return /* @__PURE__ */ jsx9( Header, { ...props, className: twMerge3( ` sticky -top-[5px] z-10 -mx-1 -mt-px truncate border-y border-y-neutral-200 bg-neutral-100/60 px-4 py-1 text-sm font-semibold text-neutral-500 backdrop-blur-md supports-[-moz-appearance:none]:bg-neutral-100 dark:border-y-neutral-700 dark:bg-neutral-700/60 dark:text-neutral-300 [&+*]:mt-1 `, props.className ) } ); } function MenuTrigger(props) { const [trigger, menu] = getMenuTriggerChildren(props.children, "MenuTrigger"); return /* @__PURE__ */ jsxs6(AriaMenuTrigger, { ...props, children: [ trigger, /* @__PURE__ */ jsx9(Popover, { placement: props.placement, className: "min-w-[150px]", children: menu }) ] }); } function SubmenuTrigger(props) { const [trigger, menu] = getMenuTriggerChildren( props.children, "SubmenuTrigger" ); return /* @__PURE__ */ jsxs6(AriaSubmenuTrigger, { ...props, children: [ trigger, /* @__PURE__ */ jsx9(Popover, { offset: -2, crossOffset: -4, children: menu }) ] }); } // src/components/Select/Select.quanta.tsx import "react"; import { Button as Button3, Header as Header3, ListBoxSection as ListBoxSection2, Select as RACSelect, SelectValue } from "react-aria-components"; import { twMerge as twMerge4 } from "tailwind-merge"; import { tv as tv9 } from "tailwind-variants"; // src/components/ListBox/ListBox.quanta.tsx import "react"; import { ListBox as AriaListBox, ListBoxItem as AriaListBoxItem, Collection, Header as Header2, ListBoxSection, composeRenderProps as composeRenderProps6 } from "react-aria-components"; import { tv as tv8 } from "tailwind-variants"; import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime"; function ListBox({ children, ...props }) { return /* @__PURE__ */ jsx10( AriaListBox, { ...props, className: composeTailwindRenderProps( props.className, "flex-1 overflow-auto outline-0" ), children } ); } var itemStyles = tv8({ extend: focusRing, base: ` group relative flex cursor-default items-center gap-8 rounded-md px-2.5 py-1.5 text-sm will-change-transform forced-color-adjust-none select-none `, variants: { isSelected: { false: ` text-slate-700 -outline-offset-2 hover:bg-slate-200 dark:text-zinc-300 dark:hover:bg-zinc-700 `, true: ` bg-blue-600 text-white -outline-offset-4 outline-white dark:outline-white forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] forced-colors:outline-[HighlightText] [&+[data-selected]]:rounded-t-none [&:has(+[data-selected])]:rounded-b-none ` }, isDisabled: { true: ` text-slate-300 dark:text-zinc-600 forced-colors:text-[GrayText] ` } } }); var dropdownItemStyles = tv8({ base: ` group flex cursor-default items-center gap-4 rounded-lg py-2 pr-1 pl-3 text-sm outline-0 forced-color-adjust-none select-none `, variants: { isDisabled: { false: ` text-gray-900 dark:text-zinc-100 `, true: ` text-gray-300 dark:text-zinc-600 forced-colors:text-[GrayText] ` }, isFocused: { true: ` bg-blue-600 text-white forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] ` } }, compoundVariants: [ { isFocused: false, isOpen: true, className: ` bg-gray-100 dark:bg-zinc-700/60 ` } ] }); function DropdownItem(props) { const textValue = props.textValue || (typeof props.children === "string" ? props.children : void 0); return /* @__PURE__ */ jsx10( AriaListBoxItem, { ...props, textValue, className: dropdownItemStyles, children: composeRenderProps6(props.children, (children, { isSelected }) => /* @__PURE__ */ jsxs7(Fragment5, { children: [ /* @__PURE__ */ jsx10( "span", { className: ` flex flex-1 items-center gap-2 truncate font-normal group-selected:font-semibold `, children } ), /* @__PURE__ */ jsx10("span", { className: "flex w-5 items-center", children: isSelected && /* @__PURE__ */ jsx10(CheckboxIcon, { className: "h-4 w-4" }) }) ] })) } ); } // src/components/Select/Select.quanta.tsx import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime"; var triggerStyles = tv9({ extend: focusRing, base: ` flex min-h-11 min-w-[180px] items-center gap-3 rounded-lg bg-quanta-snow px-3 py-2 text-left text-sm text-quanta-space transition hover:bg-quanta-smoke focus:bg-quanta-air active:bg-quanta-air forced-colors:bg-[Field] `, variants: { isDisabled: { true: ` cursor-not-allowed bg-quanta-air text-quanta-silver hover:bg-quanta-air forced-colors:text-[GrayText] ` }, isInvalid: { true: ` bg-quanta-ballet hover:bg-quanta-flamingo ` } } }); function DefaultSelectItem(item) { return /* @__PURE__ */ jsx11(SelectItem, { id: item.label, children: item.value }); } function Select({ label, description, errorMessage, children, items, ...props }) { return /* @__PURE__ */ jsx11( RACSelect, { ...props, className: composeTailwindRenderProps( props.className, "group flex flex-col gap-1" ), children: ({ isOpen }) => /* @__PURE__ */ jsxs8(Fragment6, { children: [ label && /* @__PURE__ */ jsx11(Label, { children: label }), /* @__PURE__ */ jsxs8(Button3, { className: triggerStyles, children: [ /* @__PURE__ */ jsx11( SelectValue, { className: ` min-w-0 flex-1 truncate data-[placeholder]:text-quanta-pigeon ` } ), /* @__PURE__ */ jsx11(SelectChevron, { isOpen }) ] }), description && /* @__PURE__ */ jsx11(Description, { children: description }), /* @__PURE__ */ jsx11(FieldError, { children: errorMessage }), /* @__PURE__ */ jsx11(Popover, { className: "min-w-(--trigger-width) p-1", children: children ? /* @__PURE__ */ jsx11(SelectListBox, { items, children }) : /* @__PURE__ */ jsx11( SelectListBox, { items, children: DefaultSelectItem } ) }) ] }) } ); } function SelectChevron({ isOpen }) { return /* @__PURE__ */ jsx11( ChevrondownIcon, { "aria-hidden": true, size: "base", className: isOpen ? "shrink-0 rotate-180 transition-transform" : "shrink-0 transition-transform" } ); } function SelectListBox(props) { return /* @__PURE__ */ jsx11( ListBox, { ...props, className: composeTailwindRenderProps( props.className, "max-h-72 min-w-(--trigger-width) p-1" ) } ); } function SelectItem(props) { return /* @__PURE__ */ jsx11(DropdownItem, { ...props }); } function SelectSection(props) { return /* @__PURE__ */ jsx11( ListBoxSection2, { ...props, className: twMerge4( ` after:block after:h-1 after:content-[''] first:after:h-0 `, props.className ) } ); } function SelectSectionHeader(props) { return /* @__PURE__ */ jsx11( Header3, { ...props, className: twMerge4( "px-3 py-1 text-xs font-semibold tracking-wide text-quanta-pigeon uppercase", props.className ) } ); } // src/components/TextField/TextField.quanta.tsx import "react"; import { TextField as AriaTextField } from "react-aria-components"; import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime"; function TextField({ label, description, errorMessage, ...props }) { return /* @__PURE__ */ jsxs9( AriaTextField, { ...props, className: composeTailwindRenderProps( props.className, "group flex flex-col gap-1" ), children: [ label && /* @__PURE__ */ jsx12(Label, { children: label }), /* @__PURE__ */ jsx12(Input, { className: inputStyles }), description && /* @__PURE__ */ jsx12(Description, { children: description }), /* @__PURE__ */ jsx12(FieldError, { children: errorMessage }) ] } ); } // src/components/DateTimePicker/DateTimePicker.quanta.tsx import { useCallback, useState, useEffect } from "react"; import { DatePicker as AriaDatePicker } from "react-aria-components"; import { now, getLocalTimeZone, parseDate, toZoned, parseAbsolute, ZonedDateTime } from "@internationalized/date"; // src/components/Dialog/Dialog.quanta.tsx import "react"; import { Dialog as RACDialog } from "react-aria-components"; import { twMerge as twMerge5 } from "tailwind-merge"; import { DialogTrigger } from "react-aria-components"; import { jsx as jsx13 } from "react/jsx-runtime"; function Dialog(props) { return /* @__PURE__ */ jsx13( RACDialog, { ...props, className: twMerge5( ` relative max-h-[inherit] overflow-auto p-6 outline-0 [[data-placement]>&]:p-4 `, props.className ) } ); } // src/components/DateInput/DateInput.quanta.tsx import "react"; import { DateInput as AriaDateInput, DateSegment } from "react-aria-components"; import { tv as tv10 } from "tailwind-variants"; import { jsx as jsx14 } from "react/jsx-runtime"; var segmentStyles = tv10({ base: ` inline rounded-xs p-1 text-gray-800 caret-transparent outline-0 forced-color-adjust-none dark:text-zinc-200 forced-colors:text-[ButtonText] type-literal:px-0 `, variants: { isPlaceholder: { true: ` text-gray-600 italic dark:text-zinc-400 ` }, isDisabled: { true: ` text-gray-200 dark:text-zinc-600 forced-colors:text-[GrayText] ` }, isFocused: { true: ` bg-blue-600 text-white dark:text-white forced-colors:bg-[Highlight] forced-colors:text-[HighlightText] ` } } }); function DateInput(props) { return /* @__PURE__ */ jsx14( AriaDateInput, { ...props, className: composeTailwindRenderProps( props.className, "ml-1 flex h-10 min-w-[150px] flex-1 items-center pl-2" ), children: (segment) => /* @__PURE__ */ jsx14(DateSegment, { segment, className: segmentStyles }) } ); } // src/components/DateTimePicker/DateTimePicker.quanta.tsx import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime"; function isDateOnly(granularity) { return granularity === "day"; } function utcStringToLocalDateValue(utcString, isDateOnly2) { if (!utcString) return null; if (isDateOnly2) { return parseDate(utcString); } try { const localTimeZone = getLocalTimeZone(); return parseAbsolute(utcString, localTimeZone); } catch (error) { console.warn("Failed to parse UTC string:", utcString, error); return null; } } function DateTimePicker({ label, description, errorMessage, resettable = true, value, defaultValue, onChange, isDisabled, granularity = "minute", ...props }) { const [internalValue, setInternalValue] = useState(() => { const initialValue = value ?? defaultValue ?? null; return utcStringToLocalDateValue(initialValue, isDateOnly(granularity)); }); useEffect(() => { if (value !== void 0) { setInternalValue( utcStringToLocalDateValue(value, isDateOnly(granularity)) ); } }, [value, granularity]); const handleReset = useCallback(() => { setInternalValue(null); if (onChange) { onChange(null); } }, [onChange]); const handleDateChange = useCallback( (newValue) => { if (!isDateOnly(granularity) && !internalValue && newValue) { const currentTime = now(getLocalTimeZone()); const localZoned = toZoned( newValue, getLocalTimeZone() ); const dateTimeValue = localZoned.set({ hour: currentTime.hour, minute: currentTime.minute, second: currentTime.second }); setInternalValue(dateTimeValue); if (onChange) { onChange(dateTimeValue.toAbsoluteString()); } return; } setInternalValue(newValue); if (onChange && newValue) { if (newValue instanceof ZonedDateTime) { onChange(newValue.toAbsoluteString()); } else { onChange(newValue.toString()); } } }, [onChange, internalValue, granularity] ); return /* @__PURE__ */ jsx15("div", { className: "flex items-center", children: /* @__PURE__ */ jsxs10( AriaDatePicker, { ...props, value: value !== void 0 ? internalValue : internalValue, defaultValue: value === void 0 ? utcStringToLocalDateValue( defaultValue ?? null, isDateOnly(granularity) ) : void 0, onChange: handleDateChange, granularity, isDisabled, className: composeTailwindRenderProps( props.className, "group flex flex-col gap-1" ), children: [ label && /* @__PURE__ */ jsx15(Label, { children: label }), /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [ /* @__PURE__ */ jsxs10(FieldGroup, { className: "w-auto min-w-[208px]", children: [ /* @__PURE__ */ jsx15(DateInput, { className: "flex h-10 min-w-[150px] flex-1 items-center text-sm" }), /* @__PURE__ */ jsx15( Button, { variant: "icon", className: "mr-1 w-7 rounded-xs outline-offset-0", children: /* @__PURE__ */ jsx15(CalendarIcon, { "aria-hidden": true, className: "h-4 w-4" }) } ) ] }), resettable && /* @__PURE__ */ jsx15( Button, { variant: "icon", className: "h-7 w-7 flex-shrink-0 p-1", onPress: handleReset, isDisabled: isDisabled || !internalValue || props.isReadOnly, "aria-label": "Clear date and time", slot: null, children: /* @__PURE__ */ jsx15(CloseIcon, { className: "h-4 w-4" }) } ) ] }), description && /* @__PURE__ */ jsx15(Description, { children: description }), /* @__PURE__ */ jsx15(FieldError, { children: errorMessage }), /* @__PURE__ */ jsx15(Popover, { children: /* @__PURE__ */ jsx15(Dialog, { children: /* @__PURE__ */ jsx15(Calendar, {}) }) }) ] } ) }); } // src/components/DatePicker/DatePicker.quanta.tsx import "react"; import "react-aria-components"; import { jsx as jsx16 } from "react/jsx-runtime"; function DatePicker({ label, description, errorMessage, ...props }) { return /* @__PURE__ */ jsx16( DateTimePicker, { ...props, label, description, errorMessage, granularity: "day" } ); } // src/components/TimeField/TimeField.quanta.tsx import "react"; import { TimeField as AriaTimeField } from "react-aria-components"; import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime"; function TimeField({ label, description, errorMessage, ...props }) { return /* @__PURE__ */ jsxs11(AriaTimeField, { ...props, children: [ /* @__PURE__ */ jsx17(Label, { children: label }), /* @__PURE__ */ jsx17(DateInput, { className: "w-fit px-2" }), description && /* @__PURE__ */ jsx17(Description, { children: description }), /* @__PURE__ */ jsx17(FieldError, { children: errorMessage }) ] }); } // src/components/MultiSelect/MultiSelect.quanta.tsx import { useRef, useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useId } from "react"; import { Button as Button4, ComboBox, Input as Input2, ListBox as ListBox2, Popover as Popover2, ListBoxItem, TagGroup, TagList, Tag } from "react-aria-components"; import { useListData } from "react-stately"; import { useFilter } from "react-aria"; import { twMerge as twMerge6 } from "tailwind-merge"; import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime"; function MultiSelect({ label, placeholder = "Select items...", items, className = "", description, onItemCleared, onItemInserted, renderEmptyState, selectedItems, creatable = true, ...props }) { const triggerRef = useRef(null); const tagGroupIdentifier = useId(); const selectedKeys = selectedItems?.items.map((i) => i.id); const [width, setWidth] = useState2(0); const { contains } = useFilter({ sensitivity: "base" }); const filter = useCallback2( (item, filterText) => { return !selectedKeys.includes(item.id) && contains(item.name, filterText); }, [contains, selectedKeys] ); const accessibleList = useListData({ initialItems: items, filter }); const [fieldState, setFieldState] = useState2({ selectedKey: null, inputValue: "" }); const onRemove = useCallback2( (keys) => { const key = keys.values().next().value; if (key) { selectedItems.remove(key); setFieldState({ inputValue: "", selectedKey: null }); onItemCleared?.(key); } }, [selectedItems, onItemCleared] ); const onSelectionChange = (id) => { if (!id) { return; } const item = accessibleList.getItem(id); if (!item) { return; } if (!selectedKeys.includes(id)) { selectedItems.append(item); setFieldState({ inputValue: "", selectedKey: id }); onItemInserted?.(id); } accessibleList.setFilterText(""); }; const onInputChange = (value) => { setFieldState((prev) => ({ inputValue: value, selectedKey: value === "" ? null : prev.selectedKey })); accessibleList.setFilterText(value); }; useEffect2(() => { const trigger = triggerRef.current; if (!trigger) return; const observer = new ResizeObserver((entries) => { for (const entry of entries) { setWidth(entry.target.clientWidth); } }); observer.observe(trigger); return () => { observer.unobserve(trigger); }; }, []); const onCreateTag = useCallback2(() => { const inputValue = fieldState.inputValue.trim(); const id = inputValue.toLocaleLowerCase(); let item = accessibleList.getItem(id); if (!item) { item = { id, name: inputValue }; setFieldState((prev) => ({ ...prev, inputValue: "", selectedKey: id })); accessibleList.append(item); selectedItems.append(item); } }, [fieldState.inputValue, accessibleList, selectedItems, setFieldState]); const popLast = useCallback2(() => { if (selectedItems.items.length === 0) { return; } const endKey = selectedItems.items[selectedItems.items.length - 1]; if (endKey) { selectedItems.remove(endKey.id); onItemCleared?.(endKey.id); } setFieldState({ inputValue: "", selectedKey: null }); }, [selectedItems, onItemCleared]); const onKeyDownCapture = useCallback2( (e) => { if (e.key === "Backspace" && fieldState.inputValue === "") { popLast(); } if (e.key === "Enter" && fieldState.inputValue && creatable && accessibleList.items.length === 0) { onCreateTag(); } }, [popLast, fieldState.inputValue, onCreateTag, creatable, accessibleList] ); return /* @__PURE__ */ jsxs12("div", { className: twMerge6("w-full", className), children: [ label && /* @__PURE__ */ jsx18(Label, { children: label }), /* @__PURE__ */ jsx18("div", { ref: triggerRef, className: "relative", children: /* @__PURE__ */ jsxs12( "div", { className: ` relative flex min-h-10 w-full flex-wrap items-center gap-1 rounded-md border border-gray-300 bg-white px-3 py-1.5 shadow-sm focus-within:border-gray-500 focus-within:ring-2 focus-within:ring-gray-400 `, children: [ /* @__PURE__ */ jsx18( TagGroup, { id: tagGroupIdentifier, "aria-label": "Selected items", onRemove, children: /* @__PURE__ */ jsx18( TagList, { items: selectedItems.items, className: "flex flex-wrap items-center gap-1", children: (item) => /* @__PURE__ */ jsxs12( Tag, { className: ` inline-flex items-center gap-x-1.5 rounded-md bg-gray-200 px-2 py-0.5 text-sm text-gray-800 `, textValue: item.name, id: item.id, children: [ item.name, /* @__PURE__ */ jsx18( Button4, { slot: "remove", className: ` grid cursor-pointer place-content-center text-gray-500 hover:bg-gray-600 hover:text-gray-300 focus:bg-gray-600 focus:outline-none `, type: "button", children: /* @__PURE__ */ jsx18(CloseIcon, { size: "xs" }) } ) ] } ) } ) } ), /* @__PURE__ */ jsxs12( ComboBox, { ...props, allowsEmptyCollection: true, "aria-label": "Available items", items: accessibleList.items, selectedKey: fieldState.selectedKey, inputValue: fieldState.inputValue, onSelectionChange, onInputChange, className: "relative flex flex-1", children: [ /* @__PURE__ */ jsx18( Input2, { placeholder, onBlur: () => { setFieldState({ inputValue: "", selectedKey: null }); accessibleList.setFilterText(""); }, onKeyDownCapture, className: ` min-w-0 flex-1 bg-white px-2 py-1.5 text-sm text-gray-800 outline-0 disabled:text-gray-200 ` } ), /* @__PURE__ */ jsx18( Button4, { className: ` absolute top-1/2 right-2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600 focus:outline-none `, type: "button", children: /* @__PURE__ */ jsx18(ChevrondownIcon, {}) } ), /* @__PURE__ */ jsx18( Popover2, { isNonModal: true, trigger: "ComboBox", triggerRef, style: { width: `${width}px` }, className: "max-w-none overflow-hidden", children: /* @__PURE__ */ jsx18( ListBox2, { selectionMode: "multiple", className: "rounded-md border border-gray-200 bg-white p-1 shadow-lg", disallowEmptySelection: false, renderEmptyState: renderEmptyState ? () => renderEmptyState(fieldState.inputValue) : () => /* @__PURE__ */ jsx18( "div", { className: ` block cursor-pointer rounded-md px-3 py-2 text-gray-700 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none `, role: "button", onMouseDown: (e) => { e.stopPropagation(); if (fieldState.inputValue && creatable) { onCreateTag(); } }, tabIndex: 0, children: fieldState.inputValue ? /* @__PURE__ */ jsxs12(Fragment7, { children: [ creatable ? "Create:" : "No results found for:", " ", /* @__PURE__ */ jsx18("strong", { className: "font-medium text-gray-900", children: fieldState.inputValue }) ] }) : "No options" } ), children: (item) => /* @__PURE__ */ jsx18( ListBoxItem, { id: item.id, textValue: item.name, className: ` cursor-pointer rounded-md px-3 py-2 text-gray-700 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none data-[focused]:bg-gray-100 `, children: item.name }, item.id ) } ) } ) ] } ) ] } ) }), description && /* @__PURE__ */ jsx18(Description, { children: description }) ] }); } // src/components/Separator/Separator.quanta.tsx import "react"; import { Separator as RACSeparator } from "react-aria-components"; import { tv as tv11 } from "tailwind-variants"; import { jsx as jsx19 } from "react/jsx-runtime"; var styles3 = tv11({ base: ` bg-gray-300 dark:bg-zinc-600 forced-colors:bg-[ButtonBorder] `, variants: { orientation: { horizontal: "h-px w-full", vertical: "w-px" } }, defaultVariants: { orientation: "horizontal" } }); function Separator(props) { return /* @__PURE__ */ jsx19( RACSeparator, { ...props, className: styles3({ orientation: props.orientation, className: props.className }) } ); } // src/components/Spinner/Spinner.quanta