hazo_ui 1.1.0 → 2.0.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.js CHANGED
@@ -6,12 +6,16 @@ import { cva } from 'class-variance-authority';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
8
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
- import { X, ChevronDown, ChevronUp, Check, Filter, Plus, ChevronsUpDown, Trash2, Calendar as Calendar$1, ChevronRight, ChevronLeft } from 'lucide-react';
9
+ import { X, ChevronDown, ChevronUp, Check, Filter, Plus, ChevronsUpDown, ArrowUpDown, Trash2, GripVertical, Calendar as Calendar$1, ChevronRight, ChevronLeft } from 'lucide-react';
10
10
  import * as PopoverPrimitive from '@radix-ui/react-popover';
11
11
  import * as SelectPrimitive from '@radix-ui/react-select';
12
12
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
13
13
  import { DayPicker } from 'react-day-picker';
14
14
  import { format } from 'date-fns';
15
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
16
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
17
+ import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
18
+ import { CSS } from '@dnd-kit/utilities';
15
19
 
16
20
  var ExampleComponent = ({ children, className = "" }) => {
17
21
  return /* @__PURE__ */ jsx("div", { className: `cls_example_component ${className}`, children });
@@ -756,30 +760,27 @@ function MultiFilterDialog({
756
760
  ) }),
757
761
  /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
758
762
  /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
759
- /* @__PURE__ */ jsxs(CommandList, { children: [
760
- /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }),
761
- /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
762
- CommandItem,
763
- {
764
- value: field.value,
765
- onSelect: () => handleAddField(field.value),
766
- className: "cls_command_item",
767
- children: [
768
- /* @__PURE__ */ jsx(
769
- Check,
770
- {
771
- className: cn(
772
- "cls_check_icon mr-2 h-4 w-4",
773
- "opacity-0"
774
- )
775
- }
776
- ),
777
- field.label
778
- ]
779
- },
780
- field.value
781
- )) })
782
- ] })
763
+ /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
764
+ CommandItem,
765
+ {
766
+ value: field.label,
767
+ onSelect: () => handleAddField(field.value),
768
+ className: "cls_command_item",
769
+ children: [
770
+ /* @__PURE__ */ jsx(
771
+ Check,
772
+ {
773
+ className: cn(
774
+ "cls_check_icon mr-2 h-4 w-4",
775
+ "opacity-0"
776
+ )
777
+ }
778
+ ),
779
+ field.label
780
+ ]
781
+ },
782
+ field.value
783
+ )) }) })
783
784
  ] }) })
784
785
  ] }) }),
785
786
  filterFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_filter_fields_list space-y-2", children: filterFields.map((filterConfig) => {
@@ -832,7 +833,319 @@ function MultiFilterDialog({
832
833
  ] })
833
834
  ] });
834
835
  }
