UNPKG

hazo_ui

Version:

Set of UI components for common interaction elements in a SaaS app

1,129 lines (1,124 loc) 69.7 kB
'use strict'; var jsxRuntime = require('react/jsx-runtime'); var React6 = require('react'); var reactSlot = require('@radix-ui/react-slot'); var classVarianceAuthority = require('class-variance-authority'); var clsx = require('clsx'); var tailwindMerge = require('tailwind-merge'); var DialogPrimitive = require('@radix-ui/react-dialog'); var lucideReact = require('lucide-react'); var PopoverPrimitive = require('@radix-ui/react-popover'); var SelectPrimitive = require('@radix-ui/react-select'); var TooltipPrimitive = require('@radix-ui/react-tooltip'); var reactDayPicker = require('react-day-picker'); var dateFns = require('date-fns'); var SwitchPrimitives = require('@radix-ui/react-switch'); var core = require('@dnd-kit/core'); var sortable = require('@dnd-kit/sortable'); var utilities = require('@dnd-kit/utilities'); var RadioGroupPrimitive = require('@radix-ui/react-radio-group'); var FaIcons = require('react-icons/fa'); var MdIcons = require('react-icons/md'); var HiIcons = require('react-icons/hi'); var BiIcons = require('react-icons/bi'); var AiIcons = require('react-icons/ai'); var BsIcons = require('react-icons/bs'); var FiIcons = require('react-icons/fi'); var IoIcons = require('react-icons/io5'); var RiIcons = require('react-icons/ri'); var TbIcons = require('react-icons/tb'); var CiIcons = require('react-icons/ci'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React6__namespace = /*#__PURE__*/_interopNamespace(React6); var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive); var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive); var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive); var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive); var SwitchPrimitives__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitives); var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive); var FaIcons__namespace = /*#__PURE__*/_interopNamespace(FaIcons); var MdIcons__namespace = /*#__PURE__*/_interopNamespace(MdIcons); var HiIcons__namespace = /*#__PURE__*/_interopNamespace(HiIcons); var BiIcons__namespace = /*#__PURE__*/_interopNamespace(BiIcons); var AiIcons__namespace = /*#__PURE__*/_interopNamespace(AiIcons); var BsIcons__namespace = /*#__PURE__*/_interopNamespace(BsIcons); var FiIcons__namespace = /*#__PURE__*/_interopNamespace(FiIcons); var IoIcons__namespace = /*#__PURE__*/_interopNamespace(IoIcons); var RiIcons__namespace = /*#__PURE__*/_interopNamespace(RiIcons); var TbIcons__namespace = /*#__PURE__*/_interopNamespace(TbIcons); var CiIcons__namespace = /*#__PURE__*/_interopNamespace(CiIcons); var ExampleComponent = ({ children, className = "" }) => { return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `cls_example_component ${className}`, children }); }; function cn(...inputs) { return tailwindMerge.twMerge(clsx.clsx(inputs)); } var buttonVariants = classVarianceAuthority.cva( "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline" }, size: { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10" } }, defaultVariants: { variant: "default", size: "default" } } ); var Button = React6__namespace.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { const Comp = asChild ? reactSlot.Slot : "button"; return /* @__PURE__ */ jsxRuntime.jsx( Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props } ); } ); Button.displayName = "Button"; var Dialog = DialogPrimitive__namespace.Root; var DialogTrigger = DialogPrimitive__namespace.Trigger; var DialogPortal = DialogPrimitive__namespace.Portal; var DialogOverlay = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( DialogPrimitive__namespace.Overlay, { ref, className: cn( "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className ), ...props } )); DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName; var DialogContent = React6__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}), /* @__PURE__ */ jsxRuntime.jsxs( DialogPrimitive__namespace.Content, { ref, className: cn( "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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%] sm:rounded-lg", className ), ...props, children: [ children, /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }), /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" }) ] }) ] } ) ] })); DialogContent.displayName = DialogPrimitive__namespace.Content.displayName; var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx( "div", { className: cn( "flex flex-col space-y-1.5 text-center sm:text-left", className ), ...props } ); DialogHeader.displayName = "DialogHeader"; var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx( "div", { className: cn( "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className ), ...props } ); DialogFooter.displayName = "DialogFooter"; var DialogTitle = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( DialogPrimitive__namespace.Title, { ref, className: cn( "text-lg font-semibold leading-none tracking-tight", className ), ...props } )); DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName; var DialogDescription = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props } )); DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName; var Command = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( "div", { ref, className: cn( "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", className ), ...props } )); Command.displayName = "Command"; var CommandInput = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( "input", { ref, className: cn( "flex h-11 w-full rounded-md border border-input bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 px-3", className ), ...props } )); CommandInput.displayName = "CommandInput"; var CommandList = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( "div", { ref, className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className), ...props } )); CommandList.displayName = "CommandList"; var CommandEmpty = React6__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx( "div", { ref, className: "py-6 text-center text-sm", ...props } )); CommandEmpty.displayName = "CommandEmpty"; var CommandGroup = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( "div", { ref, className: cn( "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className ), ...props } )); CommandGroup.displayName = "CommandGroup"; var CommandItem = React6__namespace.forwardRef(({ className, onSelect, value, ...props }, ref) => { const handleClick = () => { if (onSelect && value) { onSelect(value); } }; return /* @__PURE__ */ jsxRuntime.jsx( "div", { ref, className: cn( "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className ), onClick: handleClick, ...props } ); }); CommandItem.displayName = "CommandItem"; var Popover = PopoverPrimitive__namespace.Root; var PopoverTrigger = PopoverPrimitive__namespace.Trigger; var PopoverContent = React6__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx( PopoverPrimitive__namespace.Content, { ref, align, sideOffset, className: cn( "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md 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-[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 ), ...props } ) })); PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName; var Input = React6__namespace.forwardRef( ({ className, type, ...props }, ref) => { return /* @__PURE__ */ jsxRuntime.jsx( "input", { type, className: cn( "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className ), ref, ...props } ); } ); Input.displayName = "Input"; var Select = SelectPrimitive__namespace.Root; var SelectValue = SelectPrimitive__namespace.Value; var SelectTrigger = React6__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs( SelectPrimitive__namespace.Trigger, { ref, className: cn( "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className ), ...props, children: [ children, /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4 opacity-50" }) }) ] } )); SelectTrigger.displayName = SelectPrimitive__namespace.Trigger.displayName; var SelectScrollUpButton = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( SelectPrimitive__namespace.ScrollUpButton, { ref, className: cn( "flex cursor-default items-center justify-center py-1", className ), ...props, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "h-4 w-4" }) } )); SelectScrollUpButton.displayName = SelectPrimitive__namespace.ScrollUpButton.displayName; var SelectScrollDownButton = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( SelectPrimitive__namespace.ScrollDownButton, { ref, className: cn( "flex cursor-default items-center justify-center py-1", className ), ...props, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4" }) } )); SelectScrollDownButton.displayName = SelectPrimitive__namespace.ScrollDownButton.displayName; var SelectContent = React6__namespace.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs( SelectPrimitive__namespace.Content, { ref, className: cn( "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md 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", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className ), position, ...props, children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}), /* @__PURE__ */ jsxRuntime.jsx( SelectPrimitive__namespace.Viewport, { className: cn( "p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]" ), children } ), /* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {}) ] } ) })); SelectContent.displayName = SelectPrimitive__namespace.Content.displayName; var SelectLabel = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( SelectPrimitive__namespace.Label, { ref, className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className), ...props } )); SelectLabel.displayName = SelectPrimitive__namespace.Label.displayName; var SelectItem = React6__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs( SelectPrimitive__namespace.Item, { ref, className: cn( "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className ), ...props, children: [ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" }) }) }), /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children }) ] } )); SelectItem.displayName = SelectPrimitive__namespace.Item.displayName; var SelectSeparator = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( SelectPrimitive__namespace.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-muted", className), ...props } )); SelectSeparator.displayName = SelectPrimitive__namespace.Separator.displayName; var TooltipProvider = TooltipPrimitive__namespace.Provider; var Tooltip = TooltipPrimitive__namespace.Root; var TooltipTrigger = TooltipPrimitive__namespace.Trigger; var TooltipContent = React6__namespace.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( TooltipPrimitive__namespace.Content, { ref, sideOffset, className: cn( "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md 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 ), ...props } )); TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName; function Calendar({ className, classNames, showOutsideDays = true, ...props }) { return /* @__PURE__ */ jsxRuntime.jsx( reactDayPicker.DayPicker, { showOutsideDays, className: cn("p-3", className), classNames: { months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", month: "space-y-4", caption: "flex justify-center pt-1 relative items-center", caption_label: "text-sm font-medium", nav: "space-x-1 flex items-center", nav_button: cn( "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100" ), nav_button_previous: "absolute left-1", nav_button_next: "absolute right-1", table: "w-full border-collapse space-y-1", head_row: "flex", head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]", row: "flex w-full mt-2", cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20", day: cn( "h-9 w-9 p-0 font-normal aria-selected:opacity-100" ), day_range_end: "day-range-end", day_selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", day_today: "bg-accent text-accent-foreground", day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", day_disabled: "text-muted-foreground opacity-50", day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", day_hidden: "invisible", ...classNames }, components: { IconLeft: () => /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }), IconRight: () => /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" }) }, ...props } ); } Calendar.displayName = "Calendar"; function FilterFieldItem({ filterConfig, fieldConfig, onValueChange, onOperatorChange, onDelete }) { const [isCalendarOpen, setIsCalendarOpen] = React6.useState(false); const renderInput = () => { switch (fieldConfig.type) { case "text": return /* @__PURE__ */ jsxRuntime.jsx( Input, { type: "text", value: filterConfig.value || "", onChange: (e) => { const value = e.target.value; if (fieldConfig.textConfig?.maxLength && value.length > fieldConfig.textConfig.maxLength) { return; } onValueChange(value); }, placeholder: "Enter text...", minLength: fieldConfig.textConfig?.minLength, maxLength: fieldConfig.textConfig?.maxLength, className: "cls_filter_text_input w-full min-w-0" } ); case "number": const numberOperators = [ { value: "equals", label: "Equals" }, { value: "not_equals", label: "Not Equals" }, { value: "greater_than", label: "Greater Than" }, { value: "less_than", label: "Less Than" }, { value: "greater_equal", label: "Greater or Equal" }, { value: "less_equal", label: "Less or Equal" } ]; return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_number_filter_container flex flex-col sm:flex-row items-stretch sm:items-center gap-2 w-full", children: [ /* @__PURE__ */ jsxRuntime.jsxs( Select, { value: filterConfig.operator || "equals", onValueChange: (value) => onOperatorChange?.(value), children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_operator_select w-full sm:w-[140px] shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }), /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: numberOperators.map((op) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: op.value, children: op.label }, op.value)) }) ] } ), /* @__PURE__ */ jsxRuntime.jsx( Input, { type: "number", value: filterConfig.value !== void 0 && filterConfig.value !== null ? filterConfig.value : "", onChange: (e) => { const value = e.target.value; if (value === "") { onValueChange(""); return; } let numValue = fieldConfig.numberConfig?.allowDecimal ? parseFloat(value) : parseInt(value, 10); if (isNaN(numValue)) { return; } if (fieldConfig.numberConfig?.allowDecimal && fieldConfig.numberConfig?.decimalLength) { const decimalPlaces = value.split(".")[1]?.length || 0; if (decimalPlaces > fieldConfig.numberConfig.decimalLength) { return; } } if (fieldConfig.numberConfig?.min !== void 0 && numValue < fieldConfig.numberConfig.min) { numValue = fieldConfig.numberConfig.min; } if (fieldConfig.numberConfig?.max !== void 0 && numValue > fieldConfig.numberConfig.max) { numValue = fieldConfig.numberConfig.max; } onValueChange(numValue); }, placeholder: "Enter number...", min: fieldConfig.numberConfig?.min, max: fieldConfig.numberConfig?.max, step: fieldConfig.numberConfig?.allowDecimal ? 0.01 : 1, className: "cls_filter_number_input flex-1 min-w-0" } ) ] }); case "combobox": return /* @__PURE__ */ jsxRuntime.jsxs( Select, { value: filterConfig.value || "", onValueChange: (value) => onValueChange(value), children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_combobox_select w-full min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select option..." }) }), /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: fieldConfig.comboboxOptions?.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) }) ] } ); case "boolean": const trueLabel = fieldConfig.booleanLabels?.trueLabel || "On"; const falseLabel = fieldConfig.booleanLabels?.falseLabel || "Off"; return /* @__PURE__ */ jsxRuntime.jsxs( Select, { value: filterConfig.value !== void 0 && filterConfig.value !== null ? String(filterConfig.value) : "", onValueChange: (value) => onValueChange(value === "true"), children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_boolean_select w-full min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select..." }) }), /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "true", children: trueLabel }), /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "false", children: falseLabel }) ] }) ] } ); case "date": const dateOperators = [ { value: "equals", label: "Equals" }, { value: "not_equals", label: "Not Equals" }, { value: "greater_than", label: "Greater Than" }, { value: "less_than", label: "Less Than" }, { value: "greater_equal", label: "Greater or Equal" }, { value: "less_equal", label: "Less or Equal" } ]; const selectedDate = filterConfig.value ? typeof filterConfig.value === "string" ? new Date(filterConfig.value) : filterConfig.value : void 0; return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_date_filter_container flex flex-col sm:flex-row items-stretch sm:items-center gap-2 w-full", children: [ /* @__PURE__ */ jsxRuntime.jsxs( Select, { value: filterConfig.operator || "equals", onValueChange: (value) => onOperatorChange?.(value), children: [ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_operator_select w-full sm:w-[140px] shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }), /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: dateOperators.map((op) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: op.value, children: op.label }, op.value)) }) ] } ), /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isCalendarOpen, onOpenChange: setIsCalendarOpen, children: [ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", className: cn( "cls_date_picker_trigger w-full justify-start text-left font-normal min-w-0", !selectedDate && "text-muted-foreground" ), children: [ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "cls_calendar_icon mr-2 h-4 w-4 shrink-0" }), /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_date_text truncate", children: selectedDate ? dateFns.format(selectedDate, "MMM d, yyyy") : "Pick a date" }) ] } ) }), /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_calendar_popover w-auto p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsx( Calendar, { mode: "single", selected: selectedDate, onSelect: (date) => { onValueChange(date); setIsCalendarOpen(false); }, initialFocus: true } ) }) ] }) ] }); default: return null; } }; return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_filter_field_item flex flex-col sm:flex-row items-start sm:items-center gap-3 p-3 border rounded-md bg-card", children: [ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_field_label text-sm font-medium min-w-[120px] sm:min-w-[100px] truncate", children: fieldConfig.label }), /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_field_input_container flex-1 min-w-0 w-full sm:w-auto", children: renderInput() }), /* @__PURE__ */ jsxRuntime.jsx( Button, { variant: "ghost", size: "sm", onClick: onDelete, className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive shrink-0", "aria-label": `Remove ${fieldConfig.label} filter`, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "cls_delete_icon h-4 w-4" }) } ) ] }); } function HazoUiMultiFilterDialog({ availableFields, onFilterChange, initialFilters = [] }) { const [isOpen, setIsOpen] = React6.useState(false); const [filterFields, setFilterFields] = React6.useState(initialFilters); const [isComboboxOpen, setIsComboboxOpen] = React6.useState(false); React6.useEffect(() => { if (isOpen) { setFilterFields(initialFilters); } }, [isOpen, initialFilters]); const handleAddField = (fieldValue) => { if (filterFields.some((ff) => ff.field === fieldValue)) { return; } const fieldConfig = availableFields.find((af) => af.value === fieldValue); if (!fieldConfig) { return; } let defaultValue = ""; if (fieldConfig.type === "boolean") { defaultValue = false; } else if (fieldConfig.type === "number") { defaultValue = fieldConfig.numberConfig?.min || 0; } else if (fieldConfig.type === "date") { defaultValue = /* @__PURE__ */ new Date(); } const newFilter = { field: fieldValue, operator: fieldConfig.type === "number" || fieldConfig.type === "date" ? "equals" : void 0, value: defaultValue }; setFilterFields([...filterFields, newFilter]); setIsComboboxOpen(false); }; const handleDeleteField = (fieldValue) => { setFilterFields(filterFields.filter((ff) => ff.field !== fieldValue)); }; const handleValueChange = (fieldValue, value) => { setFilterFields( filterFields.map( (ff) => ff.field === fieldValue ? { ...ff, value } : ff ) ); }; const handleOperatorChange = (fieldValue, operator) => { setFilterFields( filterFields.map( (ff) => ff.field === fieldValue ? { ...ff, operator } : ff ) ); }; const handleApply = () => { onFilterChange([...filterFields]); setIsOpen(false); }; const handleCancel = () => { setFilterFields(initialFilters); setIsOpen(false); }; const handleClearAll = () => { setFilterFields([]); }; const availableFieldsToAdd = availableFields.filter( (af) => !filterFields.some((ff) => ff.field === af.value) ); const getFieldConfig = (fieldValue) => { return availableFields.find((af) => af.value === fieldValue); }; const hasActiveFilters = initialFilters.length > 0; const tooltipContent = hasActiveFilters ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_filter_tooltip_content space-y-1", children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Filters:" }), initialFilters.map((filterConfig) => { const fieldConfig = getFieldConfig(filterConfig.field); if (!fieldConfig) return null; let displayValue = String(filterConfig.value); if (fieldConfig.type === "boolean") { displayValue = filterConfig.value ? fieldConfig.booleanLabels?.trueLabel || "On" : fieldConfig.booleanLabels?.falseLabel || "Off"; } else if (fieldConfig.type === "combobox") { const option = fieldConfig.comboboxOptions?.find((opt) => opt.value === filterConfig.value); displayValue = option?.label || displayValue; } else if (fieldConfig.type === "date") { const dateValue = filterConfig.value instanceof Date ? filterConfig.value : new Date(filterConfig.value); if (!isNaN(dateValue.getTime())) { displayValue = dateFns.format(dateValue, "MMM d, yyyy"); } } const operatorLabel = filterConfig.operator ? filterConfig.operator.replace("_", " ").replace(/\b\w/g, (l) => l.toUpperCase()) + " " : ""; return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_tooltip_item text-xs", children: [ fieldConfig.label, ": ", operatorLabel, displayValue ] }, filterConfig.field); }) ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_filter_tooltip_content text-xs", children: "No active filters" }); return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [ /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", size: "sm", className: "cls_filter_button", "aria-label": "Open filter dialog", children: [ /* @__PURE__ */ jsxRuntime.jsx( lucideReact.Filter, { className: cn( "cls_filter_icon h-4 w-4 mr-2", hasActiveFilters && "text-blue-600" ) } ), "Filter" ] } ) }) }), /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: tooltipContent }) ] }) }), /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "cls_filter_dialog_content max-w-lg w-full max-h-[90vh] overflow-y-auto", children: [ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Filter Images" }), /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Add multiple fields to filter by. Select a field and set its filter value." }) ] }), /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_filter_dialog_body space-y-4 py-4", children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", role: "combobox", "aria-expanded": isComboboxOpen, className: "cls_add_field_combobox w-full justify-between", children: [ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_combobox_content flex items-center", children: [ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }), /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add field" }) ] }), /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" }) ] } ) }), /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }), /* @__PURE__ */ jsxRuntime.jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsxs( CommandItem, { value: field.label, onSelect: () => handleAddField(field.value), className: "cls_command_item", children: [ /* @__PURE__ */ jsxRuntime.jsx( lucideReact.Check, { className: cn( "cls_check_icon mr-2 h-4 w-4", "opacity-0" ) } ), field.label ] }, field.value )) }) }) ] }) }) ] }) }), filterFields.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_filter_fields_list space-y-2", children: filterFields.map((filterConfig) => { const fieldConfig = getFieldConfig(filterConfig.field); if (!fieldConfig) return null; return /* @__PURE__ */ jsxRuntime.jsx( FilterFieldItem, { filterConfig, fieldConfig, onValueChange: (value) => handleValueChange(filterConfig.field, value), onOperatorChange: (operator) => handleOperatorChange(filterConfig.field, operator), onDelete: () => handleDeleteField(filterConfig.field) }, filterConfig.field ); }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_empty_filter_fields text-center py-8 text-sm text-muted-foreground", children: 'No filter fields added. Click "Add field" to add filtering criteria.' }) ] }), /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [ filterFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", onClick: handleClearAll, className: "cls_clear_all_btn", children: [ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "cls_clear_all_icon h-4 w-4 mr-2" }), "Clear All" ] } ), /* @__PURE__ */ jsxRuntime.jsx( Button, { onClick: handleApply, className: "cls_apply_btn", children: "Apply" } ), /* @__PURE__ */ jsxRuntime.jsx( Button, { variant: "outline", onClick: handleCancel, className: "cls_cancel_btn", children: "Cancel" } ) ] }) ] }) ] }); } var Switch = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( SwitchPrimitives__namespace.Root, { className: cn( "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", className ), ...props, ref, children: /* @__PURE__ */ jsxRuntime.jsx( SwitchPrimitives__namespace.Thumb, { className: cn( "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0" ) } ) } )); Switch.displayName = SwitchPrimitives__namespace.Root.displayName; var Label2 = React6__namespace.forwardRef( ({ className, ...props }, ref) => { return /* @__PURE__ */ jsxRuntime.jsx( "label", { ref, className: cn( "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", className ), ...props } ); } ); Label2.displayName = "Label"; function SortableSortFieldItem({ sortConfig, fieldLabel, onDirectionChange, onDelete }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable.useSortable({ id: sortConfig.field }); const style = { transform: utilities.CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1 }; return /* @__PURE__ */ jsxRuntime.jsxs( "div", { ref: setNodeRef, style, className: "cls_sortable_sort_field_item flex items-center gap-3 p-3 border rounded-md bg-card", children: [ /* @__PURE__ */ jsxRuntime.jsx( "div", { ...attributes, ...listeners, className: "cls_drag_handle cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "cls_drag_icon h-4 w-4" }) } ), /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_field_label flex-1 text-sm font-medium", children: fieldLabel }), /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_direction_control flex items-center gap-2", children: [ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: `switch-${sortConfig.field}`, className: "cls_direction_label text-xs text-muted-foreground", children: sortConfig.direction === "asc" ? "Ascending" : "Descending" }), /* @__PURE__ */ jsxRuntime.jsx( Switch, { id: `switch-${sortConfig.field}`, checked: sortConfig.direction === "desc", onCheckedChange: (checked) => onDirectionChange(checked ? "desc" : "asc"), "aria-label": `Toggle sort direction for ${fieldLabel}` } ) ] }), /* @__PURE__ */ jsxRuntime.jsx( Button, { variant: "ghost", size: "sm", onClick: onDelete, className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive", "aria-label": `Remove ${fieldLabel} from sort`, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "cls_delete_icon h-4 w-4" }) } ) ] } ); } function HazoUiMultiSortDialog({ availableFields, onSortChange, initialSortFields = [] }) { const [isOpen, setIsOpen] = React6.useState(false); const [sortFields, setSortFields] = React6.useState(initialSortFields); const [isComboboxOpen, setIsComboboxOpen] = React6.useState(false); const sensors = core.useSensors( core.useSensor(core.PointerSensor), core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates }) ); React6.useEffect(() => { if (isOpen) { setSortFields(initialSortFields); } }, [isOpen, initialSortFields]); const handleAddField = (fieldValue) => { if (sortFields.some((sf) => sf.field === fieldValue)) { return; } const newField = { field: fieldValue, direction: "asc" }; setSortFields([...sortFields, newField]); setIsComboboxOpen(false); }; const handleDeleteField = (fieldValue) => { setSortFields(sortFields.filter((sf) => sf.field !== fieldValue)); }; const handleDirectionChange = (fieldValue, direction) => { setSortFields( sortFields.map( (sf) => sf.field === fieldValue ? { ...sf, direction } : sf ) ); }; const handleDragEnd = (event) => { const { active, over } = event; if (!over || active.id === over.id) { return; } const oldIndex = sortFields.findIndex((sf) => sf.field === active.id); const newIndex = sortFields.findIndex((sf) => sf.field === over.id); if (oldIndex !== -1 && newIndex !== -1) { setSortFields(sortable.arrayMove(sortFields, oldIndex, newIndex)); } }; const handleApply = () => { onSortChange([...sortFields]); setIsOpen(false); }; const handleCancel = () => { setSortFields(initialSortFields); setIsOpen(false); }; const handleClearAll = () => { setSortFields([]); }; const availableFieldsToAdd = availableFields.filter( (af) => !sortFields.some((sf) => sf.field === af.value) ); const getFieldLabel = (fieldValue) => { return availableFields.find((af) => af.value === fieldValue)?.label || fieldValue; }; const hasActiveSorts = initialSortFields.length > 0; const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Sorts:" }), initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_tooltip_item text-xs", children: [ index + 1, ". ", getFieldLabel(sortConfig.field), " (", sortConfig.direction === "asc" ? "Asc" : "Desc", ")" ] }, sortConfig.field)) ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_sort_tooltip_content text-xs", children: "No active sorts" }); return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [ /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", size: "sm", className: "cls_sort_button", "aria-label": "Open sort dialog", children: [ /* @__PURE__ */ jsxRuntime.jsx( lucideReact.ArrowUpDown, { className: cn( "cls_sort_icon h-4 w-4 mr-2", hasActiveSorts && "text-blue-600" ) } ), "Sort" ] } ) }) }), /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: tooltipContent }) ] }) }), /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg", children: [ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Sort Images" }), /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Add multiple fields to sort by and reorder them. Use the switch to toggle between ascending and descending." }) ] }), /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_sort_dialog_body space-y-4 py-4", children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs( Button, { variant: "outline", role: "combobox", "aria-expanded": isComboboxOpen, className: "cls_add_field_combobox w-full justify-between", children: [ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_combobox_content flex items-center", children: [ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }), /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add field" }) ] }), /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" }) ] } ) }), /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }), /* @__PURE__ */ jsxRuntime.jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsxs( CommandItem, { value: field.label, onSelect: () => handleAddField(field.value), className: "cls_command_item", children: [ /* @__PURE__ */ jsxRuntime.jsx( lucideReact.Check, { className: cn( "cls_check_icon mr-2 h-4 w-4", "opacity-0" )