@moontra/moonui-pro 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1541,6 +1541,13 @@ interface BulkAction<T = any> {
1541
1541
  */
1542
1542
  type ExportFormat = 'csv' | 'json' | 'xlsx';
1543
1543
 
1544
+ interface FilterCondition {
1545
+ column: string;
1546
+ operator: FilterOperator;
1547
+ value: any;
1548
+ }
1549
+ type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'between' | 'in' | 'notIn' | 'isNull' | 'isNotNull';
1550
+
1544
1551
  interface DataTableProps<TData, TValue> {
1545
1552
  columns: ColumnDef<TData, TValue>[];
1546
1553
  data: TData[];
@@ -1748,4 +1755,4 @@ declare namespace index {
1748
1755
  };
1749
1756
  }
1750
1757
 
1751
- export { MoonUIAccordionPro as Accordion, MoonUIAccordionContentPro as AccordionContent, MoonUIAccordionItemPro as AccordionItem, MoonUIAccordionTriggerPro as AccordionTrigger, AdvancedChart, AdvancedFormField, AdvancedForms, AdvancedFormsProps, MoonUIAlertPro as Alert, MoonUIAlertDescriptionPro as AlertDescription, MoonUIAlertTitlePro as AlertTitle, AnimatedButton, AnimatedButtonProps, MoonUIAspectRatioPro as AspectRatio, MoonUIAvatarPro as Avatar, MoonUIAvatarFallbackPro as AvatarFallback, MoonUIAvatarImagePro as AvatarImage, MoonUIBadgePro as Badge, MoonUIBreadcrumbPro as Breadcrumb, MoonUIBreadcrumbEllipsisPro as BreadcrumbEllipsis, MoonUIBreadcrumbItemPro as BreadcrumbItem, MoonUIBreadcrumbLinkPro as BreadcrumbLink, MoonUIBreadcrumbListPro as BreadcrumbList, MoonUIBreadcrumbPagePro as BreadcrumbPage, MoonUIBreadcrumbSeparatorPro as BreadcrumbSeparator, BulkAction, MoonUIButtonPro as Button, Calendar, CalendarEvent, MoonUICardPro as Card, MoonUICardContentPro as CardContent, MoonUICardDescriptionPro as CardDescription, MoonUICardFooterPro as CardFooter, MoonUICardHeaderPro as CardHeader, MoonUICardTitlePro as CardTitle, ChartType, MoonUICheckboxPro as Checkbox, MoonUICollapsiblePro as Collapsible, MoonUICollapsibleContentPro as CollapsibleContent, MoonUICollapsibleTriggerPro as CollapsibleTrigger, MoonUIColorPickerPro as ColorPicker, MoonUICommandPro as Command, MoonUICommandDialogPro as CommandDialog, MoonUICommandEmptyPro as CommandEmpty, MoonUICommandGroupPro as CommandGroup, MoonUICommandInputPro as CommandInput, MoonUICommandItemPro as CommandItem, MoonUICommandListPro as CommandList, MoonUICommandSeparatorPro as CommandSeparator, MoonUICommandShortcutPro as CommandShortcut, Dashboard, DataTable, MoonUIDialogPro as Dialog, MoonUIDialogClosePro as DialogClose, MoonUIDialogContentPro as DialogContent, MoonUIDialogDescriptionPro as DialogDescription, MoonUIDialogFooterPro as DialogFooter, MoonUIDialogHeaderPro as DialogHeader, MoonUIDialogTitlePro as DialogTitle, MoonUIDialogTriggerPro as DialogTrigger, DraggableList, DraggableListProps, MoonUIDropdownMenuPro as DropdownMenu, MoonUIDropdownMenuCheckboxItemPro as DropdownMenuCheckboxItem, MoonUIDropdownMenuContentPro as DropdownMenuContent, MoonUIDropdownMenuGroupPro as DropdownMenuGroup, MoonUIDropdownMenuItemPro as DropdownMenuItem, MoonUIDropdownMenuLabelPro as DropdownMenuLabel, MoonUIDropdownMenuPortalPro as DropdownMenuPortal, MoonUIDropdownMenuRadioGroupPro as DropdownMenuRadioGroup, MoonUIDropdownMenuRadioItemPro as DropdownMenuRadioItem, MoonUIDropdownMenuSeparatorPro as DropdownMenuSeparator, MoonUIDropdownMenuShortcutPro as DropdownMenuShortcut, MoonUIDropdownMenuSubPro as DropdownMenuSub, MoonUIDropdownMenuSubContentPro as DropdownMenuSubContent, MoonUIDropdownMenuSubTriggerPro as DropdownMenuSubTrigger, MoonUIDropdownMenuTriggerPro as DropdownMenuTrigger, index as Enhanced, ErrorBoundary, ExportFormat, FileUpload, FloatingActionButton, FloatingActionButtonProps, GitHubRepository, GitHubStars, GitHubStarsProps, HealthCheck, HealthCheckEndpoint, HealthCheckProps, HealthCheckResult, HoverCard3D, HoverCard3DProps, MoonUIInputPro as Input, Kanban, MoonUILabelPro as Label, LazyComponent, LazyImage, LazyImageProps, LazyList, LazyListProps, MagneticButton, MagneticButtonProps, MemoryAnalytics, MemoryAnalyticsProps, MemoryConfig, MemoryEfficientData, MemoryEfficientDataProps, MemoryStats, MoonUIAccordionContentPro, MoonUIAccordionItemPro, MoonUIAccordionPro, MoonUIAccordionTriggerPro, MoonUIAlertDescriptionPro, MoonUIAlertPro, MoonUIAlertTitlePro, MoonUIAspectRatioPro, MoonUIAvatarFallbackPro, MoonUIAvatarImagePro, MoonUIAvatarPro, MoonUIBadgePro, MoonUIBreadcrumbEllipsisPro, MoonUIBreadcrumbItemPro, MoonUIBreadcrumbLinkPro, MoonUIBreadcrumbListPro, MoonUIBreadcrumbPagePro, MoonUIBreadcrumbPro, MoonUIBreadcrumbSeparatorPro, MoonUIButtonPro, MoonUICardContentPro, MoonUICardDescriptionPro, MoonUICardFooterPro, MoonUICardHeaderPro, MoonUICardPro, MoonUICardTitlePro, MoonUICheckboxPro, MoonUICollapsibleContentPro, MoonUICollapsiblePro, MoonUICollapsibleTriggerPro, MoonUIColorPickerPro, MoonUICommandDialogPro, MoonUICommandEmptyPro, MoonUICommandGroupPro, MoonUICommandInputPro, MoonUICommandItemPro, MoonUICommandListPro, MoonUICommandPro, MoonUICommandSeparatorPro, MoonUICommandShortcutPro, MoonUIDialogClosePro, MoonUIDialogContentPro, MoonUIDialogDescriptionPro, MoonUIDialogFooterPro, MoonUIDialogHeaderPro, MoonUIDialogPro, MoonUIDialogTitlePro, MoonUIDialogTriggerPro, MoonUIDropdownMenuCheckboxItemPro, MoonUIDropdownMenuContentPro, MoonUIDropdownMenuGroupPro, MoonUIDropdownMenuItemPro, MoonUIDropdownMenuLabelPro, MoonUIDropdownMenuPortalPro, MoonUIDropdownMenuPro, MoonUIDropdownMenuRadioGroupPro, MoonUIDropdownMenuRadioItemPro, MoonUIDropdownMenuSeparatorPro, MoonUIDropdownMenuShortcutPro, MoonUIDropdownMenuSubContentPro, MoonUIDropdownMenuSubPro, MoonUIDropdownMenuSubTriggerPro, MoonUIDropdownMenuTriggerPro, MoonUIInputPro, MoonUILabelPro, MoonUIPaginationContentPro, MoonUIPaginationEllipsisPro, MoonUIPaginationItemPro, MoonUIPaginationLinkPro, MoonUIPaginationNextPro, MoonUIPaginationPreviousPro, MoonUIPaginationPro, MoonUIPopoverContentPro, MoonUIPopoverPro, MoonUIPopoverTriggerPro, MoonUIProgressPro, MoonUIRadioGroupContextPro, MoonUIRadioGroupItemPro, MoonUIRadioGroupPro, MoonUIRadioItemWithLabelPro, MoonUIRadioLabelPro, MoonUISelectContentPro, MoonUISelectGroupPro, MoonUISelectItemPro, MoonUISelectLabelPro, MoonUISelectPro, MoonUISelectSeparatorPro, MoonUISelectTriggerPro, MoonUISelectValuePro, MoonUISeparatorPro, MoonUISkeletonPro, MoonUISliderPro, MoonUISwitchPro, MoonUITableBodyPro, MoonUITableCaptionPro, MoonUITableCellPro, MoonUITableFooterPro, MoonUITableHeadPro, MoonUITableHeaderPro, MoonUITablePro, MoonUITableRowPro, MoonUITabsContentPro, MoonUITabsListPro, MoonUITabsPro, MoonUITabsTriggerPro, MoonUITextareaPro, MoonUIToastPro, MoonUITogglePro, MoonUITooltipContentPro, MoonUITooltipPro, MoonUITooltipProviderPro, MoonUITooltipTriggerPro, MoonUIalertVariantsPro, MoonUIaspectRatioVariantsPro, MoonUIbreadcrumbVariantsPro, MoonUIcollapsibleContentVariantsPro, MoonUIcollapsibleTriggerVariantsPro, MoonUIcommandVariantsPro, MoonUIradioGroupItemVariantsPro, MoonUItableVariantsPro, MoonUItoggleVariantsPro, OptimizedImage, OptimizedImageProps, MoonUIPaginationPro as Pagination, MoonUIPaginationContentPro as PaginationContent, MoonUIPaginationEllipsisPro as PaginationEllipsis, MoonUIPaginationItemPro as PaginationItem, MoonUIPaginationLinkPro as PaginationLink, MoonUIPaginationNextPro as PaginationNext, MoonUIPaginationPreviousPro as PaginationPrevious, PerformanceAlert, PerformanceDebugger, PerformanceDebuggerProps, PerformanceEntry, PerformanceMetric, PerformanceMetrics, PerformanceMonitor, PerformanceMonitorProps, PinchZoom, MoonUIPopoverPro as Popover, MoonUIPopoverContentPro as PopoverContent, MoonUIPopoverTriggerPro as PopoverTrigger, MoonUIProgressPro as Progress, MoonUIRadioGroupPro as RadioGroup, MoonUIRadioGroupContextPro as RadioGroupContext, MoonUIRadioGroupItemPro as RadioGroupItem, MoonUIRadioItemWithLabelPro as RadioItemWithLabel, MoonUIRadioLabelPro as RadioLabel, RichTextEditor, MoonUISelectPro as Select, MoonUISelectContentPro as SelectContent, MoonUISelectGroupPro as SelectGroup, MoonUISelectItemPro as SelectItem, MoonUISelectLabelPro as SelectLabel, MoonUISelectSeparatorPro as SelectSeparator, MoonUISelectTriggerPro as SelectTrigger, MoonUISelectValuePro as SelectValue, SelectableVirtualList, SelectableVirtualListProps, MoonUISeparatorPro as Separator, MoonUISkeletonPro as Skeleton, MoonUISliderPro as Slider, SpotlightCard, SpotlightCardProps, SwipeableCard, MoonUISwitchPro as Switch, MoonUITablePro as Table, MoonUITableBodyPro as TableBody, MoonUITableCaptionPro as TableCaption, MoonUITableCellPro as TableCell, MoonUITableFooterPro as TableFooter, MoonUITableHeadPro as TableHead, MoonUITableHeaderPro as TableHeader, MoonUITableRowPro as TableRow, MoonUITabsPro as Tabs, MoonUITabsContentPro as TabsContent, MoonUITabsListPro as TabsList, MoonUITabsTriggerPro as TabsTrigger, MoonUITextareaPro as Textarea, Timeline, MoonUIToastPro as Toast, MoonUITogglePro as Toggle, MoonUITooltipPro as Tooltip, MoonUITooltipContentPro as TooltipContent, MoonUITooltipProviderPro as TooltipProvider, MoonUITooltipTriggerPro as TooltipTrigger, VirtualList, VirtualListProps, MoonUIalertVariantsPro as alertVariants, animatedButtonVariants, MoonUIaspectRatioVariantsPro as aspectRatioVariants, moonUIBadgeVariantsPro as badgeVariants, MoonUIbreadcrumbVariantsPro as breadcrumbVariants, moonUIButtonProVariants as buttonVariants, cn, MoonUIcollapsibleContentVariantsPro as collapsibleContentVariants, MoonUIcollapsibleTriggerVariantsPro as collapsibleTriggerVariants, MoonUIcommandVariantsPro as commandVariants, getExpandableColumn, moonUIBadgeVariantsPro, moonUIButtonProVariants, moonUISeparatorVariantsPro, MoonUIradioGroupItemVariantsPro as radioGroupItemVariants, moonUISeparatorVariantsPro as separatorVariants, MoonUItableVariantsPro as tableVariants, MoonUItoggleVariantsPro as toggleVariants, useExpandableRows, useStreamingData, useVirtualList };
1758
+ export { MoonUIAccordionPro as Accordion, MoonUIAccordionContentPro as AccordionContent, MoonUIAccordionItemPro as AccordionItem, MoonUIAccordionTriggerPro as AccordionTrigger, AdvancedChart, AdvancedFormField, AdvancedForms, AdvancedFormsProps, MoonUIAlertPro as Alert, MoonUIAlertDescriptionPro as AlertDescription, MoonUIAlertTitlePro as AlertTitle, AnimatedButton, AnimatedButtonProps, MoonUIAspectRatioPro as AspectRatio, MoonUIAvatarPro as Avatar, MoonUIAvatarFallbackPro as AvatarFallback, MoonUIAvatarImagePro as AvatarImage, MoonUIBadgePro as Badge, MoonUIBreadcrumbPro as Breadcrumb, MoonUIBreadcrumbEllipsisPro as BreadcrumbEllipsis, MoonUIBreadcrumbItemPro as BreadcrumbItem, MoonUIBreadcrumbLinkPro as BreadcrumbLink, MoonUIBreadcrumbListPro as BreadcrumbList, MoonUIBreadcrumbPagePro as BreadcrumbPage, MoonUIBreadcrumbSeparatorPro as BreadcrumbSeparator, BulkAction, MoonUIButtonPro as Button, Calendar, CalendarEvent, MoonUICardPro as Card, MoonUICardContentPro as CardContent, MoonUICardDescriptionPro as CardDescription, MoonUICardFooterPro as CardFooter, MoonUICardHeaderPro as CardHeader, MoonUICardTitlePro as CardTitle, ChartType, MoonUICheckboxPro as Checkbox, MoonUICollapsiblePro as Collapsible, MoonUICollapsibleContentPro as CollapsibleContent, MoonUICollapsibleTriggerPro as CollapsibleTrigger, MoonUIColorPickerPro as ColorPicker, MoonUICommandPro as Command, MoonUICommandDialogPro as CommandDialog, MoonUICommandEmptyPro as CommandEmpty, MoonUICommandGroupPro as CommandGroup, MoonUICommandInputPro as CommandInput, MoonUICommandItemPro as CommandItem, MoonUICommandListPro as CommandList, MoonUICommandSeparatorPro as CommandSeparator, MoonUICommandShortcutPro as CommandShortcut, Dashboard, DataTable, MoonUIDialogPro as Dialog, MoonUIDialogClosePro as DialogClose, MoonUIDialogContentPro as DialogContent, MoonUIDialogDescriptionPro as DialogDescription, MoonUIDialogFooterPro as DialogFooter, MoonUIDialogHeaderPro as DialogHeader, MoonUIDialogTitlePro as DialogTitle, MoonUIDialogTriggerPro as DialogTrigger, DraggableList, DraggableListProps, MoonUIDropdownMenuPro as DropdownMenu, MoonUIDropdownMenuCheckboxItemPro as DropdownMenuCheckboxItem, MoonUIDropdownMenuContentPro as DropdownMenuContent, MoonUIDropdownMenuGroupPro as DropdownMenuGroup, MoonUIDropdownMenuItemPro as DropdownMenuItem, MoonUIDropdownMenuLabelPro as DropdownMenuLabel, MoonUIDropdownMenuPortalPro as DropdownMenuPortal, MoonUIDropdownMenuRadioGroupPro as DropdownMenuRadioGroup, MoonUIDropdownMenuRadioItemPro as DropdownMenuRadioItem, MoonUIDropdownMenuSeparatorPro as DropdownMenuSeparator, MoonUIDropdownMenuShortcutPro as DropdownMenuShortcut, MoonUIDropdownMenuSubPro as DropdownMenuSub, MoonUIDropdownMenuSubContentPro as DropdownMenuSubContent, MoonUIDropdownMenuSubTriggerPro as DropdownMenuSubTrigger, MoonUIDropdownMenuTriggerPro as DropdownMenuTrigger, index as Enhanced, ErrorBoundary, ExportFormat, FileUpload, FilterCondition, FilterOperator, FloatingActionButton, FloatingActionButtonProps, GitHubRepository, GitHubStars, GitHubStarsProps, HealthCheck, HealthCheckEndpoint, HealthCheckProps, HealthCheckResult, HoverCard3D, HoverCard3DProps, MoonUIInputPro as Input, Kanban, MoonUILabelPro as Label, LazyComponent, LazyImage, LazyImageProps, LazyList, LazyListProps, MagneticButton, MagneticButtonProps, MemoryAnalytics, MemoryAnalyticsProps, MemoryConfig, MemoryEfficientData, MemoryEfficientDataProps, MemoryStats, MoonUIAccordionContentPro, MoonUIAccordionItemPro, MoonUIAccordionPro, MoonUIAccordionTriggerPro, MoonUIAlertDescriptionPro, MoonUIAlertPro, MoonUIAlertTitlePro, MoonUIAspectRatioPro, MoonUIAvatarFallbackPro, MoonUIAvatarImagePro, MoonUIAvatarPro, MoonUIBadgePro, MoonUIBreadcrumbEllipsisPro, MoonUIBreadcrumbItemPro, MoonUIBreadcrumbLinkPro, MoonUIBreadcrumbListPro, MoonUIBreadcrumbPagePro, MoonUIBreadcrumbPro, MoonUIBreadcrumbSeparatorPro, MoonUIButtonPro, MoonUICardContentPro, MoonUICardDescriptionPro, MoonUICardFooterPro, MoonUICardHeaderPro, MoonUICardPro, MoonUICardTitlePro, MoonUICheckboxPro, MoonUICollapsibleContentPro, MoonUICollapsiblePro, MoonUICollapsibleTriggerPro, MoonUIColorPickerPro, MoonUICommandDialogPro, MoonUICommandEmptyPro, MoonUICommandGroupPro, MoonUICommandInputPro, MoonUICommandItemPro, MoonUICommandListPro, MoonUICommandPro, MoonUICommandSeparatorPro, MoonUICommandShortcutPro, MoonUIDialogClosePro, MoonUIDialogContentPro, MoonUIDialogDescriptionPro, MoonUIDialogFooterPro, MoonUIDialogHeaderPro, MoonUIDialogPro, MoonUIDialogTitlePro, MoonUIDialogTriggerPro, MoonUIDropdownMenuCheckboxItemPro, MoonUIDropdownMenuContentPro, MoonUIDropdownMenuGroupPro, MoonUIDropdownMenuItemPro, MoonUIDropdownMenuLabelPro, MoonUIDropdownMenuPortalPro, MoonUIDropdownMenuPro, MoonUIDropdownMenuRadioGroupPro, MoonUIDropdownMenuRadioItemPro, MoonUIDropdownMenuSeparatorPro, MoonUIDropdownMenuShortcutPro, MoonUIDropdownMenuSubContentPro, MoonUIDropdownMenuSubPro, MoonUIDropdownMenuSubTriggerPro, MoonUIDropdownMenuTriggerPro, MoonUIInputPro, MoonUILabelPro, MoonUIPaginationContentPro, MoonUIPaginationEllipsisPro, MoonUIPaginationItemPro, MoonUIPaginationLinkPro, MoonUIPaginationNextPro, MoonUIPaginationPreviousPro, MoonUIPaginationPro, MoonUIPopoverContentPro, MoonUIPopoverPro, MoonUIPopoverTriggerPro, MoonUIProgressPro, MoonUIRadioGroupContextPro, MoonUIRadioGroupItemPro, MoonUIRadioGroupPro, MoonUIRadioItemWithLabelPro, MoonUIRadioLabelPro, MoonUISelectContentPro, MoonUISelectGroupPro, MoonUISelectItemPro, MoonUISelectLabelPro, MoonUISelectPro, MoonUISelectSeparatorPro, MoonUISelectTriggerPro, MoonUISelectValuePro, MoonUISeparatorPro, MoonUISkeletonPro, MoonUISliderPro, MoonUISwitchPro, MoonUITableBodyPro, MoonUITableCaptionPro, MoonUITableCellPro, MoonUITableFooterPro, MoonUITableHeadPro, MoonUITableHeaderPro, MoonUITablePro, MoonUITableRowPro, MoonUITabsContentPro, MoonUITabsListPro, MoonUITabsPro, MoonUITabsTriggerPro, MoonUITextareaPro, MoonUIToastPro, MoonUITogglePro, MoonUITooltipContentPro, MoonUITooltipPro, MoonUITooltipProviderPro, MoonUITooltipTriggerPro, MoonUIalertVariantsPro, MoonUIaspectRatioVariantsPro, MoonUIbreadcrumbVariantsPro, MoonUIcollapsibleContentVariantsPro, MoonUIcollapsibleTriggerVariantsPro, MoonUIcommandVariantsPro, MoonUIradioGroupItemVariantsPro, MoonUItableVariantsPro, MoonUItoggleVariantsPro, OptimizedImage, OptimizedImageProps, MoonUIPaginationPro as Pagination, MoonUIPaginationContentPro as PaginationContent, MoonUIPaginationEllipsisPro as PaginationEllipsis, MoonUIPaginationItemPro as PaginationItem, MoonUIPaginationLinkPro as PaginationLink, MoonUIPaginationNextPro as PaginationNext, MoonUIPaginationPreviousPro as PaginationPrevious, PerformanceAlert, PerformanceDebugger, PerformanceDebuggerProps, PerformanceEntry, PerformanceMetric, PerformanceMetrics, PerformanceMonitor, PerformanceMonitorProps, PinchZoom, MoonUIPopoverPro as Popover, MoonUIPopoverContentPro as PopoverContent, MoonUIPopoverTriggerPro as PopoverTrigger, MoonUIProgressPro as Progress, MoonUIRadioGroupPro as RadioGroup, MoonUIRadioGroupContextPro as RadioGroupContext, MoonUIRadioGroupItemPro as RadioGroupItem, MoonUIRadioItemWithLabelPro as RadioItemWithLabel, MoonUIRadioLabelPro as RadioLabel, RichTextEditor, MoonUISelectPro as Select, MoonUISelectContentPro as SelectContent, MoonUISelectGroupPro as SelectGroup, MoonUISelectItemPro as SelectItem, MoonUISelectLabelPro as SelectLabel, MoonUISelectSeparatorPro as SelectSeparator, MoonUISelectTriggerPro as SelectTrigger, MoonUISelectValuePro as SelectValue, SelectableVirtualList, SelectableVirtualListProps, MoonUISeparatorPro as Separator, MoonUISkeletonPro as Skeleton, MoonUISliderPro as Slider, SpotlightCard, SpotlightCardProps, SwipeableCard, MoonUISwitchPro as Switch, MoonUITablePro as Table, MoonUITableBodyPro as TableBody, MoonUITableCaptionPro as TableCaption, MoonUITableCellPro as TableCell, MoonUITableFooterPro as TableFooter, MoonUITableHeadPro as TableHead, MoonUITableHeaderPro as TableHeader, MoonUITableRowPro as TableRow, MoonUITabsPro as Tabs, MoonUITabsContentPro as TabsContent, MoonUITabsListPro as TabsList, MoonUITabsTriggerPro as TabsTrigger, MoonUITextareaPro as Textarea, Timeline, MoonUIToastPro as Toast, MoonUITogglePro as Toggle, MoonUITooltipPro as Tooltip, MoonUITooltipContentPro as TooltipContent, MoonUITooltipProviderPro as TooltipProvider, MoonUITooltipTriggerPro as TooltipTrigger, VirtualList, VirtualListProps, MoonUIalertVariantsPro as alertVariants, animatedButtonVariants, MoonUIaspectRatioVariantsPro as aspectRatioVariants, moonUIBadgeVariantsPro as badgeVariants, MoonUIbreadcrumbVariantsPro as breadcrumbVariants, moonUIButtonProVariants as buttonVariants, cn, MoonUIcollapsibleContentVariantsPro as collapsibleContentVariants, MoonUIcollapsibleTriggerVariantsPro as collapsibleTriggerVariants, MoonUIcommandVariantsPro as commandVariants, getExpandableColumn, moonUIBadgeVariantsPro, moonUIButtonProVariants, moonUISeparatorVariantsPro, MoonUIradioGroupItemVariantsPro as radioGroupItemVariants, moonUISeparatorVariantsPro as separatorVariants, MoonUItableVariantsPro as tableVariants, MoonUItoggleVariantsPro as toggleVariants, useExpandableRows, useStreamingData, useVirtualList };
package/dist/index.mjs CHANGED
@@ -3791,7 +3791,7 @@ var me = t.forwardRef((r2, o) => {
3791
3791
  var e;
3792
3792
  return Array.from(((e = I.current) == null ? void 0 : e.querySelectorAll(ce)) || []);
3793
3793
  }
3794
- function X12(e) {
3794
+ function X13(e) {
3795
3795
  let s = V()[e];
3796
3796
  s && E.setState("value", s.getAttribute(T));
3797
3797
  }
@@ -3806,10 +3806,10 @@ var me = t.forwardRef((r2, o) => {
3806
3806
  s = e > 0 ? we(s, N) : De(s, N), i = s == null ? void 0 : s.querySelector(ce);
3807
3807
  i ? E.setState("value", i.getAttribute(T)) : Q(e);
3808
3808
  }
3809
- let oe = () => X12(V().length - 1), ie3 = (e) => {
3809
+ let oe = () => X13(V().length - 1), ie3 = (e) => {
3810
3810
  e.preventDefault(), e.metaKey ? oe() : e.altKey ? re(1) : Q(1);
3811
3811
  }, se = (e) => {
3812
- e.preventDefault(), e.metaKey ? X12(0) : e.altKey ? re(-1) : Q(-1);
3812
+ e.preventDefault(), e.metaKey ? X13(0) : e.altKey ? re(-1) : Q(-1);
3813
3813
  };
3814
3814
  return t.createElement(Primitive2.div, { ref: o, tabIndex: -1, ...O, "cmdk-root": "", onKeyDown: (e) => {
3815
3815
  var s;
@@ -3836,7 +3836,7 @@ var me = t.forwardRef((r2, o) => {
3836
3836
  break;
3837
3837
  }
3838
3838
  case "Home": {
3839
- e.preventDefault(), X12(0);
3839
+ e.preventDefault(), X13(0);
3840
3840
  break;
3841
3841
  }
3842
3842
  case "End": {
@@ -52710,6 +52710,338 @@ function getVisibleColumns(columns, columnVisibility) {
52710
52710
  return key && columnVisibility[key] !== false;
52711
52711
  }).map((col) => col.id || col.accessorKey).filter(Boolean);
52712
52712
  }
52713
+ var operatorLabels = {
52714
+ equals: "Equals",
52715
+ notEquals: "Not equals",
52716
+ contains: "Contains",
52717
+ notContains: "Not contains",
52718
+ startsWith: "Starts with",
52719
+ endsWith: "Ends with",
52720
+ greaterThan: "Greater than",
52721
+ lessThan: "Less than",
52722
+ greaterThanOrEqual: "Greater than or equal",
52723
+ lessThanOrEqual: "Less than or equal",
52724
+ between: "Between",
52725
+ in: "In",
52726
+ notIn: "Not in",
52727
+ isNull: "Is empty",
52728
+ isNotNull: "Is not empty"
52729
+ };
52730
+ function getOperatorsForColumnType(columnType) {
52731
+ switch (columnType) {
52732
+ case "number":
52733
+ return ["equals", "notEquals", "greaterThan", "lessThan", "greaterThanOrEqual", "lessThanOrEqual", "between", "isNull", "isNotNull"];
52734
+ case "date":
52735
+ return ["equals", "notEquals", "greaterThan", "lessThan", "greaterThanOrEqual", "lessThanOrEqual", "between", "isNull", "isNotNull"];
52736
+ case "boolean":
52737
+ return ["equals", "notEquals", "isNull", "isNotNull"];
52738
+ case "select":
52739
+ return ["equals", "notEquals", "in", "notIn", "isNull", "isNotNull"];
52740
+ default:
52741
+ return ["equals", "notEquals", "contains", "notContains", "startsWith", "endsWith", "isNull", "isNotNull"];
52742
+ }
52743
+ }
52744
+ function DataTableFilterDrawer({
52745
+ table,
52746
+ open,
52747
+ onOpenChange,
52748
+ position = "right",
52749
+ width = "400px",
52750
+ filters: externalFilters,
52751
+ onFiltersChange,
52752
+ customFilters
52753
+ }) {
52754
+ const [internalFilters, setInternalFilters] = useState([]);
52755
+ const [matchAll, setMatchAll] = useState(true);
52756
+ const filters = externalFilters || internalFilters;
52757
+ const setFilters = onFiltersChange || setInternalFilters;
52758
+ const filterableColumns = useMemo(() => {
52759
+ return table.getAllColumns().filter((column) => {
52760
+ if (column.id === "select" || column.id === "actions" || column.id === "expander") {
52761
+ return false;
52762
+ }
52763
+ return column.getCanFilter();
52764
+ });
52765
+ }, [table]);
52766
+ const addFilter = () => {
52767
+ const firstColumn = filterableColumns[0];
52768
+ if (!firstColumn)
52769
+ return;
52770
+ const newFilter = {
52771
+ column: firstColumn.id,
52772
+ operator: "contains",
52773
+ value: ""
52774
+ };
52775
+ setFilters([...filters, newFilter]);
52776
+ };
52777
+ const updateFilter = (index, updates) => {
52778
+ const newFilters = [...filters];
52779
+ newFilters[index] = { ...newFilters[index], ...updates };
52780
+ setFilters(newFilters);
52781
+ };
52782
+ const removeFilter = (index) => {
52783
+ setFilters(filters.filter((_, i) => i !== index));
52784
+ };
52785
+ const clearAllFilters = () => {
52786
+ setFilters([]);
52787
+ table.resetColumnFilters();
52788
+ };
52789
+ const applyFilters = () => {
52790
+ table.resetColumnFilters();
52791
+ filters.forEach((filter) => {
52792
+ const column = table.getColumn(filter.column);
52793
+ if (!column)
52794
+ return;
52795
+ switch (filter.operator) {
52796
+ case "equals":
52797
+ column.setFilterValue(filter.value);
52798
+ break;
52799
+ case "notEquals":
52800
+ column.setFilterValue((value) => value !== filter.value);
52801
+ break;
52802
+ case "contains":
52803
+ column.setFilterValue(
52804
+ (value) => String(value).toLowerCase().includes(String(filter.value).toLowerCase())
52805
+ );
52806
+ break;
52807
+ case "notContains":
52808
+ column.setFilterValue(
52809
+ (value) => !String(value).toLowerCase().includes(String(filter.value).toLowerCase())
52810
+ );
52811
+ break;
52812
+ case "startsWith":
52813
+ column.setFilterValue(
52814
+ (value) => String(value).toLowerCase().startsWith(String(filter.value).toLowerCase())
52815
+ );
52816
+ break;
52817
+ case "endsWith":
52818
+ column.setFilterValue(
52819
+ (value) => String(value).toLowerCase().endsWith(String(filter.value).toLowerCase())
52820
+ );
52821
+ break;
52822
+ case "greaterThan":
52823
+ column.setFilterValue((value) => Number(value) > Number(filter.value));
52824
+ break;
52825
+ case "lessThan":
52826
+ column.setFilterValue((value) => Number(value) < Number(filter.value));
52827
+ break;
52828
+ case "greaterThanOrEqual":
52829
+ column.setFilterValue((value) => Number(value) >= Number(filter.value));
52830
+ break;
52831
+ case "lessThanOrEqual":
52832
+ column.setFilterValue((value) => Number(value) <= Number(filter.value));
52833
+ break;
52834
+ case "isNull":
52835
+ column.setFilterValue((value) => value == null || value === "");
52836
+ break;
52837
+ case "isNotNull":
52838
+ column.setFilterValue((value) => value != null && value !== "");
52839
+ break;
52840
+ }
52841
+ });
52842
+ onOpenChange(false);
52843
+ };
52844
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
52845
+ /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(
52846
+ motion.div,
52847
+ {
52848
+ initial: { opacity: 0 },
52849
+ animate: { opacity: 1 },
52850
+ exit: { opacity: 0 },
52851
+ className: "fixed inset-0 bg-black/20 z-40",
52852
+ onClick: () => onOpenChange(false)
52853
+ }
52854
+ ) }),
52855
+ /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(
52856
+ motion.div,
52857
+ {
52858
+ initial: { x: position === "right" ? "100%" : "-100%" },
52859
+ animate: { x: 0 },
52860
+ exit: { x: position === "right" ? "100%" : "-100%" },
52861
+ transition: { type: "spring", damping: 30, stiffness: 300 },
52862
+ className: cn(
52863
+ "fixed top-0 bottom-0 z-50 bg-background border-l shadow-xl",
52864
+ position === "right" ? "right-0" : "left-0"
52865
+ ),
52866
+ style: { width },
52867
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
52868
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
52869
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
52870
+ /* @__PURE__ */ jsx(Filter, { className: "h-5 w-5" }),
52871
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Filters" }),
52872
+ filters.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
52873
+ "(",
52874
+ filters.length,
52875
+ " active)"
52876
+ ] })
52877
+ ] }),
52878
+ /* @__PURE__ */ jsx(
52879
+ MoonUIButtonPro,
52880
+ {
52881
+ variant: "ghost",
52882
+ size: "icon",
52883
+ onClick: () => onOpenChange(false),
52884
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
52885
+ }
52886
+ )
52887
+ ] }),
52888
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto p-4", children: [
52889
+ /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
52890
+ /* @__PURE__ */ jsx(MoonUILabelPro, { className: "text-sm font-medium mb-2 block", children: "Match conditions" }),
52891
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
52892
+ /* @__PURE__ */ jsx(
52893
+ MoonUIButtonPro,
52894
+ {
52895
+ variant: matchAll ? "primary" : "outline",
52896
+ size: "sm",
52897
+ onClick: () => setMatchAll(true),
52898
+ className: "flex-1",
52899
+ children: "Match all"
52900
+ }
52901
+ ),
52902
+ /* @__PURE__ */ jsx(
52903
+ MoonUIButtonPro,
52904
+ {
52905
+ variant: !matchAll ? "primary" : "outline",
52906
+ size: "sm",
52907
+ onClick: () => setMatchAll(false),
52908
+ className: "flex-1",
52909
+ children: "Match any"
52910
+ }
52911
+ )
52912
+ ] })
52913
+ ] }),
52914
+ /* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "mb-6" }),
52915
+ customFilters && /* @__PURE__ */ jsxs(Fragment, { children: [
52916
+ customFilters,
52917
+ /* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "my-6" })
52918
+ ] }),
52919
+ /* @__PURE__ */ jsx("div", { className: "space-y-4", children: filters.map((filter, index) => /* @__PURE__ */ jsx(
52920
+ FilterConditionRow,
52921
+ {
52922
+ filter,
52923
+ columns: filterableColumns,
52924
+ onUpdate: (updates) => updateFilter(index, updates),
52925
+ onRemove: () => removeFilter(index)
52926
+ },
52927
+ index
52928
+ )) }),
52929
+ /* @__PURE__ */ jsxs(
52930
+ MoonUIButtonPro,
52931
+ {
52932
+ variant: "outline",
52933
+ size: "sm",
52934
+ onClick: addFilter,
52935
+ className: "w-full mt-4",
52936
+ children: [
52937
+ /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
52938
+ "Add filter"
52939
+ ]
52940
+ }
52941
+ )
52942
+ ] }),
52943
+ /* @__PURE__ */ jsx("div", { className: "p-4 border-t space-y-2", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
52944
+ /* @__PURE__ */ jsxs(
52945
+ MoonUIButtonPro,
52946
+ {
52947
+ variant: "outline",
52948
+ onClick: clearAllFilters,
52949
+ disabled: filters.length === 0,
52950
+ className: "flex-1",
52951
+ children: [
52952
+ /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4 mr-2" }),
52953
+ "Clear all"
52954
+ ]
52955
+ }
52956
+ ),
52957
+ /* @__PURE__ */ jsx(MoonUIButtonPro, { onClick: applyFilters, className: "flex-1", children: "Apply filters" })
52958
+ ] }) })
52959
+ ] })
52960
+ }
52961
+ ) })
52962
+ ] });
52963
+ }
52964
+ function FilterConditionRow({
52965
+ filter,
52966
+ columns,
52967
+ onUpdate,
52968
+ onRemove
52969
+ }) {
52970
+ const selectedColumn = columns.find((col) => col.id === filter.column);
52971
+ const columnDef = selectedColumn?.columnDef;
52972
+ const columnType = columnDef?.meta?.filterType || "string";
52973
+ const availableOperators = getOperatorsForColumnType(columnType);
52974
+ const needsValue = filter.operator !== "isNull" && filter.operator !== "isNotNull";
52975
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 p-3 border rounded-lg bg-muted/30", children: [
52976
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
52977
+ /* @__PURE__ */ jsxs(
52978
+ MoonUISelectPro,
52979
+ {
52980
+ value: filter.column,
52981
+ onValueChange: (value) => onUpdate({ column: value }),
52982
+ children: [
52983
+ /* @__PURE__ */ jsx(MoonUISelectTriggerPro, { className: "flex-1", children: /* @__PURE__ */ jsx(MoonUISelectValuePro, {}) }),
52984
+ /* @__PURE__ */ jsx(MoonUISelectContentPro, { children: columns.map((column) => {
52985
+ const header = column.columnDef.header;
52986
+ const label = typeof header === "function" ? column.id : header || column.id;
52987
+ return /* @__PURE__ */ jsx(MoonUISelectItemPro, { value: column.id, children: label }, column.id);
52988
+ }) })
52989
+ ]
52990
+ }
52991
+ ),
52992
+ /* @__PURE__ */ jsx(
52993
+ MoonUIButtonPro,
52994
+ {
52995
+ variant: "ghost",
52996
+ size: "icon",
52997
+ onClick: onRemove,
52998
+ className: "h-8 w-8",
52999
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
53000
+ }
53001
+ )
53002
+ ] }),
53003
+ /* @__PURE__ */ jsxs(
53004
+ MoonUISelectPro,
53005
+ {
53006
+ value: filter.operator,
53007
+ onValueChange: (value) => onUpdate({ operator: value }),
53008
+ children: [
53009
+ /* @__PURE__ */ jsx(MoonUISelectTriggerPro, { children: /* @__PURE__ */ jsx(MoonUISelectValuePro, {}) }),
53010
+ /* @__PURE__ */ jsx(MoonUISelectContentPro, { children: availableOperators.map((operator2) => /* @__PURE__ */ jsx(MoonUISelectItemPro, { value: operator2, children: operatorLabels[operator2] }, operator2)) })
53011
+ ]
53012
+ }
53013
+ ),
53014
+ needsValue && /* @__PURE__ */ jsx("div", { children: columnType === "boolean" ? /* @__PURE__ */ jsxs(
53015
+ MoonUISelectPro,
53016
+ {
53017
+ value: String(filter.value),
53018
+ onValueChange: (value) => onUpdate({ value: value === "true" }),
53019
+ children: [
53020
+ /* @__PURE__ */ jsx(MoonUISelectTriggerPro, { children: /* @__PURE__ */ jsx(MoonUISelectValuePro, {}) }),
53021
+ /* @__PURE__ */ jsxs(MoonUISelectContentPro, { children: [
53022
+ /* @__PURE__ */ jsx(MoonUISelectItemPro, { value: "true", children: "True" }),
53023
+ /* @__PURE__ */ jsx(MoonUISelectItemPro, { value: "false", children: "False" })
53024
+ ] })
53025
+ ]
53026
+ }
53027
+ ) : columnType === "number" ? /* @__PURE__ */ jsx(
53028
+ MoonUIInputPro,
53029
+ {
53030
+ type: "number",
53031
+ value: filter.value || "",
53032
+ onChange: (e) => onUpdate({ value: e.target.value }),
53033
+ placeholder: "Enter value..."
53034
+ }
53035
+ ) : /* @__PURE__ */ jsx(
53036
+ MoonUIInputPro,
53037
+ {
53038
+ value: filter.value || "",
53039
+ onChange: (e) => onUpdate({ value: e.target.value }),
53040
+ placeholder: "Enter value..."
53041
+ }
53042
+ ) })
53043
+ ] });
53044
+ }
52713
53045
  function DataTable({
52714
53046
  columns,
52715
53047
  data,
@@ -52766,6 +53098,7 @@ function DataTable({
52766
53098
  const [globalFilter, setGlobalFilter] = t__default.useState("");
52767
53099
  const [isPaginationLoading, setIsPaginationLoading] = t__default.useState(false);
52768
53100
  const [internalExpandedRows, setInternalExpandedRows] = t__default.useState(/* @__PURE__ */ new Set());
53101
+ const [filterDrawerOpen, setFilterDrawerOpen] = t__default.useState(false);
52769
53102
  const expandedRows = controlledExpandedRows || internalExpandedRows;
52770
53103
  const actualPageSize = defaultPageSize || pageSize;
52771
53104
  const stableData = t__default.useMemo(() => data, [data]);
@@ -52876,10 +53209,19 @@ function DataTable({
52876
53209
  }
52877
53210
  )
52878
53211
  ] }),
52879
- filterable && /* @__PURE__ */ jsxs(MoonUIButtonPro, { variant: "outline", size: "sm", children: [
52880
- /* @__PURE__ */ jsx("span", { suppressHydrationWarning: true, children: /* @__PURE__ */ jsx(Filter, { className: "mr-2 h-4 w-4" }) }),
52881
- "Filters"
52882
- ] }),
53212
+ filterable && /* @__PURE__ */ jsxs(
53213
+ MoonUIButtonPro,
53214
+ {
53215
+ variant: "outline",
53216
+ size: "sm",
53217
+ onClick: () => setFilterDrawerOpen(true),
53218
+ children: [
53219
+ /* @__PURE__ */ jsx("span", { suppressHydrationWarning: true, children: /* @__PURE__ */ jsx(Filter, { className: "mr-2 h-4 w-4" }) }),
53220
+ "Filters",
53221
+ columnFilters.length > 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 rounded-full bg-primary px-2 py-0.5 text-xs text-primary-foreground", children: columnFilters.length })
53222
+ ]
53223
+ }
53224
+ ),
52883
53225
  selectable && bulkActions.length > 0 && /* @__PURE__ */ jsx(
52884
53226
  DataTableBulkActions,
52885
53227
  {
@@ -53080,7 +53422,15 @@ function DataTable({
53080
53422
  )
53081
53423
  ] })
53082
53424
  ] })