836
+ var Switch = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
837
+ SwitchPrimitives.Root,
838
+ {
839
+ className: cn(
840
+ "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",
841
+ className
842
+ ),
843
+ ...props,
844
+ ref,
845
+ children: /* @__PURE__ */ jsx(
846
+ SwitchPrimitives.Thumb,
847
+ {
848
+ className: cn(
849
+ "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"
850
+ )
851
+ }
852
+ )
853
+ }
854
+ ));
855
+ Switch.displayName = SwitchPrimitives.Root.displayName;
856
+ var Label2 = React6.forwardRef(
857
+ ({ className, ...props }, ref) => {
858
+ return /* @__PURE__ */ jsx(
859
+ "label",
860
+ {
861
+ ref,
862
+ className: cn(
863
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
864
+ className
865
+ ),
866
+ ...props
867
+ }
868
+ );
869
+ }
870
+ );
871
+ Label2.displayName = "Label";
872
+ function SortableSortFieldItem({
873
+ sortConfig,
874
+ fieldLabel,
875
+ onDirectionChange,
876
+ onDelete
877
+ }) {
878
+ const {
879
+ attributes,
880
+ listeners,
881
+ setNodeRef,
882
+ transform,
883
+ transition,
884
+ isDragging
885
+ } = useSortable({ id: sortConfig.field });
886
+ const style = {
887
+ transform: CSS.Transform.toString(transform),
888
+ transition,
889
+ opacity: isDragging ? 0.5 : 1
890
+ };
891
+ return /* @__PURE__ */ jsxs(
892
+ "div",
893
+ {
894
+ ref: setNodeRef,
895
+ style,
896
+ className: "cls_sortable_sort_field_item flex items-center gap-3 p-3 border rounded-md bg-card",
897
+ children: [
898
+ /* @__PURE__ */ jsx(
899
+ "div",
900
+ {
901
+ ...attributes,
902
+ ...listeners,
903
+ className: "cls_drag_handle cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground",
904
+ children: /* @__PURE__ */ jsx(GripVertical, { className: "cls_drag_icon h-4 w-4" })
905
+ }
906
+ ),
907
+ /* @__PURE__ */ jsx("span", { className: "cls_field_label flex-1 text-sm font-medium", children: fieldLabel }),
908
+ /* @__PURE__ */ jsxs("div", { className: "cls_direction_control flex items-center gap-2", children: [
909
+ /* @__PURE__ */ jsx(Label2, { htmlFor: `switch-${sortConfig.field}`, className: "cls_direction_label text-xs text-muted-foreground", children: sortConfig.direction === "asc" ? "Ascending" : "Descending" }),
910
+ /* @__PURE__ */ jsx(
911
+ Switch,
912
+ {
913
+ id: `switch-${sortConfig.field}`,
914
+ checked: sortConfig.direction === "desc",
915
+ onCheckedChange: (checked) => onDirectionChange(checked ? "desc" : "asc"),
916
+ "aria-label": `Toggle sort direction for ${fieldLabel}`
917
+ }
918
+ )
919
+ ] }),
920
+ /* @__PURE__ */ jsx(
921
+ Button,
922
+ {
923
+ variant: "ghost",
924
+ size: "sm",
925
+ onClick: onDelete,
926
+ className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive",
927
+ "aria-label": `Remove ${fieldLabel} from sort`,
928
+ children: /* @__PURE__ */ jsx(Trash2, { className: "cls_delete_icon h-4 w-4" })
929
+ }
930
+ )
931
+ ]
932
+ }
933
+ );
934
+ }
935
+ function MultiSortDialog({
936
+ availableFields,
937
+ onSortChange,
938
+ initialSortFields = []
939
+ }) {
940
+ const [isOpen, setIsOpen] = useState(false);
941
+ const [sortFields, setSortFields] = useState(initialSortFields);
942
+ const [isComboboxOpen, setIsComboboxOpen] = useState(false);
943
+ const sensors = useSensors(
944
+ useSensor(PointerSensor),
945
+ useSensor(KeyboardSensor, {
946
+ coordinateGetter: sortableKeyboardCoordinates
947
+ })
948
+ );
949
+ useEffect(() => {
950
+ if (isOpen) {
951
+ setSortFields(initialSortFields);
952
+ }
953
+ }, [isOpen, initialSortFields]);
954
+ const handleAddField = (fieldValue) => {
955
+ if (sortFields.some((sf) => sf.field === fieldValue)) {
956
+ return;
957
+ }
958
+ const newField = {
959
+ field: fieldValue,
960
+ direction: "asc"
961
+ };
962
+ setSortFields([...sortFields, newField]);
963
+ setIsComboboxOpen(false);
964
+ };
965
+ const handleDeleteField = (fieldValue) => {
966
+ setSortFields(sortFields.filter((sf) => sf.field !== fieldValue));
967
+ };
968
+ const handleDirectionChange = (fieldValue, direction) => {
969
+ setSortFields(
970
+ sortFields.map(
971
+ (sf) => sf.field === fieldValue ? { ...sf, direction } : sf
972
+ )
973
+ );
974
+ };
975
+ const handleDragEnd = (event) => {
976
+ const { active, over } = event;
977
+ if (!over || active.id === over.id) {
978
+ return;
979
+ }
980
+ const oldIndex = sortFields.findIndex((sf) => sf.field === active.id);
981
+ const newIndex = sortFields.findIndex((sf) => sf.field === over.id);
982
+ if (oldIndex !== -1 && newIndex !== -1) {
983
+ setSortFields(arrayMove(sortFields, oldIndex, newIndex));
984
+ }
985
+ };
986
+ const handleApply = () => {
987
+ onSortChange([...sortFields]);
988
+ setIsOpen(false);
989
+ };
990
+ const handleCancel = () => {
991
+ setSortFields(initialSortFields);
992
+ setIsOpen(false);
993
+ };
994
+ const handleClearAll = () => {
995
+ setSortFields([]);
996
+ };
997
+ const availableFieldsToAdd = availableFields.filter(
998
+ (af) => !sortFields.some((sf) => sf.field === af.value)
999
+ );
1000
+ const getFieldLabel = (fieldValue) => {
1001
+ return availableFields.find((af) => af.value === fieldValue)?.label || fieldValue;
1002
+ };
1003
+ const hasActiveSorts = initialSortFields.length > 0;
1004
+ const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [
1005
+ /* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Sorts:" }),
1006
+ initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxs("div", { className: "cls_tooltip_item text-xs", children: [
1007
+ index + 1,
1008
+ ". ",
1009
+ getFieldLabel(sortConfig.field),
1010
+ " (",
1011
+ sortConfig.direction === "asc" ? "Asc" : "Desc",
1012
+ ")"
1013
+ ] }, sortConfig.field))
1014
+ ] }) : /* @__PURE__ */ jsx("div", { className: "cls_sort_tooltip_content text-xs", children: "No active sorts" });
1015
+ return /* @__PURE__ */ jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
1016
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
1017
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1018
+ Button,
1019
+ {
1020
+ variant: "outline",
1021
+ size: "sm",
1022
+ className: "cls_sort_button",
1023
+ "aria-label": "Open sort dialog",
1024
+ children: [
1025
+ /* @__PURE__ */ jsx(
1026
+ ArrowUpDown,
1027
+ {
1028
+ className: cn(
1029
+ "cls_sort_icon h-4 w-4 mr-2",
1030
+ hasActiveSorts && "text-blue-600"
1031
+ )
1032
+ }
1033
+ ),
1034
+ "Sort"
1035
+ ]
1036
+ }
1037
+ ) }) }),
1038
+ /* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
1039
+ ] }) }),
1040
+ /* @__PURE__ */ jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg", children: [
1041
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1042
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Sort Images" }),
1043
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Add multiple fields to sort by and reorder them. Use the switch to toggle between ascending and descending." })
1044
+ ] }),
1045
+ /* @__PURE__ */ jsxs("div", { className: "cls_sort_dialog_body space-y-4 py-4", children: [
1046
+ /* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1047
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1048
+ Button,
1049
+ {
1050
+ variant: "outline",
1051
+ role: "combobox",
1052
+ "aria-expanded": isComboboxOpen,
1053
+ className: "cls_add_field_combobox w-full justify-between",
1054
+ children: [
1055
+ /* @__PURE__ */ jsxs("div", { className: "cls_combobox_content flex items-center", children: [
1056
+ /* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }),
1057
+ /* @__PURE__ */ jsx("span", { children: "Add field" })
1058
+ ] }),
1059
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
1060
+ ]
1061
+ }
1062
+ ) }),
1063
+ /* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
1064
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
1065
+ /* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
1066
+ CommandItem,
1067
+ {
1068
+ value: field.label,
1069
+ onSelect: () => handleAddField(field.value),
1070
+ className: "cls_command_item",
1071
+ children: [
1072
+ /* @__PURE__ */ jsx(
1073
+ Check,
1074
+ {
1075
+ className: cn(
1076
+ "cls_check_icon mr-2 h-4 w-4",
1077
+ "opacity-0"
1078
+ )
1079
+ }
1080
+ ),
1081
+ field.label
1082
+ ]
1083
+ },
1084
+ field.value
1085
+ )) }) })
1086
+ ] }) })
1087
+ ] }) }),
1088
+ sortFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_sort_fields_list space-y-2", children: /* @__PURE__ */ jsx(
1089
+ DndContext,
1090
+ {
1091
+ sensors,
1092
+ collisionDetection: closestCenter,
1093
+ onDragEnd: handleDragEnd,
1094
+ children: /* @__PURE__ */ jsx(
1095
+ SortableContext,
1096
+ {
1097
+ items: sortFields.map((sf) => sf.field),
1098
+ strategy: verticalListSortingStrategy,
1099
+ children: sortFields.map((sortConfig) => /* @__PURE__ */ jsx(
1100
+ SortableSortFieldItem,
1101
+ {
1102
+ sortConfig,
1103
+ fieldLabel: getFieldLabel(sortConfig.field),
1104
+ onDirectionChange: (direction) => handleDirectionChange(sortConfig.field, direction),
1105
+ onDelete: () => handleDeleteField(sortConfig.field)
1106
+ },
1107
+ sortConfig.field
1108
+ ))
1109
+ }
1110
+ )
1111
+ }
1112
+ ) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_sort_fields text-center py-8 text-sm text-muted-foreground", children: 'No sort fields added. Click "Add field" to add sorting criteria.' })
1113
+ ] }),
1114
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
1115
+ sortFields.length > 0 && /* @__PURE__ */ jsxs(
1116
+ Button,
1117
+ {
1118
+ variant: "outline",
1119
+ onClick: handleClearAll,
1120
+ className: "cls_clear_all_btn",
1121
+ children: [
1122
+ /* @__PURE__ */ jsx(Trash2, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
1123
+ "Clear All"
1124
+ ]
1125
+ }
1126
+ ),
1127
+ /* @__PURE__ */ jsx(
1128
+ Button,
1129
+ {
1130
+ onClick: handleApply,
1131
+ className: "cls_apply_btn",
1132
+ children: "Apply"
1133
+ }
1134
+ ),
1135
+ /* @__PURE__ */ jsx(
1136
+ Button,
1137
+ {
1138
+ variant: "outline",
1139
+ onClick: handleCancel,
1140
+ className: "cls_cancel_btn",
1141
+ children: "Cancel"
1142
+ }
1143
+ )
1144
+ ] })
1145
+ ] })
1146
+ ] });
1147
+ }
835
1148
 
836
- export { ExampleComponent, MultiFilterDialog };
1149
+ export { ExampleComponent, MultiFilterDialog, MultiSortDialog };
837
1150
  //# sourceMappingURL=index.js.map
838
1151
  //# sourceMappingURL=index.js.map