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.cjs CHANGED
@@ -13,6 +13,10 @@ var SelectPrimitive = require('@radix-ui/react-select');
13
13
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
14
14
  var reactDayPicker = require('react-day-picker');
15
15
  var dateFns = require('date-fns');
16
+ var SwitchPrimitives = require('@radix-ui/react-switch');
17
+ var core = require('@dnd-kit/core');
18
+ var sortable = require('@dnd-kit/sortable');
19
+ var utilities = require('@dnd-kit/utilities');
16
20
 
17
21
  function _interopNamespace(e) {
18
22
  if (e && e.__esModule) return e;
@@ -37,6 +41,7 @@ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive)
37
41
  var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
38
42
  var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
39
43
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
44
+ var SwitchPrimitives__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitives);
40
45
 
41
46
  var ExampleComponent = ({ children, className = "" }) => {
42
47
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `cls_example_component ${className}`, children });
@@ -781,30 +786,27 @@ function MultiFilterDialog({
781
786
  ) }),
782
787
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
783
788
  /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
784
- /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
785
- /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No fields found." }),
786
- /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsxs(
787
- CommandItem,
788
- {
789
- value: field.value,
790
- onSelect: () => handleAddField(field.value),
791
- className: "cls_command_item",
792
- children: [
793
- /* @__PURE__ */ jsxRuntime.jsx(
794
- lucideReact.Check,
795
- {
796
- className: cn(
797
- "cls_check_icon mr-2 h-4 w-4",
798
- "opacity-0"
799
- )
800
- }
801
- ),
802
- field.label
803
- ]
804
- },
805
- field.value
806
- )) })
807
- ] })
789
+ /* @__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(
790
+ CommandItem,
791
+ {
792
+ value: field.label,
793
+ onSelect: () => handleAddField(field.value),
794
+ className: "cls_command_item",
795
+ children: [
796
+ /* @__PURE__ */ jsxRuntime.jsx(
797
+ lucideReact.Check,
798
+ {
799
+ className: cn(
800
+ "cls_check_icon mr-2 h-4 w-4",
801
+ "opacity-0"
802
+ )
803
+ }
804
+ ),
805
+ field.label
806
+ ]
807
+ },
808
+ field.value
809
+ )) }) })
808
810
  ] }) })
809
811
  ] }) }),
810
812
  filterFields.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_filter_fields_list space-y-2", children: filterFields.map((filterConfig) => {
@@ -857,8 +859,321 @@ function MultiFilterDialog({
857
859
  ] })
858
860
  ] });
859
861
  }