53083
- ] })
53425
+ ] }),
53426
+ filterable && /* @__PURE__ */ jsx(
53427
+ DataTableFilterDrawer,
53428
+ {
53429
+ table,
53430
+ open: filterDrawerOpen,
53431
+ onOpenChange: setFilterDrawerOpen
53432
+ }
53433
+ )
53084
53434
  ] });
53085
53435
  }
53086
53436
  function getExpandableColumn(expandedRows, onToggle) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -0,0 +1,442 @@
1
+ "use client"
2
+
3
+ import React, { useState, useMemo } from 'react'
4
+ import { Column, Table } from '@tanstack/react-table'
5
+ import { X, Filter, Trash2, Plus } from 'lucide-react'
6
+ import { Button } from '../ui/button'
7
+ import { Input } from '../ui/input'
8
+ import { Label } from '../ui/label'
9
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'
10
+ import { Switch } from '../ui/switch'
11
+ import { Separator } from '../ui/separator'
12
+ import { cn } from '../../lib/utils'
13
+ import { motion, AnimatePresence } from 'framer-motion'
14
+
15
+ export interface FilterCondition {
16
+ column: string
17
+ operator: FilterOperator
18
+ value: any
19
+ }
20
+
21
+ export type FilterOperator =
22
+ | 'equals'
23
+ | 'notEquals'
24
+ | 'contains'
25
+ | 'notContains'
26
+ | 'startsWith'
27
+ | 'endsWith'
28
+ | 'greaterThan'
29
+ | 'lessThan'
30
+ | 'greaterThanOrEqual'
31
+ | 'lessThanOrEqual'
32
+ | 'between'
33
+ | 'in'
34
+ | 'notIn'
35
+ | 'isNull'
36
+ | 'isNotNull'
37
+
38
+ export interface DataTableFilterDrawerProps<TData> {
39
+ table: Table<TData>
40
+ open: boolean
41
+ onOpenChange: (open: boolean) => void
42
+ position?: 'left' | 'right'
43
+ width?: string
44
+ filters?: FilterCondition[]
45
+ onFiltersChange?: (filters: FilterCondition[]) => void
46
+ customFilters?: React.ReactNode
47
+ }
48
+
49
+ const operatorLabels: Record<FilterOperator, string> = {
50
+ equals: 'Equals',
51
+ notEquals: 'Not equals',
52
+ contains: 'Contains',
53
+ notContains: 'Not contains',
54
+ startsWith: 'Starts with',
55
+ endsWith: 'Ends with',
56
+ greaterThan: 'Greater than',
57
+ lessThan: 'Less than',
58
+ greaterThanOrEqual: 'Greater than or equal',
59
+ lessThanOrEqual: 'Less than or equal',
60
+ between: 'Between',
61
+ in: 'In',
62
+ notIn: 'Not in',
63
+ isNull: 'Is empty',
64
+ isNotNull: 'Is not empty',
65
+ }
66
+
67
+ function getOperatorsForColumnType(columnType?: string): FilterOperator[] {
68
+ switch (columnType) {
69
+ case 'number':
70
+ return ['equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual', 'between', 'isNull', 'isNotNull']
71
+ case 'date':
72
+ return ['equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual', 'between', 'isNull', 'isNotNull']
73
+ case 'boolean':
74
+ return ['equals', 'notEquals', 'isNull', 'isNotNull']
75
+ case 'select':
76
+ return ['equals', 'notEquals', 'in', 'notIn', 'isNull', 'isNotNull']
77
+ default: // string
78
+ return ['equals', 'notEquals', 'contains', 'notContains', 'startsWith', 'endsWith', 'isNull', 'isNotNull']
79
+ }
80
+ }
81
+
82
+ export function DataTableFilterDrawer<TData>({
83
+ table,
84
+ open,
85
+ onOpenChange,
86
+ position = 'right',
87
+ width = '400px',
88
+ filters: externalFilters,
89
+ onFiltersChange,
90
+ customFilters,
91
+ }: DataTableFilterDrawerProps<TData>) {
92
+ const [internalFilters, setInternalFilters] = useState<FilterCondition[]>([])
93
+ const [matchAll, setMatchAll] = useState(true)
94
+
95
+ const filters = externalFilters || internalFilters
96
+ const setFilters = onFiltersChange || setInternalFilters
97
+
98
+ // Get filterable columns
99
+ const filterableColumns = useMemo(() => {
100
+ return table.getAllColumns().filter(column => {
101
+ // Skip special columns
102
+ if (column.id === 'select' || column.id === 'actions' || column.id === 'expander') {
103
+ return false
104
+ }
105
+ // Only include columns that can be filtered
106
+ return column.getCanFilter()
107
+ })
108
+ }, [table])
109
+
110
+ const addFilter = () => {
111
+ const firstColumn = filterableColumns[0]
112
+ if (!firstColumn) return
113
+
114
+ const newFilter: FilterCondition = {
115
+ column: firstColumn.id,
116
+ operator: 'contains',
117
+ value: '',
118
+ }
119
+ setFilters([...filters, newFilter])
120
+ }
121
+
122
+ const updateFilter = (index: number, updates: Partial<FilterCondition>) => {
123
+ const newFilters = [...filters]
124
+ newFilters[index] = { ...newFilters[index], ...updates }
125
+ setFilters(newFilters)
126
+ }
127
+
128
+ const removeFilter = (index: number) => {
129
+ setFilters(filters.filter((_, i) => i !== index))
130
+ }
131
+
132
+ const clearAllFilters = () => {
133
+ setFilters([])
134
+ table.resetColumnFilters()
135
+ }
136
+
137
+ const applyFilters = () => {
138
+ // Reset all column filters first
139
+ table.resetColumnFilters()
140
+
141
+ // Apply each filter
142
+ filters.forEach(filter => {
143
+ const column = table.getColumn(filter.column)
144
+ if (!column) return
145
+
146
+ // Apply filter based on operator
147
+ switch (filter.operator) {
148
+ case 'equals':
149
+ column.setFilterValue(filter.value)
150
+ break
151
+ case 'notEquals':
152
+ column.setFilterValue((value: any) => value !== filter.value)
153
+ break
154
+ case 'contains':
155
+ column.setFilterValue((value: any) =>
156
+ String(value).toLowerCase().includes(String(filter.value).toLowerCase())
157
+ )
158
+ break
159
+ case 'notContains':
160
+ column.setFilterValue((value: any) =>
161
+ !String(value).toLowerCase().includes(String(filter.value).toLowerCase())
162
+ )
163
+ break
164
+ case 'startsWith':
165
+ column.setFilterValue((value: any) =>
166
+ String(value).toLowerCase().startsWith(String(filter.value).toLowerCase())
167
+ )
168
+ break
169
+ case 'endsWith':
170
+ column.setFilterValue((value: any) =>
171
+ String(value).toLowerCase().endsWith(String(filter.value).toLowerCase())
172
+ )
173
+ break
174
+ case 'greaterThan':
175
+ column.setFilterValue((value: any) => Number(value) > Number(filter.value))
176
+ break
177
+ case 'lessThan':
178
+ column.setFilterValue((value: any) => Number(value) < Number(filter.value))
179
+ break
180
+ case 'greaterThanOrEqual':
181
+ column.setFilterValue((value: any) => Number(value) >= Number(filter.value))
182
+ break
183
+ case 'lessThanOrEqual':
184
+ column.setFilterValue((value: any) => Number(value) <= Number(filter.value))
185
+ break
186
+ case 'isNull':
187
+ column.setFilterValue((value: any) => value == null || value === '')
188
+ break
189
+ case 'isNotNull':
190
+ column.setFilterValue((value: any) => value != null && value !== '')
191
+ break
192
+ // Add more operators as needed
193
+ }
194
+ })
195
+
196
+ onOpenChange(false)
197
+ }
198
+
199
+ return (
200
+ <>
201
+ {/* Backdrop */}
202
+ <AnimatePresence>
203
+ {open && (
204
+ <motion.div
205
+ initial={{ opacity: 0 }}
206
+ animate={{ opacity: 1 }}
207
+ exit={{ opacity: 0 }}
208
+ className="fixed inset-0 bg-black/20 z-40"
209
+ onClick={() => onOpenChange(false)}
210
+ />
211
+ )}
212
+ </AnimatePresence>
213
+
214
+ {/* Drawer */}
215
+ <AnimatePresence>
216
+ {open && (
217
+ <motion.div
218
+ initial={{ x: position === 'right' ? '100%' : '-100%' }}
219
+ animate={{ x: 0 }}
220
+ exit={{ x: position === 'right' ? '100%' : '-100%' }}
221
+ transition={{ type: 'spring', damping: 30, stiffness: 300 }}
222
+ className={cn(
223
+ "fixed top-0 bottom-0 z-50 bg-background border-l shadow-xl",
224
+ position === 'right' ? 'right-0' : 'left-0'
225
+ )}
226
+ style={{ width }}
227
+ >
228
+ <div className="flex flex-col h-full">
229
+ {/* Header */}
230
+ <div className="flex items-center justify-between p-4 border-b">
231
+ <div className="flex items-center gap-2">
232
+ <Filter className="h-5 w-5" />
233
+ <h2 className="text-lg font-semibold">Filters</h2>
234
+ {filters.length > 0 && (
235
+ <span className="text-sm text-muted-foreground">
236
+ ({filters.length} active)
237
+ </span>
238
+ )}
239
+ </div>
240
+ <Button
241
+ variant="ghost"
242
+ size="icon"
243
+ onClick={() => onOpenChange(false)}
244
+ >
245
+ <X className="h-4 w-4" />
246
+ </Button>
247
+ </div>
248
+
249
+ {/* Content */}
250
+ <div className="flex-1 overflow-y-auto p-4">
251
+ {/* Match mode */}
252
+ <div className="mb-6">
253
+ <Label className="text-sm font-medium mb-2 block">
254
+ Match conditions
255
+ </Label>
256
+ <div className="flex items-center gap-2">
257
+ <Button
258
+ variant={matchAll ? 'primary' : 'outline'}
259
+ size="sm"
260
+ onClick={() => setMatchAll(true)}
261
+ className="flex-1"
262
+ >
263
+ Match all
264
+ </Button>
265
+ <Button
266
+ variant={!matchAll ? 'primary' : 'outline'}
267
+ size="sm"
268
+ onClick={() => setMatchAll(false)}
269
+ className="flex-1"
270
+ >
271
+ Match any
272
+ </Button>
273
+ </div>
274
+ </div>
275
+
276
+ <Separator className="mb-6" />
277
+
278
+ {/* Custom filters */}
279
+ {customFilters && (
280
+ <>
281
+ {customFilters}
282
+ <Separator className="my-6" />
283
+ </>
284
+ )}
285
+
286
+ {/* Filter conditions */}
287
+ <div className="space-y-4">
288
+ {filters.map((filter, index) => (
289
+ <FilterConditionRow
290
+ key={index}
291
+ filter={filter}
292
+ columns={filterableColumns}
293
+ onUpdate={(updates) => updateFilter(index, updates)}
294
+ onRemove={() => removeFilter(index)}
295
+ />
296
+ ))}
297
+ </div>
298
+
299
+ {/* Add filter button */}
300
+ <Button
301
+ variant="outline"
302
+ size="sm"
303
+ onClick={addFilter}
304
+ className="w-full mt-4"
305
+ >
306
+ <Plus className="h-4 w-4 mr-2" />
307
+ Add filter
308
+ </Button>
309
+ </div>
310
+
311
+ {/* Footer */}
312
+ <div className="p-4 border-t space-y-2">
313
+ <div className="flex gap-2">
314
+ <Button
315
+ variant="outline"
316
+ onClick={clearAllFilters}
317
+ disabled={filters.length === 0}
318
+ className="flex-1"
319
+ >
320
+ <Trash2 className="h-4 w-4 mr-2" />
321
+ Clear all
322
+ </Button>
323
+ <Button onClick={applyFilters} className="flex-1">
324
+ Apply filters
325
+ </Button>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ </motion.div>
330
+ )}
331
+ </AnimatePresence>
332
+ </>
333
+ )
334
+ }
335
+
336
+ interface FilterConditionRowProps<TData> {
337
+ filter: FilterCondition
338
+ columns: Column<TData, any>[]
339
+ onUpdate: (updates: Partial<FilterCondition>) => void
340
+ onRemove: () => void
341
+ }
342
+
343
+ function FilterConditionRow<TData>({
344
+ filter,
345
+ columns,
346
+ onUpdate,
347
+ onRemove,
348
+ }: FilterConditionRowProps<TData>) {
349
+ const selectedColumn = columns.find(col => col.id === filter.column)
350
+ const columnDef = selectedColumn?.columnDef as any
351
+ const columnType = columnDef?.meta?.filterType || 'string'
352
+ const availableOperators = getOperatorsForColumnType(columnType)
353
+
354
+ const needsValue = filter.operator !== 'isNull' && filter.operator !== 'isNotNull'
355
+
356
+ return (
357
+ <div className="space-y-2 p-3 border rounded-lg bg-muted/30">
358
+ {/* Column selector */}
359
+ <div className="flex items-center gap-2">
360
+ <Select
361
+ value={filter.column}
362
+ onValueChange={(value) => onUpdate({ column: value })}
363
+ >
364
+ <SelectTrigger className="flex-1">
365
+ <SelectValue />
366
+ </SelectTrigger>
367
+ <SelectContent>
368
+ {columns.map(column => {
369
+ const header = column.columnDef.header
370
+ const label = typeof header === 'function' ? column.id : header || column.id
371
+
372
+ return (
373
+ <SelectItem key={column.id} value={column.id}>
374
+ {label}
375
+ </SelectItem>
376
+ )
377
+ })}
378
+ </SelectContent>
379
+ </Select>
380
+
381
+ <Button
382
+ variant="ghost"
383
+ size="icon"
384
+ onClick={onRemove}
385
+ className="h-8 w-8"
386
+ >
387
+ <X className="h-4 w-4" />
388
+ </Button>
389
+ </div>
390
+
391
+ {/* Operator selector */}
392
+ <Select
393
+ value={filter.operator}
394
+ onValueChange={(value) => onUpdate({ operator: value as FilterOperator })}
395
+ >
396
+ <SelectTrigger>
397
+ <SelectValue />
398
+ </SelectTrigger>
399
+ <SelectContent>
400
+ {availableOperators.map(operator => (
401
+ <SelectItem key={operator} value={operator}>
402
+ {operatorLabels[operator]}
403
+ </SelectItem>
404
+ ))}
405
+ </SelectContent>
406
+ </Select>
407
+
408
+ {/* Value input */}
409
+ {needsValue && (
410
+ <div>
411
+ {columnType === 'boolean' ? (
412
+ <Select
413
+ value={String(filter.value)}
414
+ onValueChange={(value) => onUpdate({ value: value === 'true' })}
415
+ >
416
+ <SelectTrigger>
417
+ <SelectValue />
418
+ </SelectTrigger>
419
+ <SelectContent>
420
+ <SelectItem value="true">True</SelectItem>
421
+ <SelectItem value="false">False</SelectItem>
422
+ </SelectContent>
423
+ </Select>
424
+ ) : columnType === 'number' ? (
425
+ <Input
426
+ type="number"
427
+ value={filter.value || ''}
428
+ onChange={(e) => onUpdate({ value: e.target.value })}
429
+ placeholder="Enter value..."
430
+ />
431
+ ) : (
432
+ <Input
433
+ value={filter.value || ''}
434
+ onChange={(e) => onUpdate({ value: e.target.value })}
435
+ placeholder="Enter value..."
436
+ />
437
+ )}
438
+ </div>
439
+ )}
440
+ </div>
441
+ )
442
+ }
@@ -44,6 +44,7 @@ import { motion, AnimatePresence } from 'framer-motion'
44
44
  import { DataTableColumnToggle } from './data-table-column-toggle'
