UNPKG

reablocks

Version:
1,436 lines 363 kB
(function(global, factory) { typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("react/jsx-runtime"), require("body-scroll-lock-upgrade"), require("motion/react"), require("react-dom"), require("@floating-ui/react"), require("tailwind-merge"), require("date-fns"), require("focus-trap-react"), require("name-initials"), require("@marko19907/string-to-color"), require("ellipsize"), require("ctrl-keys"), require("classnames"), require("react-highlight-words"), require("@reaviz/react-use-fuzzy"), require("react-fast-compare"), require("react-textarea-autosize"), require("pluralize"), require("human-format"), require("coverup"), require("chroma-js"), require("create-global-state-hook")) : typeof define === "function" && define.amd ? define(["exports", "react", "react/jsx-runtime", "body-scroll-lock-upgrade", "motion/react", "react-dom", "@floating-ui/react", "tailwind-merge", "date-fns", "focus-trap-react", "name-initials", "@marko19907/string-to-color", "ellipsize", "ctrl-keys", "classnames", "react-highlight-words", "@reaviz/react-use-fuzzy", "react-fast-compare", "react-textarea-autosize", "pluralize", "human-format", "coverup", "chroma-js", "create-global-state-hook"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.reablocks = {}, global.React, global.jsxRuntime, global.bodyScrollLockUpgrade, global.react, global.reactDom, global.react$1, global.tailwindMerge, global.dateFns, global.FocusTrap, global.getInitials, global.stringToColor, global.ellipsize, global.ctrlKeys, global.classNames, global.Highlighter, global.reactUseFuzzy, global.isEqual, global.TextareaAutosize, global.pluralizeLib, global.humanFormat, global.coverup, global.chroma, global.creteGlobalStateHook)); })(this, function(exports2, React, jsxRuntime, bodyScrollLockUpgrade, react, reactDom, react$1, tailwindMerge, dateFns, FocusTrap, getInitials, stringToColor, ellipsize, ctrlKeys, classNames, Highlighter, reactUseFuzzy, isEqual, TextareaAutosize, pluralizeLib, humanFormat, coverup, chroma, creteGlobalStateHook) { "use strict"; function _interopNamespaceDefault(e) { const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } }); if (e) { for (const k in e) { if (k !== "default") { const d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return Object.freeze(n); } const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React); const useExitListener = ({ ref, open = true, onClickOutside, onEscape }) => { React.useEffect(() => { if (!open) { return; } const handleClick = (event) => { if (ref.current && !ref.current.contains(event.target)) { onClickOutside == null ? void 0 : onClickOutside(event); } }; const handleKey = (event) => { if (event.code === "Escape") { onEscape == null ? void 0 : onEscape(event); } }; if (onClickOutside) { document.addEventListener("mousedown", handleClick); document.addEventListener("touchstart", handleClick); } if (onEscape) { document.addEventListener("keydown", handleKey); } return () => { if (onClickOutside) { document.removeEventListener("mousedown", handleClick); document.removeEventListener("touchstart", handleClick); } if (onEscape) { document.removeEventListener("keydown", handleKey); } }; }, [ref, onClickOutside, onEscape, open]); }; const OverlayContext = React.createContext({ close: () => void 0 }); let id = 0; const genId = () => `ref-${++id}`; const useId = (idFromProps) => { const [id2] = React.useState(idFromProps || genId()); return `${id2}`; }; const useUnmount = (fn) => { const fnRef = React.useRef(fn); fnRef.current = fn; React.useLayoutEffect(() => () => fnRef.current(), []); }; const Portal = React.forwardRef( ({ children, className, style, element = "div", onMount, onUnmount }, ref) => { const elementRef = React.useRef(null); const mounted = React.useRef(false); React.useEffect(() => { var _a; if (className && elementRef.current) { elementRef.current.setAttribute("class", `${className} rdk-portal`); } if (style && elementRef.current) { (_a = Object.keys(style)) == null ? void 0 : _a.forEach( (key) => { var _a2; return (_a2 = elementRef.current.style) == null ? void 0 : _a2.setProperty(key, style[key]); } ); } }, [className, style, elementRef.current]); React.useLayoutEffect(() => { elementRef.current = document.createElement(element); onMount == null ? void 0 : onMount(); }, []); useUnmount(() => { onUnmount == null ? void 0 : onUnmount(); const ref2 = elementRef.current; if (ref2 && document.body.contains(ref2)) { document.body.removeChild(ref2); } }); React.useImperativeHandle(ref, () => elementRef.current); if (!elementRef.current) { return null; } if (!mounted.current) { mounted.current = true; elementRef.current.classList.add("rdk-portal"); document.body.appendChild(elementRef.current); } return reactDom.createPortal(children, elementRef.current); } ); const portals = []; const START_INDEX = 990; const OverlayPortal = React.forwardRef( ({ className, children, onMount, onUnmount, appendToBody = true, id: id2, style }, ref) => { let portalId = useId(id2); const [portalIndex, setPortalIndex] = React.useState(null); const [overlayIndex, setOverlayIndex] = React.useState(null); const portalRef = React.useRef(null); React.useImperativeHandle(ref, () => portalRef.current); return /* @__PURE__ */ jsxRuntime.jsx( Portal, { className, ref: portalRef, style, appendToBody, onMount: () => { portals.push(portalId); let pidx = portals.indexOf(portalId); setPortalIndex(pidx); const overlayIdx = START_INDEX + pidx * 2 + 1; setOverlayIndex(overlayIdx); onMount == null ? void 0 : onMount({ portalId, overlayIndex: overlayIdx, portalIndex: pidx, backdropIndex: overlayIdx }); }, onUnmount: () => { onUnmount == null ? void 0 : onUnmount(); portals.splice(portals.indexOf(portalId), 1); setPortalIndex(null); setOverlayIndex(null); }, children: children({ overlayIndex, portalIndex, backdropIndex: overlayIndex, portalId }) } ); } ); const Backdrop = ({ zIndex = 998, portalIndex = 0, className, theme: customTheme, onClick }) => { const theme2 = useComponentTheme("backdrop", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( react.motion.div, { className: cn(theme2.base, className), initial: { opacity: 0 }, animate: { opacity: theme2.opacity - portalIndex / 10 }, exit: { opacity: 0 }, style: { zIndex }, onClick } ); }; const backdropTheme = { base: "fixed top-0 left-0 w-full h-full opacity-0 select-none bg-black", opacity: 0.8 }; const legacyBackdropTheme = { base: "fixed top-0 left-0 w-full h-full opacity-0 select-none bg-[var(--color-layer-transparent)]", opacity: 0.8 }; const GlobalOverlay = ({ open, hasBackdrop = true, closeOnEscape = true, closeOnBackdropClick = true, backdropClassName, children, onClose }) => { const overlayRef = React.useRef(null); const onBackdropClick = React.useCallback(() => { if (closeOnBackdropClick) { onClose == null ? void 0 : onClose(); } }, [closeOnBackdropClick, onClose]); useExitListener({ ref: overlayRef, open, onEscape: () => closeOnEscape && (onClose == null ? void 0 : onClose()) }); React.useEffect(() => { if (open && overlayRef.current !== void 0) { bodyScrollLockUpgrade.disableBodyScroll(overlayRef.current, { // allowTouchMove determines which elements to allow touchmove events for iOS // Reference: https://github.com/rick-liruixin/body-scroll-lock-upgrade?tab=readme-ov-file#allowtouchmove // NOTE: allowTouchMove is typed wrong: https://github.com/rick-liruixin/body-scroll-lock-upgrade/issues/21 allowTouchMove: (el) => { while (el && el !== document.body) { if (el.getAttribute("body-scroll-lock-ignore") !== null) { return true; } if (el.parentElement !== null) { el = el.parentElement; } } return false; } }); } else { bodyScrollLockUpgrade.clearAllBodyScrollLocks(); } return () => { bodyScrollLockUpgrade.clearAllBodyScrollLocks(); }; }, [children, open]); return /* @__PURE__ */ jsxRuntime.jsx(OverlayContext.Provider, { value: { close: () => onClose == null ? void 0 : onClose() }, children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx(OverlayPortal, { ref: overlayRef, children: ({ overlayIndex, portalIndex }) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [ hasBackdrop && /* @__PURE__ */ jsxRuntime.jsx( Backdrop, { zIndex: overlayIndex, portalIndex, onClick: onBackdropClick, className: backdropClassName } ), /* @__PURE__ */ jsxRuntime.jsx("div", { "body-scroll-lock-ignore": "true", children: children({ overlayIndex, portalIndex }) }) ] }) }) }) }); }; const OverlayTrigger = React.forwardRef( ({ children, className, elementType = "span", trigger = ["click"], onOpen = () => void 0, onClose = () => void 0 }, ref) => { const hasTrigger = React.useCallback( (type) => { if (Array.isArray(trigger)) { return trigger.includes(type); } else { return type === trigger; } }, [trigger] ); const onFocus = React.useCallback( (event) => { if (hasTrigger("focus")) { onOpen({ type: "focus", nativeEvent: event }); } }, [onOpen, hasTrigger] ); const onBlur = React.useCallback( (event) => { if (hasTrigger("focus")) { onClose({ type: "focus", nativeEvent: event }); } }, [onClose, hasTrigger] ); const onMouseEnter = React.useCallback( (event) => { if (hasTrigger("hover")) { onOpen({ type: "hover", nativeEvent: event }); } }, [onOpen, hasTrigger] ); const onMouseLeave = React.useCallback( (event) => { if (hasTrigger("hover")) { onClose({ type: "hover", nativeEvent: event }); } }, [onClose, hasTrigger] ); const onClick = React.useCallback( (event) => { if (hasTrigger("click")) { onOpen({ type: "click", nativeEvent: event }); } if (!hasTrigger("click")) { onClose({ type: "hover", nativeEvent: event }); } }, [onOpen, onClose, hasTrigger] ); const onContextMenu = React.useCallback( (event) => { if (hasTrigger("contextmenu")) { event.preventDefault(); onOpen({ type: "contextmenu", nativeEvent: event }); } }, [hasTrigger, onOpen] ); const tabIndex = hasTrigger("focus") ? -1 : void 0; const Component = elementType; return /* @__PURE__ */ jsxRuntime.jsx( Component, { ref, tabIndex, onMouseEnter, onMouseLeave, onFocus, onBlur, onClick, onContextMenu, className, children } ); } ); const usePosition = ({ reference, floating, followCursor, placement = "top", modifiers = [react$1.flip(), react$1.shift({ limiter: react$1.limitShift() })] } = {}) => { const isVirtualElement = React.useMemo( () => !(reference == null ? void 0 : reference.nodeType), [reference] ); const { refs, floatingStyles, update } = react$1.useFloating({ open: true, placement, middleware: modifiers, elements: { reference: isVirtualElement ? null : reference, floating }, whileElementsMounted: react$1.autoUpdate }); React.useEffect(() => { if (isVirtualElement && reference && !followCursor) { const refObject = reference; refs.setPositionReference({ getBoundingClientRect() { return { width: refObject.width, height: refObject.height, x: refObject.left, y: refObject.top, left: refObject.left, top: refObject.top, right: refObject.left + refObject.width, bottom: refObject.top + refObject.height }; } }); } }, [reference, refs, isVirtualElement, followCursor]); const onMouseMove = React.useCallback( ({ clientX, clientY }) => { refs.setPositionReference({ getBoundingClientRect() { return { width: 0, height: 0, x: clientX, y: clientY, left: clientX, top: clientY, right: clientX, bottom: clientY }; } }); }, [refs] ); React.useLayoutEffect(() => { if (followCursor) { window.addEventListener("mousemove", onMouseMove); } return () => { window.removeEventListener("mousemove", onMouseMove); }; }, [followCursor, onMouseMove]); return { refs, anchorRef: refs.reference, floatingRef: refs.floating, floatingStyles, update }; }; const ConnectedOverlayContent = React.forwardRef( ({ triggerRef, children, portalClassName, closeOnBodyClick = true, closeOnEscape = true, elementType, appendToBody = true, followCursor, modifiers, placement = "bottom", onClose }, ref) => { const id2 = useId(); const [overlayIndex, setOverlayIndex] = React.useState(null); const { refs, floatingStyles, update } = usePosition({ reference: triggerRef.current ?? triggerRef, followCursor, modifiers, placement }); React.useImperativeHandle(ref, () => ({ updatePosition: () => { update(); } })); const onClickOutside = React.useCallback( (event) => { if (closeOnBodyClick) { let ref2 = null; if (triggerRef.current) { ref2 = triggerRef.current; } else if (triggerRef.contains !== void 0) { ref2 = triggerRef; } const container = event.target.closest(".rdk-portal"); const isLast = portals.indexOf(id2) === portals.length - 1; if (!(ref2 == null ? void 0 : ref2.contains(event.target)) && (isLast || !container)) { onClose == null ? void 0 : onClose(event); } } }, // eslint-disable-next-line react-hooks/exhaustive-deps [closeOnBodyClick, onClose] ); const onEscape = React.useCallback(() => { if (closeOnEscape) { onClose == null ? void 0 : onClose(); } }, [closeOnEscape, onClose]); useExitListener({ open: true, ref: refs.floating, onClickOutside, onEscape }); return /* @__PURE__ */ jsxRuntime.jsx( OverlayPortal, { id: id2, ref: refs.setFloating, style: { ...floatingStyles, "z-index": overlayIndex }, className: portalClassName, elementType, appendToBody, onMount: (event) => setOverlayIndex(event.overlayIndex), onUnmount: () => setOverlayIndex(null), children } ); } ); const ConnectedOverlay = React.forwardRef( ({ reference, children, open, content, triggerElement, triggerClassName, trigger = "click", onOpen, onClose, ...rest }, ref) => { const mounted = React.useRef(false); const overlayTriggerRef = React.useRef(null); const contentRef = React.useRef(null); const triggerRef = reference || overlayTriggerRef; React.useImperativeHandle(ref, () => ({ updatePosition: () => { var _a; (_a = contentRef.current) == null ? void 0 : _a.updatePosition(); } })); React.useEffect(() => { if (mounted.current) { if (!open) { onClose == null ? void 0 : onClose(); } else { onOpen == null ? void 0 : onOpen(); } } }, [open]); React.useEffect(() => { if (!mounted.current) { mounted.current = true; } }); const providerValue = React.useMemo( () => ({ close: () => onClose == null ? void 0 : onClose() }), [onClose] ); return /* @__PURE__ */ jsxRuntime.jsxs(OverlayContext.Provider, { value: providerValue, children: [ children && /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: trigger ? /* @__PURE__ */ jsxRuntime.jsx( OverlayTrigger, { elementType: triggerElement, ref: overlayTriggerRef, className: triggerClassName, trigger, onOpen, onClose, children } ) : children }), /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx( ConnectedOverlayContent, { ...rest, ref: contentRef, triggerRef, onClose, children: content } ) }) ] }); } ); const useOverlay = () => { const context = React.useContext(OverlayContext); if (context === void 0) { throw new Error( "`useOverlay` hook can only be used inside a overlay component." ); } return context; }; const baseTheme$H = { base: "inline-flex whitespace-no-wrap select-none items-center justify-center px-2.5 py-1 rounded-xs font-sans cursor-pointer", disabled: "disabled:cursor-not-allowed", fullWidth: "flex w-full", group: "rounded-none first:rounded-s last:rounded-e border-s-0 first:border-s", groupText: "border border-y-transparent border-l-transparent last:border-r-transparent hover:bg-initial", adornment: { base: "flex", start: "pr-1", end: "pl-1", sizes: { small: "[&>svg]:w-3 [&>svg]:h-3", medium: "[&>svg]:w-4 [&>svg]:h-4", large: "[&>svg]:w-5 [&>svg]:h-5" } }, sizes: { small: "text-sm px-2 py-1 leading-[normal]", medium: "text-base px-4 py-2 leading-[normal]", large: "text-xl px-5 py-2.5 leading-[normal]" }, iconSizes: { small: "px-2 py-1", medium: "px-4 py-2", large: "px-5 py-2.5" } }; const buttonTheme = { base: [baseTheme$H.base, "text-text-primary font-semibold"].join(" "), disabled: [ baseTheme$H.disabled, "data-[variant=filled]:disabled:bg-gray-600 disabled:text-gray-400 border-gray-500" ].join(" "), fullWidth: baseTheme$H.fullWidth, group: baseTheme$H.group, groupText: baseTheme$H.groupText, adornment: baseTheme$H.adornment, sizes: baseTheme$H.sizes, iconSizes: baseTheme$H.iconSizes, variants: { filled: "bg-secondary hover:bg-border-secondary-hover border-secondary light:text-gray-100", outline: "border-grey border", text: "border-0" }, colors: { default: { filled: "bg-gray-800 hover:bg-gray-700 border-gray-800", outline: "border-secondary border", text: "text-text-primary" }, primary: { filled: "bg-primary hover:bg-primary-hover border-primary text-text-primary", outline: "border border-primary", text: "text-primary hover:text-primary-hover" }, secondary: { filled: "bg-secondary hover:bg-secondary-hover text-text-primary!", outline: "border border-secondary", text: "text-secondary hover:text-secondary-hover" }, success: { filled: "bg-success hover:bg-success-hover border-success text-text-primary", outline: "border border-success", text: "text-success hover:text-success-hover" }, warning: { filled: "bg-warning hover:bg-warning-hover border-warning text-text-primary", outline: "border border-warning", text: "text-warning hover:text-warning-hover" }, error: { filled: "bg-error hover:bg-error-hover border-error text-text-primary", outline: "border border-error", text: "text-error hover:text-error-hover" } } }; const legacyButtonTheme = { base: [ baseTheme$H.base, "[border:_var(--button-border)] rounded-[var(--button-border)] [font-family:_var(--button-font-family)] [font-weight:_var(--button-font-weight)]" ].join(" "), disabled: [ baseTheme$H.disabled, "data-[variant=filled]:disabled:bg-[var(--disabled-background)] disabled:text-[var(--button-disabled-color-on-background)] border-[var(--disabled-background)]" ].join(" "), fullWidth: baseTheme$H.fullWidth, group: baseTheme$H.group, groupText: baseTheme$H.groupText, sizes: { small: "[font-size:_var(--font-size-sm)] p-[var(--button-spacing-sm)]", medium: "[font-size:_var(--font-size-md)] p-[var(--button-spacing-md)]", large: "[font-size:_var(--font-size-lg)] p-[var(--button-spacing-lg)]" }, iconSizes: { small: "[font-size:_var(--font-size-sm)] p-[var(--button-spacing-sm)]", medium: "[font-size:_var(--font-size-md)] p-[var(--button-spacing-md)]", large: "[font-size:_var(--font-size-lg)] p-[var(--button-spacing-lg)]" }, adornment: { ...baseTheme$H.adornment, start: [ baseTheme$H.adornment.start, "[padding-right:_calc(var(--list-item-spacing)_/_2)]" ].join(" "), end: [ baseTheme$H.adornment.start, "[padding-left:_calc(var(--list-item-spacing)_/_2)]" ].join(" "), sizes: { small: "[&>svg]:w-[var(--button-adornment-size-sm)] [&>svg]:h-[var(--button-adornment-size-sm)]", medium: "[&>svg]:w-[var(--button-adornment-size-md)] [&>svg]:h-[var(--button-adornment-size-md)]", large: "[&>svg]:w-[var(--button-adornment-size-lg)] [&>svg]:h-[var(--button-adornment-size-lg)]" } }, variants: { filled: "bg-[var(--button-background)] text-[var(--button-color-on-background)] hover:bg-[var(--button-background-hover)] border-[var(--button-background)] hover:border-[var(--button-background-hover)]", outline: "border-[var(--button-background)] hover:border-[var(--button-background-hover)] text-[var(--button-color)] hover:text-[var(--button-color-hover)] border", text: "border-0" }, colors: { default: { filled: "bg-[var(--button-background)] text-[var(--button-color-on-background)] hover:bg-[var(--button-background-hover)] border-[var(--button-background)] hover:border-[var(--button-background-hover)]", outline: "", text: "text-[var(--button-color)] hover:text-[var(--button-color-hover)]" }, primary: { filled: "bg-[var(--primary-background)] hover:bg-[var(--primary-background-hover)] border-[var(--primary-background)] border-[var(--primary-background-hover)] text-[var(--button-color-on-background)]", outline: "", text: "text-[var(--primary-color)] hover:text-[var(--primary-color-hover)]" }, secondary: { filled: "bg-[var(--secondary-background)] hover:bg-[var(--secondary-background-hover)] border-[var(--secondary-background)] hover:border-[var(--secondary-background-hover)] text-[var(--button-color-on-background)]", outline: "", text: "text-[var(--secondary-color)] hover:text-[var(--secondary-color-hover)]" }, success: { filled: "bg-[var(--success-background)] hover:bg-[var(--success-background-hover)] border-[var(--success-background)] hover:border-[var(--success-background-hover)] text-[var(--button-color-on-background)]", outline: "", text: "text-[var(--success-color)] hover:text-[var(--success-color-hover)]" }, warning: { filled: "bg-[var(--warning-background)] hover:bg-[var(--warning-background-hover)] border-[var(--warning-background)] hover:border-[var(--warning-background-hover)] text-[var(--button-color-on-background)]", outline: "", text: "text-[var(--warning-color)] hover:text-[var(--warning-color-hover)]" }, error: { filled: "bg-[var(--error-background)] hover:bg-[var(--error-background-hover)] border-[var(--error-background)] hover:border-[var(--error-background-hover)] text-[var(--button-color-on-background)]", outline: "", text: "text-[var(--error-color)] hover:text-[var(--warning-error-hover)]" } } }; const ButtonGroupContext = React.createContext({ variant: null, size: null }); const Button = React.forwardRef( ({ color = "default", variant = "filled", children, fullWidth, size = "medium", disableAnimation, className, disableMargins, disablePadding, disabled, startAdornment, endAdornment, theme: customTheme, type = "button", ...rest }, ref) => { const theme2 = useComponentTheme("button", customTheme); const { variant: groupVariant, size: groupSize } = React.useContext(ButtonGroupContext); const isGroup = !!groupVariant && !!groupSize; return /* @__PURE__ */ jsxRuntime.jsxs( react.motion.button, { ...rest, type, disabled, ref, whileTap: { scale: disabled || disableAnimation ? 1 : 0.9 }, "data-variant": groupVariant || variant, className: tailwindMerge.twMerge( theme2.base, theme2.disabled, fullWidth && theme2.fullWidth, theme2.variants[groupVariant || variant], theme2.colors[color][groupVariant || variant], theme2.sizes[groupSize || size], isGroup && theme2.group, isGroup && groupVariant === "text" && theme2.groupText, disableMargins && "m-0", disablePadding && "p-0", className ), children: [ startAdornment && /* @__PURE__ */ jsxRuntime.jsx( "div", { className: tailwindMerge.twMerge( theme2.adornment.base, theme2.adornment.start, theme2.adornment.sizes[size] ), children: startAdornment } ), children, endAdornment && /* @__PURE__ */ jsxRuntime.jsx( "div", { className: tailwindMerge.twMerge( theme2.adornment.base, theme2.adornment.end, theme2.adornment.sizes[size] ), children: endAdornment } ) ] } ); } ); const ButtonGroup = ({ children, className, variant, size }) => { const values = React.useMemo( () => ({ variant: variant || "filled", size: size || "medium" }), [size, variant] ); return /* @__PURE__ */ jsxRuntime.jsx(ButtonGroupContext.Provider, { value: values, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, children }) }); }; const Chip = React.forwardRef( ({ children, color = "default", variant = "filled", size = "medium", selected, disabled, className, disableMargins, start, end, onClick, theme: customTheme, ...rest }, ref) => { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m; const theme2 = useComponentTheme("chip", customTheme); return /* @__PURE__ */ jsxRuntime.jsxs( "div", { ...rest, ref, tabIndex: onClick ? 0 : -1, onClick: !disabled ? onClick : void 0, className: tailwindMerge.twMerge( theme2.base, theme2.variants[variant], (_a = theme2.colors[color]) == null ? void 0 : _a.base, (_c = (_b = theme2.colors[color]) == null ? void 0 : _b.variants) == null ? void 0 : _c[variant], theme2.sizes[size], theme2.focus, !!onClick && !disabled && ((_e = (_d = theme2.colors[color]) == null ? void 0 : _d.selectable) == null ? void 0 : _e.base), !!onClick && !disabled && ((_i = (_h = (_g = (_f = theme2.colors[color]) == null ? void 0 : _f.selectable) == null ? void 0 : _g.variants) == null ? void 0 : _h[variant]) == null ? void 0 : _i.base), selected && ((_m = (_l = (_k = (_j = theme2.colors[color]) == null ? void 0 : _j.selectable) == null ? void 0 : _k.variants) == null ? void 0 : _l[variant]) == null ? void 0 : _m.selected), disableMargins && "m-0", "transition-colors duration-300 ease [&>svg]:transition-[fill] [&>svg]:will-change-[fill]", className, disabled && theme2.disabled ), "aria-disabled": disabled, children: [ start && /* @__PURE__ */ jsxRuntime.jsx( "div", { className: tailwindMerge.twMerge( theme2.adornment.base, theme2.adornment.start, theme2.adornment.sizes[size] ), children: start } ), /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children }), end && /* @__PURE__ */ jsxRuntime.jsx( "div", { className: tailwindMerge.twMerge( theme2.adornment.base, theme2.adornment.end, theme2.adornment.sizes[size] ), children: end } ) ] } ); } ); function getMonthNames(locale, format2 = "short") { if (!locale && typeof window !== "undefined") { locale = navigator.language; } const formatter = new Intl.DateTimeFormat(locale, { month: format2, timeZone: "UTC" }); const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((month) => { const mm = month < 10 ? `0${month}` : month; return /* @__PURE__ */ new Date(`2017-${mm}-01T00:00:00+00:00`); }); return months.map((date) => formatter.format(date)); } const monthNames = getMonthNames(); function getDayLabels(locale) { return Array.from({ length: 7 }, (_, i) => { if (!locale && typeof window !== "undefined") { locale = navigator.language; } return new Intl.DateTimeFormat(locale, { weekday: "short" }).format(new Date(1970, 0, 4 + i)); }); } const daysOfWeek = getDayLabels(); function getWeeks(date, options = { format: "MM/dd/yyyy" }) { if (!date) { throw new Error("A date is required"); } else if (!dateFns.isValid(date)) { console.warn("Invalid date - setting to today", date); date = /* @__PURE__ */ new Date(); } const daysInMonth = dateFns.getDaysInMonth(date); let day = dateFns.startOfMonth(date); let offset = dateFns.getDay(day); const numOfWeeks = Math.ceil((daysInMonth + offset) / 7); const weeks = Array.apply(null, { length: numOfWeeks }).map(() => []); const current = /* @__PURE__ */ new Date(); const [firstWeek] = weeks; for (let i = offset; i > 0; i--) { const offsetDay = dateFns.subDays(day, i); firstWeek.push({ date: offsetDay, dayOfMonth: dateFns.getDate(offsetDay), isWeekendDay: dateFns.getISODay(offsetDay) > 5, isPreviousMonth: true, isNextMonth: false, isToday: false, formattedDate: dateFns.format(offsetDay, options.format) }); } for (let i = 0, week = weeks[i]; i < numOfWeeks; i++, week = weeks[i]) { for (let dayOfWeek = offset; dayOfWeek < 7; dayOfWeek++) { week.push({ date: day, dayOfMonth: dateFns.getDate(day), isPreviousMonth: false, isToday: dateFns.isSameDay(day, current), isNextMonth: !dateFns.isSameMonth(day, date), isWeekendDay: dateFns.getISODay(day) > 5, formattedDate: dateFns.format(day, options.format) }); day = dateFns.addDays(day, 1); } offset = 0; } return weeks; } function getDayAttributes(day, current, hover, isRange) { let isActive = false; let isRangeStart = false; let isRangeEnd = false; const isInRange = (date, range) => { const startDate = dateFns.min(range); const endDate = dateFns.max(range); return dateFns.isWithinInterval(date, { start: startDate, end: endDate }); }; const isSelectionStarted = Array.isArray(current) && dateFns.isValid(current[0]); const isSelectionComplete = isSelectionStarted && dateFns.isValid(current[1]); if (!isRange && dateFns.isValid(current)) { isActive = dateFns.isSameDay(day, current); } else if (!isSelectionStarted) { isActive = dateFns.isSameDay(day, hover); isRangeStart = isActive; isRangeEnd = isActive; } else if (isSelectionComplete) { isActive = isInRange(day, current); isRangeStart = dateFns.isSameDay(day, current[0]); isRangeEnd = dateFns.isSameDay(day, current[1]); } else { const activeRange = [current[0], hover ?? current[0]]; isActive = isInRange(day, activeRange); isRangeStart = dateFns.isSameDay(day, dateFns.min(activeRange)); isRangeEnd = dateFns.isSameDay(day, dateFns.max(activeRange)); } return { isActive, isRangeStart, isRangeEnd }; } function isNextWeekEmpty(day, range, hideNextMonth) { const nextWeek = dateFns.addDays(day, 7); const nextWeekInRange = dateFns.isBefore(nextWeek, dateFns.max(range)) || dateFns.isSameDay(nextWeek, dateFns.max(range)); return !(nextWeekInRange && (dateFns.isSameMonth(day, nextWeek) || !hideNextMonth)); } function isPreviousWeekEmpty(day, range, hidePrevMonth) { const prevWeek = dateFns.addDays(day, -7); const prevWeekInRange = dateFns.isAfter(prevWeek, dateFns.min(range)) || dateFns.isSameDay(prevWeek, dateFns.min(range)); return !(prevWeekInRange && (dateFns.isSameMonth(day, prevWeek) || !hidePrevMonth)); } const CalendarDays = ({ value, current, hover = null, isRange, disabled, min: minLimit, max, animated, xAnimation = 0, showDayOfWeek, showToday, dayOfWeekLabels = daysOfWeek, hidePrevMonthDays, hideNextMonthDays, onChange, onHover, theme: customTheme }) => { const { days } = useComponentTheme("calendar", customTheme); const [hoveringDate, setHoveringDate] = React.useState(hover); const weeks = React.useMemo(() => getWeeks(value), [value]); const maxLimit = React.useMemo(() => max === "now" ? /* @__PURE__ */ new Date() : max, [max]); const renderDay = React.useCallback( (day) => { if (day.isPreviousMonth && hidePrevMonthDays || day.isNextMonth && hideNextMonthDays) { return /* @__PURE__ */ jsxRuntime.jsx("div", {}, day.dayOfMonth); } const handleHover = (value2) => { if (onHover) { onHover(value2); } else { setHoveringDate(value2); } }; const isDisabled = disabled || minLimit && dateFns.isBefore(day.date, minLimit) || maxLimit && dateFns.isAfter(day.date, maxLimit); const currentHover = hover || hoveringDate; const { isActive, isRangeStart, isRangeEnd } = getDayAttributes( day.date, current, currentHover, isRange ); const currentRange = Array.isArray(current) ? [current[0], current[1] ?? currentHover] : [current ?? hoveringDate, current ?? hoveringDate]; const isRangeMiddle = isRange && isActive && !isRangeStart && !isRangeEnd; const rangeConnectsBottom = isRangeStart && isNextWeekEmpty(day.date, currentRange, hideNextMonthDays); const rangeConnectsTop = isRangeEnd && isPreviousWeekEmpty(day.date, currentRange, hidePrevMonthDays); const colorVariant = isActive ? "primary" : "default"; const buttonVariant = isActive ? "filled" : "text"; return /* @__PURE__ */ jsxRuntime.jsx( Button, { className: cn(days.day, { [days.outside]: !isActive && (day.isNextMonth || day.isPreviousMonth), [days.today]: showToday && dateFns.isToday(day.date), [days.selected]: isActive, [days.hover]: day.date === currentHover, [days.range]: isRangeMiddle, [days.startRangeDate]: isRange && isRangeStart && !isRangeEnd, [days.cornerStartDateBottom]: isRange && isActive && !rangeConnectsBottom, [days.endRangeDate]: isRange && isRangeEnd && !isRangeStart, [days.cornerEndDateTop]: isRange && isActive && !rangeConnectsTop }), onMouseEnter: () => handleHover(day.date), onMouseLeave: () => handleHover(null), variant: buttonVariant, color: colorVariant, disableMargins: true, disabled: isDisabled, title: day.formattedDate, onClick: () => onChange(day.date), children: day.dayOfMonth }, day.formattedDate ); }, [ disabled, minLimit, maxLimit, current, hover, isRange, onChange, onHover, hoveringDate, days, hideNextMonthDays, hidePrevMonthDays, showToday ] ); return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsxs( react.motion.div, { initial: { opacity: 0, x: xAnimation }, animate: { opacity: 1, x: 0 }, transition: { x: { type: animated ? "keyframes" : false }, opacity: { duration: 0.2, type: animated ? "tween" : false } }, children: [ showDayOfWeek && /* @__PURE__ */ jsxRuntime.jsx("div", { className: days.header, children: dayOfWeekLabels.map((day) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: days.dayOfWeek, children: day.substring(0, 2) }, `day-${day}`)) }), weeks.map((week, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: days.week, children: week.map(renderDay) }, `week-${i}`)) ] }, value.toString() ) }); }; const CalendarMonths = ({ value, onChange, theme: customTheme }) => { const { months } = useComponentTheme("calendar", customTheme); return /* @__PURE__ */ jsxRuntime.jsx("div", { className: months.root, children: monthNames.map((month, i) => /* @__PURE__ */ jsxRuntime.jsx( Button, { className: cn(months.month, { [months.selected]: value === i }), color: value === i ? "primary" : "default", variant: value === i ? "filled" : "text", disableMargins: true, title: month, onClick: () => onChange(i), children: month }, month )) }); }; const CalendarYears = ({ decadeStart, decadeEnd, value, animated, xAnimation = 0, onChange, theme: customTheme }) => { const { years } = useComponentTheme("calendar", customTheme); const yearDates = React.useMemo(() => { const arr = []; const start = decadeStart.getFullYear(); const end = decadeEnd.getFullYear(); for (let i = start - 1; i < end + 2; i++) { arr.push(i); } return arr; }, [decadeEnd, decadeStart]); return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsx( react.motion.div, { className: years.root, initial: { opacity: 0, x: xAnimation }, animate: { opacity: 1, x: 0 }, transition: { x: { type: animated ? "keyframes" : false }, opacity: { duration: 0.2, type: animated ? "tween" : false } }, children: yearDates.map((year) => /* @__PURE__ */ jsxRuntime.jsx( Button, { className: cn(years.year, { [years.selected]: value === year }), color: value === year ? "primary" : "default", variant: value === year ? "filled" : "text", disableMargins: true, title: year, onClick: () => onChange(year), children: year }, year )) }, `${decadeStart.toString()}-${decadeEnd.toString()}` ) }); }; const PageTitle = React.forwardRef( ({ children, color = "default", variant = "default", disableMargins = false, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme("typography", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( "h1", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.pageTitle, disableMargins && theme2.disableMargins, className ), ...rest, children } ); } ); const PrimaryHeading = React.forwardRef( ({ children, color = "default", variant = "default", disableMargins = false, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme( "typography", customTheme ); return /* @__PURE__ */ jsxRuntime.jsx( "h2", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.primaryHeading, disableMargins && theme2.disableMargins, className ), ...rest, children } ); } ); const SecondaryHeading = React.forwardRef( ({ children, color = "default", variant = "default", disableMargins = false, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme( "typography", customTheme ); return /* @__PURE__ */ jsxRuntime.jsx( "h3", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.secondaryHeading, disableMargins && theme2.disableMargins, className ), ...rest, children } ); } ); const SmallHeading = React.forwardRef( ({ children, color = "default", variant = "default", disableMargins = false, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme("typography", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( "h5", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.smallHeading, disableMargins && theme2.disableMargins, className ), ...rest, children } ); } ); const Sub = React.forwardRef( ({ color = "default", variant = "default", disableMargins = false, children, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme("typography", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( "h6", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.sub, disableMargins && theme2.disableMargins, className ), ...rest, children } ); } ); const Text = React.forwardRef( ({ color = "default", variant = "default", fontStyle = "default", children, className, theme: customTheme, ...rest }, ref) => { const theme2 = useComponentTheme("typography", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( "span", { ref, className: tailwindMerge.twMerge( theme2.colors[color], theme2.variant[variant], theme2.text[fontStyle], className ), ...rest, children } ); } ); const baseTheme$G = { text: { thin: "font-thin", bold: "font-semibold", extraBold: "font-extrabold", italic: "italic" }, variant: { default: "", mono: "font-mono" }, colors: { primary: "text-primary", secondary: "text-secondary", success: "text-success", warning: "text-warning", error: "text-error", info: "text-info" }, sub: "text-sm font-semibold mb-0.5", smallHeading: "text-base font-normal mb-1", secondaryHeading: "text-3xl font-normal mb-1", primaryHeading: "text-3xl font-extrabold mb-1", pageTitle: "text-[40px] font-semibold mb-5", disableMargins: "m-0" }; const typographyTheme = { ...baseTheme$G }; const legacyTypographyTheme = { ...baseTheme$G, colors: { primary: "text-[var(--primary-color)]", secondary: "text-[var(--secondary-color)]", success: "text-[var(--success-color)]", warning: "text-[var(--warning-color)]", error: "text-[var(--error-color)]", info: "text-[var(--info-color)]" }, pageTitle: "[font-family:_var(--font-family)] [font-size:_var(--page-title-font-size)] [font-weight:_var(--page-title-font-weight)] color-[var(--page-title-color)] m-[var(--page-title-margin)]", primaryHeading: "[font-family:_var(--font-family)] [font-size:_var(--primary-heading-font-size)] [font-weight:_var(--primary-heading-font-weight)] text-[var(--primary-heading-color)] m-[var(--primary-heading-margin)]", secondaryHeading: "[font-family:_var(--font-family)] [font-size:_var(--secondary-heading-font-size)] [font-weight:_var(--secondary-heading-font-weight)] text-[var(--secondary-heading-color)] m-[var(--secondary-heading-margin)]", smallHeading: "[font-family:_var(--font-family)] [font-size:_var(--small-heading-font-size)] [font-weight:_var(--small-heading-font-weight)] text-[var(--small-heading-color)] m-[var(--small-heading-margin)]", sub: "[font-size:_var(--sub-font-size)] [font-weight:_var(--sub-font-weight)] text-[var(--sub-color)] m-[var(--sub-margin)]", text: { ...baseTheme$G.text, thin: "[font-weight:_var(--font-weight-thin)]", bold: "[font-weight:_var(--font-weight-bold)]", extraBold: "[font-weight:_var(--font-weight-extraBold)]" } }; const Divider = ({ className, disableMargins = false, orientation = "horizontal", variant = "primary", theme: customTheme, ...rest }) => { const theme2 = useComponentTheme("divider", customTheme); return /* @__PURE__ */ jsxRuntime.jsx( "hr", { ...rest, className: tailwindMerge.twMerge( theme2.base, theme2.variant[variant], theme2.orientation[orientation], disableMargins && theme2.disableMargins, className ) } ); }; const baseTheme$F = { base: "border-none", orientation: { horizontal: "h-px w-full my-2.5", vertical: "w-px h-full mx-2.5" }, variant: { primary: "bg-surface", secondary: "bg-linear-to-r from-transparent to-transparent via-blue-500" }, disableMargins: "my-0 mx-0" }; const dividerTheme = { ...baseTheme$F }; const legacyDividerTheme = { ...baseTheme$F, base: [baseTheme$F.base, "bg-[var(--divider-background)]"].join(" "), orientation: { horizontal: [ baseTheme$