862
+ var Switch = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
863
+ SwitchPrimitives__namespace.Root,
864
+ {
865
+ className: cn(
866
+ "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",
867
+ className
868
+ ),
869
+ ...props,
870
+ ref,
871
+ children: /* @__PURE__ */ jsxRuntime.jsx(
872
+ SwitchPrimitives__namespace.Thumb,
873
+ {
874
+ className: cn(
875
+ "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"
876
+ )
877
+ }
878
+ )
879
+ }
880
+ ));
881
+ Switch.displayName = SwitchPrimitives__namespace.Root.displayName;
882
+ var Label2 = React6__namespace.forwardRef(
883
+ ({ className, ...props }, ref) => {
884
+ return /* @__PURE__ */ jsxRuntime.jsx(
885
+ "label",
886
+ {
887
+ ref,
888
+ className: cn(
889
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
890
+ className
891
+ ),
892
+ ...props
893
+ }
894
+ );
895
+ }
896
+ );
897
+ Label2.displayName = "Label";
898
+ function SortableSortFieldItem({
899
+ sortConfig,
900
+ fieldLabel,
901
+ onDirectionChange,
902
+ onDelete
903
+ }) {
904
+ const {
905
+ attributes,
906
+ listeners,
907
+ setNodeRef,
908
+ transform,
909
+ transition,
910
+ isDragging
911
+ } = sortable.useSortable({ id: sortConfig.field });
912
+ const style = {
913
+ transform: utilities.CSS.Transform.toString(transform),
914
+ transition,
915
+ opacity: isDragging ? 0.5 : 1
916
+ };
917
+ return /* @__PURE__ */ jsxRuntime.jsxs(
918
+ "div",
919
+ {
920
+ ref: setNodeRef,
921
+ style,
922
+ className: "cls_sortable_sort_field_item flex items-center gap-3 p-3 border rounded-md bg-card",
923
+ children: [
924
+ /* @__PURE__ */ jsxRuntime.jsx(
925
+ "div",
926
+ {
927
+ ...attributes,
928
+ ...listeners,
929
+ className: "cls_drag_handle cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground",
930
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "cls_drag_icon h-4 w-4" })
931
+ }
932
+ ),
933
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_field_label flex-1 text-sm font-medium", children: fieldLabel }),
934
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_direction_control flex items-center gap-2", children: [
935
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: `switch-${sortConfig.field}`, className: "cls_direction_label text-xs text-muted-foreground", children: sortConfig.direction === "asc" ? "Ascending" : "Descending" }),
936
+ /* @__PURE__ */ jsxRuntime.jsx(
937
+ Switch,
938
+ {
939
+ id: `switch-${sortConfig.field}`,
940
+ checked: sortConfig.direction === "desc",
941
+ onCheckedChange: (checked) => onDirectionChange(checked ? "desc" : "asc"),
942
+ "aria-label": `Toggle sort direction for ${fieldLabel}`
943
+ }
944
+ )
945
+ ] }),
946
+ /* @__PURE__ */ jsxRuntime.jsx(
947
+ Button,
948
+ {
949
+ variant: "ghost",
950
+ size: "sm",
951
+ onClick: onDelete,
952
+ className: "cls_delete_btn h-8 w-8 p-0 text-destructive hover:text-destructive",
953
+ "aria-label": `Remove ${fieldLabel} from sort`,
954
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "cls_delete_icon h-4 w-4" })
955
+ }
956
+ )
957
+ ]
958
+ }
959
+ );
960
+ }
961
+ function MultiSortDialog({
962
+ availableFields,
963
+ onSortChange,
964
+ initialSortFields = []
965
+ }) {
966
+ const [isOpen, setIsOpen] = React6.useState(false);
967
+ const [sortFields, setSortFields] = React6.useState(initialSortFields);
968
+ const [isComboboxOpen, setIsComboboxOpen] = React6.useState(false);
969
+ const sensors = core.useSensors(
970
+ core.useSensor(core.PointerSensor),
971
+ core.useSensor(core.KeyboardSensor, {
972
+ coordinateGetter: sortable.sortableKeyboardCoordinates
973
+ })
974
+ );
975
+ React6.useEffect(() => {
976
+ if (isOpen) {
977
+ setSortFields(initialSortFields);
978
+ }
979
+ }, [isOpen, initialSortFields]);
980
+ const handleAddField = (fieldValue) => {
981
+ if (sortFields.some((sf) => sf.field === fieldValue)) {
982
+ return;
983
+ }
984
+ const newField = {
985
+ field: fieldValue,
986
+ direction: "asc"
987
+ };
988
+ setSortFields([...sortFields, newField]);
989
+ setIsComboboxOpen(false);
990
+ };
991
+ const handleDeleteField = (fieldValue) => {
992
+ setSortFields(sortFields.filter((sf) => sf.field !== fieldValue));
993
+ };
994
+ const handleDirectionChange = (fieldValue, direction) => {
995
+ setSortFields(
996
+ sortFields.map(
997
+ (sf) => sf.field === fieldValue ? { ...sf, direction } : sf
998
+ )
999
+ );
1000
+ };
1001
+ const handleDragEnd = (event) => {
1002
+ const { active, over } = event;
1003
+ if (!over || active.id === over.id) {
1004
+ return;
1005
+ }
1006
+ const oldIndex = sortFields.findIndex((sf) => sf.field === active.id);
1007
+ const newIndex = sortFields.findIndex((sf) => sf.field === over.id);
1008
+ if (oldIndex !== -1 && newIndex !== -1) {
1009
+ setSortFields(sortable.arrayMove(sortFields, oldIndex, newIndex));
1010
+ }
1011
+ };
1012
+ const handleApply = () => {
1013
+ onSortChange([...sortFields]);
1014
+ setIsOpen(false);
1015
+ };
1016
+ const handleCancel = () => {
1017
+ setSortFields(initialSortFields);
1018
+ setIsOpen(false);
1019
+ };
1020
+ const handleClearAll = () => {
1021
+ setSortFields([]);
1022
+ };
1023
+ const availableFieldsToAdd = availableFields.filter(
1024
+ (af) => !sortFields.some((sf) => sf.field === af.value)
1025
+ );
1026
+ const getFieldLabel = (fieldValue) => {
1027
+ return availableFields.find((af) => af.value === fieldValue)?.label || fieldValue;
1028
+ };
1029
+ const hasActiveSorts = initialSortFields.length > 0;
1030
+ const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [
1031
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active Sorts:" }),
1032
+ initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_tooltip_item text-xs", children: [
1033
+ index + 1,
1034
+ ". ",
1035
+ getFieldLabel(sortConfig.field),
1036
+ " (",
1037
+ sortConfig.direction === "asc" ? "Asc" : "Desc",
1038
+ ")"
1039
+ ] }, sortConfig.field))
1040
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_sort_tooltip_content text-xs", children: "No active sorts" });
1041
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
1042
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
1043
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1044
+ Button,
1045
+ {
1046
+ variant: "outline",
1047
+ size: "sm",
1048
+ className: "cls_sort_button",
1049
+ "aria-label": "Open sort dialog",
1050
+ children: [
1051
+ /* @__PURE__ */ jsxRuntime.jsx(
1052
+ lucideReact.ArrowUpDown,
1053
+ {
1054
+ className: cn(
1055
+ "cls_sort_icon h-4 w-4 mr-2",
1056
+ hasActiveSorts && "text-blue-600"
1057
+ )
1058
+ }
1059
+ ),
1060
+ "Sort"
1061
+ ]
1062
+ }
1063
+ ) }) }),
1064
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: tooltipContent })
1065
+ ] }) }),
1066
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg", children: [
1067
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
1068
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Sort Images" }),
1069
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Add multiple fields to sort by and reorder them. Use the switch to toggle between ascending and descending." })
1070
+ ] }),
1071
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_sort_dialog_body space-y-4 py-4", children: [
1072
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1073
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1074
+ Button,
1075
+ {
1076
+ variant: "outline",
1077
+ role: "combobox",
1078
+ "aria-expanded": isComboboxOpen,
1079
+ className: "cls_add_field_combobox w-full justify-between",
1080
+ children: [
1081
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_combobox_content flex items-center", children: [
1082
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }),
1083
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add field" })
1084
+ ] }),
1085
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
1086
+ ]
1087
+ }
1088
+ ) }),
1089
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
1090
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
1091
+ /* @__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(
1092
+ CommandItem,
1093
+ {
1094
+ value: field.label,
1095
+ onSelect: () => handleAddField(field.value),
1096
+ className: "cls_command_item",
1097
+ children: [
1098
+ /* @__PURE__ */ jsxRuntime.jsx(
1099
+ lucideReact.Check,
1100
+ {
1101
+ className: cn(
1102
+ "cls_check_icon mr-2 h-4 w-4",
1103
+ "opacity-0"
1104
+ )
1105
+ }
1106
+ ),
1107
+ field.label
1108
+ ]
1109
+ },
1110
+ field.value
1111
+ )) }) })
1112
+ ] }) })
1113
+ ] }) }),
1114
+ sortFields.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_sort_fields_list space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1115
+ core.DndContext,
1116
+ {
1117
+ sensors,
1118
+ collisionDetection: core.closestCenter,
1119
+ onDragEnd: handleDragEnd,
1120
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1121
+ sortable.SortableContext,
1122
+ {
1123
+ items: sortFields.map((sf) => sf.field),
1124
+ strategy: sortable.verticalListSortingStrategy,
1125
+ children: sortFields.map((sortConfig) => /* @__PURE__ */ jsxRuntime.jsx(
1126
+ SortableSortFieldItem,
1127
+ {
1128
+ sortConfig,
1129
+ fieldLabel: getFieldLabel(sortConfig.field),
1130
+ onDirectionChange: (direction) => handleDirectionChange(sortConfig.field, direction),
1131
+ onDelete: () => handleDeleteField(sortConfig.field)
1132
+ },
1133
+ sortConfig.field
1134
+ ))
1135
+ }
1136
+ )
1137
+ }
1138
+ ) }) : /* @__PURE__ */ jsxRuntime.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.' })
1139
+ ] }),
1140
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
1141
+ sortFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1142
+ Button,
1143
+ {
1144
+ variant: "outline",
1145
+ onClick: handleClearAll,
1146
+ className: "cls_clear_all_btn",
1147
+ children: [
1148
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
1149
+ "Clear All"
1150
+ ]
1151
+ }
1152
+ ),
1153
+ /* @__PURE__ */ jsxRuntime.jsx(
1154
+ Button,
1155
+ {
1156
+ onClick: handleApply,
1157
+ className: "cls_apply_btn",
1158
+ children: "Apply"
1159
+ }
1160
+ ),
1161
+ /* @__PURE__ */ jsxRuntime.jsx(
1162
+ Button,
1163
+ {
1164
+ variant: "outline",
1165
+ onClick: handleCancel,
1166
+ className: "cls_cancel_btn",
1167
+ children: "Cancel"
1168
+ }
1169
+ )
1170
+ ] })
1171
+ ] })
1172
+ ] });
1173
+ }
860
1174
 
861
1175
  exports.ExampleComponent = ExampleComponent;
862
1176
  exports.MultiFilterDialog = MultiFilterDialog;
1177
+ exports.MultiSortDialog = MultiSortDialog;
863
1178
  //# sourceMappingURL=index.cjs.map
864
1179
  //# sourceMappingURL=index.cjs.map