45
45
  import { DataTableBulkActions, type BulkAction } from './data-table-bulk-actions'
46
46
  import { exportData, type ExportFormat, getVisibleColumns } from './data-table-export'
47
+ import { DataTableFilterDrawer, type FilterCondition } from './data-table-filter-drawer'
47
48
  import {
48
49
  DropdownMenu,
49
50
  DropdownMenuContent,
@@ -192,6 +193,7 @@ export function DataTable<TData, TValue>({
192
193
  const [globalFilter, setGlobalFilter] = React.useState('')
193
194
  const [isPaginationLoading, setIsPaginationLoading] = React.useState(false)
194
195
  const [internalExpandedRows, setInternalExpandedRows] = React.useState<Set<string>>(new Set())
196
+ const [filterDrawerOpen, setFilterDrawerOpen] = React.useState(false)
195
197
 
196
198
  // Use controlled or internal expanded state
197
199
  const expandedRows = controlledExpandedRows || internalExpandedRows
@@ -339,9 +341,18 @@ export function DataTable<TData, TValue>({
339
341
  )}
340
342
 
341
343
  {filterable && (
342
- <Button variant="outline" size="sm">
344
+ <Button
345
+ variant="outline"
346
+ size="sm"
347
+ onClick={() => setFilterDrawerOpen(true)}
348
+ >
343
349
  <span suppressHydrationWarning><Filter className="mr-2 h-4 w-4" /></span>
344
350
  Filters
351
+ {columnFilters.length > 0 && (
352
+ <span className="ml-2 rounded-full bg-primary px-2 py-0.5 text-xs text-primary-foreground">
353
+ {columnFilters.length}
354
+ </span>
355
+ )}
345
356
  </Button>
346
357
  )}
347
358
 
@@ -586,6 +597,15 @@ export function DataTable<TData, TValue>({
586
597
  </div>
587
598
  </div>
588
599
  )}
600
+
601
+ {/* Filter Drawer */}
602
+ {filterable && (
603
+ <DataTableFilterDrawer
604
+ table={table}
605
+ open={filterDrawerOpen}
606
+ onOpenChange={setFilterDrawerOpen}
607
+ />
608
+ )}
589
609
  </div>
590
610
  )
591
611
  }
@@ -736,3 +756,4 @@ TableRow.displayName = 'TableRow'
736
756
  export { type ColumnDef } from "@tanstack/react-table";
737
757
  export type { BulkAction } from './data-table-bulk-actions';
738
758
  export type { ExportFormat } from './data-table-export';
759
+ export type { FilterCondition, FilterOperator } from './data-table-filter-drawer';