@nccirtu/tablefy 0.6.3 → 0.6.4

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.
Files changed (35) hide show
  1. package/README.md +34 -0
  2. package/cli/templates/tablefy/data-table-empty.tsx +0 -1
  3. package/cli/templates/tablefy/data-table-header.tsx +0 -1
  4. package/cli/templates/tablefy/data-table-pagination.tsx +0 -1
  5. package/dist/columns/actions-column.d.ts +3 -3
  6. package/dist/columns/base-column.d.ts +2 -2
  7. package/dist/columns/checkbox-column.d.ts +1 -1
  8. package/dist/columns/columns/actions-column.d.ts +3 -3
  9. package/dist/columns/columns/base-column.d.ts +2 -2
  10. package/dist/columns/columns/checkbox-column.d.ts +1 -1
  11. package/dist/columns/columns/date-column.d.ts +5 -5
  12. package/dist/columns/columns/icon-column.d.ts +7 -7
  13. package/dist/columns/columns/image-column.d.ts +7 -7
  14. package/dist/columns/columns/link-column.d.ts +6 -6
  15. package/dist/columns/columns/number-column.d.ts +3 -3
  16. package/dist/columns/columns/progress-column.d.ts +7 -7
  17. package/dist/columns/columns/text-column.d.ts +3 -3
  18. package/dist/columns/columns/types.d.ts +5 -5
  19. package/dist/columns/date-column.d.ts +5 -5
  20. package/dist/columns/icon-column.d.ts +7 -7
  21. package/dist/columns/image-column.d.ts +7 -7
  22. package/dist/columns/index.esm.js +189 -167
  23. package/dist/columns/index.esm.js.map +1 -1
  24. package/dist/columns/index.js +189 -167
  25. package/dist/columns/index.js.map +1 -1
  26. package/dist/columns/link-column.d.ts +6 -6
  27. package/dist/columns/number-column.d.ts +3 -3
  28. package/dist/columns/progress-column.d.ts +7 -7
  29. package/dist/columns/text-column.d.ts +3 -3
  30. package/dist/columns/types.d.ts +5 -5
  31. package/dist/index.esm.js +189 -167
  32. package/dist/index.esm.js.map +1 -1
  33. package/dist/index.js +189 -167
  34. package/dist/index.js.map +1 -1
  35. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -443,7 +443,7 @@ class BaseColumn {
443
443
  sortable: false,
444
444
  searchable: false,
445
445
  hidden: false,
446
- align: 'left',
446
+ align: "left",
447
447
  };
448
448
  }
449
449
  // Fluent API Methods
@@ -464,15 +464,15 @@ class BaseColumn {
464
464
  return this;
465
465
  }
466
466
  alignLeft() {
467
- this.config.align = 'left';
467
+ this.config.align = "left";
468
468
  return this;
469
469
  }
470
470
  alignCenter() {
471
- this.config.align = 'center';
471
+ this.config.align = "center";
472
472
  return this;
473
473
  }
474
474
  alignRight() {
475
- this.config.align = 'right';
475
+ this.config.align = "right";
476
476
  return this;
477
477
  }
478
478
  width(width) {
@@ -493,11 +493,11 @@ class BaseColumn {
493
493
  }
494
494
  // Hilfsfunktion für Alignment-Klassen
495
495
  getAlignmentClass() {
496
- const baseClasses = 'text-sm text-muted-foreground';
496
+ const baseClasses = "text-sm text-muted-foreground";
497
497
  switch (this.config.align) {
498
- case 'center':
498
+ case "center":
499
499
  return `${baseClasses} text-center`;
500
- case 'right':
500
+ case "right":
501
501
  return `${baseClasses} text-right`;
502
502
  default:
503
503
  return `${baseClasses} text-left`;
@@ -698,8 +698,9 @@ class CheckboxColumn {
698
698
  }
699
699
  build() {
700
700
  return {
701
- id: 'select',
702
- header: ({ table }) => (jsx(Checkbox, { checked: table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'), onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value), "aria-label": "Alle ausw\u00E4hlen" })),
701
+ id: "select",
702
+ header: ({ table }) => (jsx(Checkbox, { checked: table.getIsAllPageRowsSelected() ||
703
+ (table.getIsSomePageRowsSelected() && "indeterminate"), onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value), "aria-label": "Alle ausw\u00E4hlen" })),
703
704
  cell: ({ row }) => (jsx(Checkbox, { checked: row.getIsSelected(), onCheckedChange: (value) => row.toggleSelected(!!value), "aria-label": "Zeile ausw\u00E4hlen" })),
704
705
  enableSorting: false,
705
706
  enableHiding: false,
@@ -710,8 +711,8 @@ class CheckboxColumn {
710
711
  class DateColumn extends BaseColumn {
711
712
  constructor(accessor) {
712
713
  super(accessor);
713
- this.config.format = 'short';
714
- this.config.locale = 'de-DE';
714
+ this.config.format = "short";
715
+ this.config.locale = "de-DE";
715
716
  this.config.showIcon = false;
716
717
  }
717
718
  static make(accessor) {
@@ -731,52 +732,62 @@ class DateColumn extends BaseColumn {
731
732
  }
732
733
  // Shortcuts
733
734
  short() {
734
- return this.format('short');
735
+ return this.format("short");
735
736
  }
736
737
  long() {
737
- return this.format('long');
738
+ return this.format("long");
738
739
  }
739
740
  relative() {
740
- return this.format('relative');
741
+ return this.format("relative");
741
742
  }
742
743
  time() {
743
- return this.format('time');
744
+ return this.format("time");
744
745
  }
745
746
  datetime() {
746
- return this.format('datetime');
747
+ return this.format("datetime");
747
748
  }
748
749
  formatDate(date, format, locale) {
749
- if (format === 'relative') {
750
+ if (format === "relative") {
750
751
  return this.getRelativeTime(date);
751
752
  }
752
753
  const formatOptions = {
753
- short: { day: '2-digit', month: '2-digit', year: 'numeric' },
754
- long: { day: 'numeric', month: 'long', year: 'numeric' },
755
- time: { hour: '2-digit', minute: '2-digit' },
756
- datetime: { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' },
754
+ short: { day: "2-digit", month: "2-digit", year: "numeric" },
755
+ long: { day: "numeric", month: "long", year: "numeric" },
756
+ time: { hour: "2-digit", minute: "2-digit" },
757
+ datetime: {
758
+ day: "2-digit",
759
+ month: "2-digit",
760
+ year: "numeric",
761
+ hour: "2-digit",
762
+ minute: "2-digit",
763
+ },
764
+ };
765
+ const options = formatOptions[format] || {
766
+ day: "2-digit",
767
+ month: "2-digit",
768
+ year: "numeric",
757
769
  };
758
- const options = formatOptions[format] || { day: '2-digit', month: '2-digit', year: 'numeric' };
759
770
  return new Intl.DateTimeFormat(locale, options).format(date);
760
771
  }
761
772
  getRelativeTime(date) {
762
773
  const now = new Date();
763
774
  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
764
775
  const intervals = [
765
- { label: 'Jahr', seconds: 31536000 },
766
- { label: 'Monat', seconds: 2592000 },
767
- { label: 'Woche', seconds: 604800 },
768
- { label: 'Tag', seconds: 86400 },
769
- { label: 'Stunde', seconds: 3600 },
770
- { label: 'Minute', seconds: 60 },
776
+ { label: "Jahr", seconds: 31536000 },
777
+ { label: "Monat", seconds: 2592000 },
778
+ { label: "Woche", seconds: 604800 },
779
+ { label: "Tag", seconds: 86400 },
780
+ { label: "Stunde", seconds: 3600 },
781
+ { label: "Minute", seconds: 60 },
771
782
  ];
772
783
  for (const interval of intervals) {
773
784
  const count = Math.floor(diffInSeconds / interval.seconds);
774
785
  if (count >= 1) {
775
- const plural = count > 1 ? (interval.label === 'Monat' ? 'e' : 'en') : '';
786
+ const plural = count > 1 ? (interval.label === "Monat" ? "e" : "en") : "";
776
787
  return `vor ${count} ${interval.label}${plural}`;
777
788
  }
778
789
  }
779
- return 'gerade eben';
790
+ return "gerade eben";
780
791
  }
781
792
  build() {
782
793
  const config = this.config;
@@ -786,9 +797,9 @@ class DateColumn extends BaseColumn {
786
797
  header: ({ column }) => {
787
798
  const displayLabel = label || String(accessor);
788
799
  if (!sortable) {
789
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
800
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
790
801
  }
791
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
802
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
792
803
  },
793
804
  cell: ({ getValue }) => {
794
805
  const value = getValue();
@@ -797,10 +808,10 @@ class DateColumn extends BaseColumn {
797
808
  }
798
809
  const date = value instanceof Date ? value : new Date(value);
799
810
  if (isNaN(date.getTime())) {
800
- return jsx("span", { className: "text-muted-foreground", children: "Ung\u00FCltiges Datum" });
811
+ return (jsx("span", { className: "text-muted-foreground", children: "Ung\u00FCltiges Datum" }));
801
812
  }
802
- const formatted = this.formatDate(date, format || 'short', locale || 'de-DE');
803
- return (jsxs("span", { className: cn('flex items-center gap-2', this.getAlignmentClass(), this.config.cellClassName), children: [showIcon && jsx(Calendar, { className: "text-muted-foreground h-4 w-4" }), formatted] }));
813
+ const formatted = this.formatDate(date, format || "short", locale || "de-DE");
814
+ return (jsxs("span", { className: cn("flex items-center gap-2", this.getAlignmentClass(), this.config.cellClassName), children: [showIcon && jsx(Calendar, { className: "text-muted-foreground h-4 w-4" }), formatted] }));
804
815
  },
805
816
  };
806
817
  }
@@ -823,11 +834,11 @@ class IconColumn extends BaseColumn {
823
834
  super(accessor);
824
835
  const config = this.config;
825
836
  config.states = {};
826
- config.size = 'md';
837
+ config.size = "md";
827
838
  config.showLabel = false;
828
839
  config.showTooltip = true;
829
840
  config.withBackground = false;
830
- config.align = 'center';
841
+ config.align = "center";
831
842
  }
832
843
  static make(accessor) {
833
844
  return new IconColumn(accessor);
@@ -879,14 +890,14 @@ class IconColumn extends BaseColumn {
879
890
  c.states = {
880
891
  true: {
881
892
  icon: config?.trueIcon || this.createCheckIcon(),
882
- label: config?.trueLabel || 'Ja',
883
- color: config?.trueColor || 'text-green-500',
893
+ label: config?.trueLabel || "Ja",
894
+ color: config?.trueColor || "text-green-500",
884
895
  bgColor: config?.trueBgColor,
885
896
  },
886
897
  false: {
887
898
  icon: config?.falseIcon || this.createXIcon(),
888
- label: config?.falseLabel || 'Nein',
889
- color: config?.falseColor || 'text-red-500',
899
+ label: config?.falseLabel || "Nein",
900
+ color: config?.falseColor || "text-red-500",
890
901
  bgColor: config?.falseBgColor,
891
902
  },
892
903
  };
@@ -897,15 +908,15 @@ class IconColumn extends BaseColumn {
897
908
  return this.states({
898
909
  active: {
899
910
  icon: this.createCircleIcon(),
900
- label: 'Aktiv',
901
- color: 'text-green-500',
902
- tooltip: 'Status: Aktiv',
911
+ label: "Aktiv",
912
+ color: "text-green-500",
913
+ tooltip: "Status: Aktiv",
903
914
  },
904
915
  inactive: {
905
916
  icon: this.createCircleIcon(),
906
- label: 'Inaktiv',
907
- color: 'text-gray-400',
908
- tooltip: 'Status: Inaktiv',
917
+ label: "Inaktiv",
918
+ color: "text-gray-400",
919
+ tooltip: "Status: Inaktiv",
909
920
  },
910
921
  });
911
922
  }
@@ -914,27 +925,27 @@ class IconColumn extends BaseColumn {
914
925
  return this.states({
915
926
  online: {
916
927
  icon: this.createCircleIcon(),
917
- label: 'Online',
918
- color: 'text-green-500',
919
- bgColor: 'bg-green-500',
928
+ label: "Online",
929
+ color: "text-green-500",
930
+ bgColor: "bg-green-500",
920
931
  },
921
932
  offline: {
922
933
  icon: this.createCircleIcon(),
923
- label: 'Offline',
924
- color: 'text-gray-400',
925
- bgColor: 'bg-gray-400',
934
+ label: "Offline",
935
+ color: "text-gray-400",
936
+ bgColor: "bg-gray-400",
926
937
  },
927
938
  away: {
928
939
  icon: this.createCircleIcon(),
929
- label: 'Abwesend',
930
- color: 'text-yellow-500',
931
- bgColor: 'bg-yellow-500',
940
+ label: "Abwesend",
941
+ color: "text-yellow-500",
942
+ bgColor: "bg-yellow-500",
932
943
  },
933
944
  busy: {
934
945
  icon: this.createCircleIcon(),
935
- label: 'Beschäftigt',
936
- color: 'text-red-500',
937
- bgColor: 'bg-red-500',
946
+ label: "Beschäftigt",
947
+ color: "text-red-500",
948
+ bgColor: "bg-red-500",
938
949
  },
939
950
  });
940
951
  }
@@ -943,23 +954,23 @@ class IconColumn extends BaseColumn {
943
954
  return this.states({
944
955
  low: {
945
956
  icon: this.createArrowDownIcon(),
946
- label: 'Niedrig',
947
- color: 'text-blue-500',
957
+ label: "Niedrig",
958
+ color: "text-blue-500",
948
959
  },
949
960
  medium: {
950
961
  icon: this.createMinusIcon(),
951
- label: 'Mittel',
952
- color: 'text-yellow-500',
962
+ label: "Mittel",
963
+ color: "text-yellow-500",
953
964
  },
954
965
  high: {
955
966
  icon: this.createArrowUpIcon(),
956
- label: 'Hoch',
957
- color: 'text-orange-500',
967
+ label: "Hoch",
968
+ color: "text-orange-500",
958
969
  },
959
970
  critical: {
960
971
  icon: this.createAlertIcon(),
961
- label: 'Kritisch',
962
- color: 'text-red-500',
972
+ label: "Kritisch",
973
+ color: "text-red-500",
963
974
  },
964
975
  });
965
976
  }
@@ -968,18 +979,18 @@ class IconColumn extends BaseColumn {
968
979
  return this.states({
969
980
  verified: {
970
981
  icon: this.createShieldCheckIcon(),
971
- label: 'Verifiziert',
972
- color: 'text-green-500',
982
+ label: "Verifiziert",
983
+ color: "text-green-500",
973
984
  },
974
985
  pending: {
975
986
  icon: this.createClockIcon(),
976
- label: 'Ausstehend',
977
- color: 'text-yellow-500',
987
+ label: "Ausstehend",
988
+ color: "text-yellow-500",
978
989
  },
979
990
  rejected: {
980
991
  icon: this.createShieldXIcon(),
981
- label: 'Abgelehnt',
982
- color: 'text-red-500',
992
+ label: "Abgelehnt",
993
+ color: "text-red-500",
983
994
  },
984
995
  });
985
996
  }
@@ -1016,33 +1027,33 @@ class IconColumn extends BaseColumn {
1016
1027
  }
1017
1028
  build() {
1018
1029
  const config = this.config;
1019
- const { accessor, label, sortable, states, size, showLabel, showTooltip, withBackground, defaultIcon, defaultLabel } = config;
1030
+ const { accessor, label, sortable, states, size, showLabel, showTooltip, withBackground, defaultIcon, defaultLabel, } = config;
1020
1031
  const sizeClasses = {
1021
- xs: 'h-3 w-3',
1022
- sm: 'h-4 w-4',
1023
- md: 'h-5 w-5',
1024
- lg: 'h-6 w-6',
1032
+ xs: "h-3 w-3",
1033
+ sm: "h-4 w-4",
1034
+ md: "h-5 w-5",
1035
+ lg: "h-6 w-6",
1025
1036
  };
1026
1037
  const bgSizeClasses = {
1027
- xs: 'h-5 w-5',
1028
- sm: 'h-6 w-6',
1029
- md: 'h-8 w-8',
1030
- lg: 'h-10 w-10',
1038
+ xs: "h-5 w-5",
1039
+ sm: "h-6 w-6",
1040
+ md: "h-8 w-8",
1041
+ lg: "h-10 w-10",
1031
1042
  };
1032
1043
  const iconInBgSizeClasses = {
1033
- xs: 'h-2.5 w-2.5',
1034
- sm: 'h-3 w-3',
1035
- md: 'h-4 w-4',
1036
- lg: 'h-5 w-5',
1044
+ xs: "h-2.5 w-2.5",
1045
+ sm: "h-3 w-3",
1046
+ md: "h-4 w-4",
1047
+ lg: "h-5 w-5",
1037
1048
  };
1038
1049
  return {
1039
1050
  accessorKey: accessor,
1040
1051
  header: ({ column }) => {
1041
1052
  const displayLabel = label || String(accessor);
1042
1053
  if (!sortable) {
1043
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1054
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1044
1055
  }
1045
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1056
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1046
1057
  },
1047
1058
  cell: ({ getValue }) => {
1048
1059
  const value = String(getValue());
@@ -1050,16 +1061,16 @@ class IconColumn extends BaseColumn {
1050
1061
  // Default verwenden wenn State nicht gefunden
1051
1062
  const icon = stateConfig?.icon || defaultIcon;
1052
1063
  const stateLabel = stateConfig?.label || defaultLabel || value;
1053
- const color = stateConfig?.color || 'text-muted-foreground';
1064
+ const color = stateConfig?.color || "text-muted-foreground";
1054
1065
  const bgColor = stateConfig?.bgColor;
1055
1066
  const tooltip = stateConfig?.tooltip || stateLabel;
1056
1067
  if (!icon) {
1057
1068
  return jsx("span", { className: "text-muted-foreground", children: "\u2014" });
1058
1069
  }
1059
1070
  // Icon als Element rendern (falls LucideIcon übergeben wurde)
1060
- const IconElement = typeof icon === 'function' ? icon : null;
1061
- const renderedIcon = IconElement ? jsx(IconElement, { className: "h-full w-full" }) : icon;
1062
- const iconElement = (jsxs("div", { className: cn('flex items-center gap-2', this.getAlignmentClass(), this.config.cellClassName), children: [withBackground ? (jsx("div", { className: cn('inline-flex items-center justify-center rounded-md', bgSizeClasses[size || 'md'], bgColor || 'bg-blue-50'), children: jsx("div", { className: cn(iconInBgSizeClasses[size || 'md'], color), children: renderedIcon }) })) : (jsx("div", { className: cn(sizeClasses[size || 'md'], color), children: renderedIcon })), showLabel && jsx("span", { className: cn('text-sm', color), children: stateLabel })] }));
1071
+ const IconElement = typeof icon === "function" ? icon : null;
1072
+ const renderedIcon = IconElement ? (jsx(IconElement, { className: "h-full w-full" })) : icon;
1073
+ const iconElement = (jsxs("div", { className: cn("flex items-center gap-2", this.getAlignmentClass(), this.config.cellClassName), children: [withBackground ? (jsx("div", { className: cn("inline-flex items-center justify-center rounded-md", bgSizeClasses[size || "md"], bgColor || "bg-blue-50"), children: jsx("div", { className: cn(iconInBgSizeClasses[size || "md"], color), children: renderedIcon }) })) : (jsx("div", { className: cn(sizeClasses[size || "md"], color), children: renderedIcon })), showLabel && (jsx("span", { className: cn("text-sm", color), children: stateLabel }))] }));
1063
1074
  if (showTooltip) {
1064
1075
  return (jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: iconElement }), jsx(TooltipContent, { children: jsx("p", { children: tooltip }) })] }) }));
1065
1076
  }
@@ -1072,8 +1083,8 @@ class IconColumn extends BaseColumn {
1072
1083
  class ImageColumn extends BaseColumn {
1073
1084
  constructor(accessor) {
1074
1085
  super(accessor);
1075
- this.config.size = 'md';
1076
- this.config.rounded = 'md';
1086
+ this.config.size = "md";
1087
+ this.config.rounded = "md";
1077
1088
  }
1078
1089
  static make(accessor) {
1079
1090
  return new ImageColumn(accessor);
@@ -1087,10 +1098,10 @@ class ImageColumn extends BaseColumn {
1087
1098
  return this;
1088
1099
  }
1089
1100
  circular() {
1090
- return this.rounded('full');
1101
+ return this.rounded("full");
1091
1102
  }
1092
1103
  square() {
1093
- return this.rounded('none');
1104
+ return this.rounded("none");
1094
1105
  }
1095
1106
  fallback(url) {
1096
1107
  this.config.fallback = url;
@@ -1104,24 +1115,24 @@ class ImageColumn extends BaseColumn {
1104
1115
  const config = this.config;
1105
1116
  const { accessor, label, size, rounded, fallback, alt } = config;
1106
1117
  const sizeClasses = {
1107
- sm: 'h-8 w-8',
1108
- md: 'h-10 w-10',
1109
- lg: 'h-12 w-12',
1118
+ sm: "h-8 w-8",
1119
+ md: "h-10 w-10",
1120
+ lg: "h-12 w-12",
1110
1121
  };
1111
1122
  const roundedClasses = {
1112
- none: 'rounded-none',
1113
- sm: 'rounded-sm',
1114
- md: 'rounded-md',
1115
- lg: 'rounded-lg',
1116
- full: 'rounded-full',
1123
+ none: "rounded-none",
1124
+ sm: "rounded-sm",
1125
+ md: "rounded-md",
1126
+ lg: "rounded-lg",
1127
+ full: "rounded-full",
1117
1128
  };
1118
1129
  return {
1119
1130
  accessorKey: accessor,
1120
- header: () => jsx("span", { className: cn('text-muted-foreground font-medium', this.config.headerClassName), children: label || '' }),
1131
+ header: () => (jsx("span", { className: cn("text-muted-foreground font-medium", this.config.headerClassName), children: label || "" })),
1121
1132
  cell: ({ getValue, row }) => {
1122
1133
  const src = getValue();
1123
- const altText = alt ? alt(row.original) : 'Bild';
1124
- return (jsx("img", { src: src || fallback || '/placeholder.png', alt: altText, className: cn('object-cover', sizeClasses[size || 'md'], roundedClasses[rounded || 'md'], this.config.cellClassName), onError: (e) => {
1134
+ const altText = alt ? alt(row.original) : "Bild";
1135
+ return (jsx("img", { src: src || fallback || "/placeholder.png", alt: altText, className: cn("object-cover", sizeClasses[size || "md"], roundedClasses[rounded || "md"], this.config.cellClassName), onError: (e) => {
1125
1136
  if (fallback) {
1126
1137
  e.target.src = fallback;
1127
1138
  }
@@ -1149,7 +1160,7 @@ class LinkColumn extends BaseColumn {
1149
1160
  const config = this.config;
1150
1161
  config.external = false;
1151
1162
  config.showExternalIcon = false;
1152
- config.underline = 'hover';
1163
+ config.underline = "hover";
1153
1164
  config.openInNewTab = false;
1154
1165
  }
1155
1166
  static make(accessor) {
@@ -1200,20 +1211,20 @@ class LinkColumn extends BaseColumn {
1200
1211
  }
1201
1212
  build() {
1202
1213
  const config = this.config;
1203
- const { accessor, label, sortable, href, icon, showExternalIcon, underline, openInNewTab, onClick } = config;
1214
+ const { accessor, label, sortable, href, icon, showExternalIcon, underline, openInNewTab, onClick, } = config;
1204
1215
  const underlineClasses = {
1205
- always: 'underline',
1206
- hover: 'hover:underline',
1207
- never: 'no-underline',
1216
+ always: "underline",
1217
+ hover: "hover:underline",
1218
+ never: "no-underline",
1208
1219
  };
1209
1220
  return {
1210
1221
  accessorKey: accessor,
1211
1222
  header: ({ column }) => {
1212
1223
  const displayLabel = label || String(accessor);
1213
1224
  if (!sortable) {
1214
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1225
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1215
1226
  }
1216
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1227
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1217
1228
  },
1218
1229
  cell: ({ getValue, row }) => {
1219
1230
  const value = getValue();
@@ -1221,7 +1232,7 @@ class LinkColumn extends BaseColumn {
1221
1232
  return jsx("span", { className: "text-muted-foreground", children: "\u2014" });
1222
1233
  }
1223
1234
  // URL berechnen
1224
- const url = typeof href === 'function' ? href(row.original) : href || value;
1235
+ const url = typeof href === "function" ? href(row.original) : href || value;
1225
1236
  const handleClick = (e) => {
1226
1237
  if (onClick) {
1227
1238
  e.preventDefault();
@@ -1229,8 +1240,12 @@ class LinkColumn extends BaseColumn {
1229
1240
  }
1230
1241
  };
1231
1242
  // Alignment ohne text-muted-foreground für Links
1232
- const alignmentClass = this.config.align === 'center' ? 'text-center' : this.config.align === 'right' ? 'text-right' : 'text-left';
1233
- return (jsxs("a", { href: url, target: openInNewTab ? '_blank' : undefined, rel: openInNewTab ? 'noopener noreferrer' : undefined, onClick: onClick ? handleClick : undefined, className: cn('inline-flex items-center gap-1.5 text-sm text-blue-500', underlineClasses[underline || 'hover'], 'hover:text-blue-500/80', alignmentClass, this.config.cellClassName), children: [icon, jsx("span", { children: value }), showExternalIcon && jsx(ExternalLink, { className: "text-muted-foreground h-3 w-3" })] }));
1243
+ const alignmentClass = this.config.align === "center"
1244
+ ? "text-center"
1245
+ : this.config.align === "right"
1246
+ ? "text-right"
1247
+ : "text-left";
1248
+ return (jsxs("a", { href: url, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noopener noreferrer" : undefined, onClick: onClick ? handleClick : undefined, className: cn("inline-flex items-center gap-1.5 text-sm text-blue-500", underlineClasses[underline || "hover"], "hover:text-blue-500/80", alignmentClass, this.config.cellClassName), children: [icon, jsx("span", { children: value }), showExternalIcon && (jsx(ExternalLink, { className: "text-muted-foreground h-3 w-3" }))] }));
1234
1249
  },
1235
1250
  };
1236
1251
  }
@@ -1239,9 +1254,9 @@ class LinkColumn extends BaseColumn {
1239
1254
  class NumberColumn extends BaseColumn {
1240
1255
  constructor(accessor) {
1241
1256
  super(accessor);
1242
- this.config.align = 'right'; // Zahlen standardmäßig rechtsbündig
1257
+ this.config.align = "right"; // Zahlen standardmäßig rechtsbündig
1243
1258
  this.config.decimals = 0;
1244
- this.config.locale = 'de-DE';
1259
+ this.config.locale = "de-DE";
1245
1260
  }
1246
1261
  static make(accessor) {
1247
1262
  return new NumberColumn(accessor);
@@ -1255,7 +1270,7 @@ class NumberColumn extends BaseColumn {
1255
1270
  return this;
1256
1271
  }
1257
1272
  // Währungsformatierung
1258
- money(currency = 'EUR') {
1273
+ money(currency = "EUR") {
1259
1274
  this.config.currency = currency;
1260
1275
  this.config.decimals = 2;
1261
1276
  return this;
@@ -1275,15 +1290,15 @@ class NumberColumn extends BaseColumn {
1275
1290
  }
1276
1291
  build() {
1277
1292
  const config = this.config;
1278
- const { accessor, label, sortable, decimals, locale, currency, percent, prefix, suffix } = config;
1293
+ const { accessor, label, sortable, decimals, locale, currency, percent, prefix, suffix, } = config;
1279
1294
  return {
1280
1295
  accessorKey: accessor,
1281
1296
  header: ({ column }) => {
1282
1297
  const displayLabel = label || String(accessor);
1283
1298
  if (!sortable) {
1284
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1299
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1285
1300
  }
1286
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1301
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1287
1302
  },
1288
1303
  cell: ({ getValue }) => {
1289
1304
  const value = getValue();
@@ -1293,7 +1308,7 @@ class NumberColumn extends BaseColumn {
1293
1308
  let formatted;
1294
1309
  if (currency) {
1295
1310
  formatted = new Intl.NumberFormat(locale, {
1296
- style: 'currency',
1311
+ style: "currency",
1297
1312
  currency,
1298
1313
  minimumFractionDigits: decimals,
1299
1314
  maximumFractionDigits: decimals,
@@ -1301,7 +1316,7 @@ class NumberColumn extends BaseColumn {
1301
1316
  }
1302
1317
  else if (percent) {
1303
1318
  formatted = new Intl.NumberFormat(locale, {
1304
- style: 'percent',
1319
+ style: "percent",
1305
1320
  minimumFractionDigits: decimals,
1306
1321
  maximumFractionDigits: decimals,
1307
1322
  }).format(value / 100);
@@ -1312,8 +1327,8 @@ class NumberColumn extends BaseColumn {
1312
1327
  maximumFractionDigits: decimals,
1313
1328
  }).format(value);
1314
1329
  }
1315
- const displayValue = `${prefix || ''}${formatted}${suffix || ''}`;
1316
- return jsx("span", { className: cn('tabular-nums', this.getAlignmentClass(), this.config.cellClassName), children: displayValue });
1330
+ const displayValue = `${prefix || ""}${formatted}${suffix || ""}`;
1331
+ return (jsx("span", { className: cn("tabular-nums", this.getAlignmentClass(), this.config.cellClassName), children: displayValue }));
1317
1332
  },
1318
1333
  };
1319
1334
  }
@@ -1326,8 +1341,8 @@ class ProgressColumn extends BaseColumn {
1326
1341
  config.max = 100;
1327
1342
  config.showValue = false;
1328
1343
  config.showPercentage = true;
1329
- config.size = 'md';
1330
- config.color = 'default';
1344
+ config.size = "md";
1345
+ config.color = "default";
1331
1346
  }
1332
1347
  static make(accessor) {
1333
1348
  return new ProgressColumn(accessor);
@@ -1371,10 +1386,10 @@ class ProgressColumn extends BaseColumn {
1371
1386
  config.color = (value, max) => {
1372
1387
  const percent = (value / max) * 100;
1373
1388
  if (percent <= danger)
1374
- return 'danger';
1389
+ return "danger";
1375
1390
  if (percent <= warning)
1376
- return 'warning';
1377
- return 'success';
1391
+ return "warning";
1392
+ return "success";
1378
1393
  };
1379
1394
  return this;
1380
1395
  }
@@ -1385,10 +1400,10 @@ class ProgressColumn extends BaseColumn {
1385
1400
  config.color = (value, max) => {
1386
1401
  const percent = (value / max) * 100;
1387
1402
  if (percent >= danger)
1388
- return 'danger';
1403
+ return "danger";
1389
1404
  if (percent >= warning)
1390
- return 'warning';
1391
- return 'success';
1405
+ return "warning";
1406
+ return "success";
1392
1407
  };
1393
1408
  return this;
1394
1409
  }
@@ -1399,26 +1414,26 @@ class ProgressColumn extends BaseColumn {
1399
1414
  }
1400
1415
  build() {
1401
1416
  const config = this.config;
1402
- const { accessor, label, sortable, max, showValue, showPercentage, size, color, format } = config;
1417
+ const { accessor, label, sortable, max, showValue, showPercentage, size, color, format, } = config;
1403
1418
  const sizeClasses = {
1404
- sm: 'h-1.5',
1405
- md: 'h-2',
1406
- lg: 'h-3',
1419
+ sm: "h-1.5",
1420
+ md: "h-2",
1421
+ lg: "h-3",
1407
1422
  };
1408
1423
  const colorClasses = {
1409
- default: '[&>div]:bg-primary',
1410
- success: '[&>div]:bg-green-500',
1411
- warning: '[&>div]:bg-yellow-500',
1412
- danger: '[&>div]:bg-red-500',
1424
+ default: "[&>div]:bg-primary",
1425
+ success: "[&>div]:bg-green-500",
1426
+ warning: "[&>div]:bg-yellow-500",
1427
+ danger: "[&>div]:bg-red-500",
1413
1428
  };
1414
1429
  return {
1415
1430
  accessorKey: accessor,
1416
1431
  header: ({ column }) => {
1417
1432
  const displayLabel = label || String(accessor);
1418
1433
  if (!sortable) {
1419
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1434
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1420
1435
  }
1421
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1436
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1422
1437
  },
1423
1438
  cell: ({ getValue }) => {
1424
1439
  const value = getValue();
@@ -1428,9 +1443,11 @@ class ProgressColumn extends BaseColumn {
1428
1443
  }
1429
1444
  const percentage = Math.min(100, Math.max(0, (value / maxValue) * 100));
1430
1445
  // Farbe berechnen
1431
- const currentColor = typeof color === 'function' ? color(value, maxValue) : color || 'default';
1446
+ const currentColor = typeof color === "function"
1447
+ ? color(value, maxValue)
1448
+ : color || "default";
1432
1449
  // Label erstellen
1433
- let labelText = '';
1450
+ let labelText = "";
1434
1451
  if (format) {
1435
1452
  labelText = format(value, maxValue);
1436
1453
  }
@@ -1440,7 +1457,7 @@ class ProgressColumn extends BaseColumn {
1440
1457
  else if (showPercentage) {
1441
1458
  labelText = `${Math.round(percentage)}%`;
1442
1459
  }
1443
- return (jsxs("div", { className: cn('flex min-w-[120px] items-center gap-3', this.config.cellClassName), children: [jsx(Progress, { value: percentage, className: cn('flex-1', sizeClasses[size || 'md'], colorClasses[currentColor]) }), labelText && jsx("span", { className: "text-muted-foreground min-w-[3rem] text-right text-sm tabular-nums", children: labelText })] }));
1460
+ return (jsxs("div", { className: cn("flex min-w-[120px] items-center gap-3", this.config.cellClassName), children: [jsx(Progress, { value: percentage, className: cn("flex-1", sizeClasses[size || "md"], colorClasses[currentColor]) }), labelText && (jsx("span", { className: "text-muted-foreground min-w-[3rem] text-right text-sm tabular-nums", children: labelText }))] }));
1444
1461
  },
1445
1462
  };
1446
1463
  }
@@ -1483,7 +1500,9 @@ class TextColumn extends BaseColumn {
1483
1500
  const existingFormatter = this.config.formatter;
1484
1501
  this.config.formatter = (value, row) => {
1485
1502
  const result = existingFormatter ? existingFormatter(value, row) : value;
1486
- return typeof result === 'string' ? result.toUpperCase() : result;
1503
+ return typeof result === "string"
1504
+ ? result.toUpperCase()
1505
+ : result;
1487
1506
  };
1488
1507
  return this;
1489
1508
  }
@@ -1491,7 +1510,9 @@ class TextColumn extends BaseColumn {
1491
1510
  const existingFormatter = this.config.formatter;
1492
1511
  this.config.formatter = (value, row) => {
1493
1512
  const result = existingFormatter ? existingFormatter(value, row) : value;
1494
- return typeof result === 'string' ? result.toLowerCase() : result;
1513
+ return typeof result === "string"
1514
+ ? result.toLowerCase()
1515
+ : result;
1495
1516
  };
1496
1517
  return this;
1497
1518
  }
@@ -1499,23 +1520,23 @@ class TextColumn extends BaseColumn {
1499
1520
  const existingFormatter = this.config.formatter;
1500
1521
  this.config.formatter = (value, row) => {
1501
1522
  const result = existingFormatter ? existingFormatter(value, row) : value;
1502
- if (typeof result === 'string' && result.length > chars) {
1503
- return result.slice(0, chars) + '...';
1523
+ if (typeof result === "string" && result.length > chars) {
1524
+ return result.slice(0, chars) + "...";
1504
1525
  }
1505
1526
  return result;
1506
1527
  };
1507
1528
  return this;
1508
1529
  }
1509
1530
  build() {
1510
- const { accessor, label, sortable, prefix, suffix, placeholder, formatter } = this.config;
1531
+ const { accessor, label, sortable, prefix, suffix, placeholder, formatter, } = this.config;
1511
1532
  return {
1512
1533
  accessorKey: accessor,
1513
1534
  header: ({ column }) => {
1514
1535
  const displayLabel = label || String(accessor);
1515
1536
  if (!sortable) {
1516
- return (jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1537
+ return (jsx("span", { className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
1517
1538
  }
1518
- return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1539
+ return (jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === "asc"), className: cn("text-muted-foreground font-medium", this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
1519
1540
  },
1520
1541
  cell: ({ row, getValue }) => {
1521
1542
  let value = getValue();
@@ -1524,12 +1545,12 @@ class TextColumn extends BaseColumn {
1524
1545
  value = formatter(value, row);
1525
1546
  }
1526
1547
  // Placeholder wenn leer
1527
- if (value === null || value === undefined || value === '') {
1528
- return (jsx("span", { className: cn('text-muted-foreground', this.getAlignmentClass(), this.config.cellClassName), children: placeholder || '' }));
1548
+ if (value === null || value === undefined || value === "") {
1549
+ return (jsx("span", { className: cn("text-muted-foreground", this.getAlignmentClass(), this.config.cellClassName), children: placeholder || "" }));
1529
1550
  }
1530
1551
  // Prefix/Suffix hinzufügen
1531
- const displayValue = `${prefix || ''}${value}${suffix || ''}`;
1532
- return jsx("span", { className: cn(this.getAlignmentClass(), this.config.cellClassName), children: displayValue });
1552
+ const displayValue = `${prefix || ""}${value}${suffix || ""}`;
1553
+ return (jsx("span", { className: cn(this.getAlignmentClass(), this.config.cellClassName), children: displayValue }));
1533
1554
  },
1534
1555
  };
1535
1556
  }
@@ -1538,7 +1559,7 @@ class TextColumn extends BaseColumn {
1538
1559
  class ActionsColumn {
1539
1560
  config = {
1540
1561
  actions: [],
1541
- label: 'Aktionen',
1562
+ label: "Aktionen",
1542
1563
  };
1543
1564
  static make() {
1544
1565
  return new ActionsColumn();
@@ -1558,16 +1579,16 @@ class ActionsColumn {
1558
1579
  }
1559
1580
  // Shortcuts für gängige Actions
1560
1581
  view(onClick) {
1561
- return this.action({ label: 'Anzeigen', onClick });
1582
+ return this.action({ label: "Anzeigen", onClick });
1562
1583
  }
1563
1584
  edit(onClick) {
1564
- return this.action({ label: 'Bearbeiten', onClick });
1585
+ return this.action({ label: "Bearbeiten", onClick });
1565
1586
  }
1566
1587
  delete(onClick) {
1567
1588
  return this.action({
1568
- label: 'Löschen',
1589
+ label: "Löschen",
1569
1590
  onClick,
1570
- variant: 'destructive',
1591
+ variant: "destructive",
1571
1592
  separator: true,
1572
1593
  });
1573
1594
  }
@@ -1583,21 +1604,22 @@ class ActionsColumn {
1583
1604
  build() {
1584
1605
  const { actions, label, triggerIcon } = this.config;
1585
1606
  return {
1586
- id: 'actions',
1607
+ id: "actions",
1587
1608
  header: () => jsx("span", { className: "sr-only", children: label }),
1588
1609
  cell: ({ row }) => {
1589
1610
  const data = row.original;
1590
1611
  const visibleActions = actions.filter((action) => !action.hidden || !action.hidden(data));
1591
1612
  if (visibleActions.length === 0)
1592
1613
  return null;
1593
- return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", className: "h-10 w-10 p-0", children: [jsx("span", { className: "sr-only", children: label }), triggerIcon || jsx(MoreHorizontal, { className: "h-8 w-8" })] }) }), jsx(DropdownMenuContent, { align: "end", children: visibleActions.map((action, index) => (jsxs("div", { children: [jsxs(DropdownMenuItem, { disabled: action.disabled?.(data), className: cn(action.variant === 'destructive' && 'text-destructive focus:text-destructive'), onClick: () => {
1614
+ return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", className: "h-10 w-10 p-0", children: [jsx("span", { className: "sr-only", children: label }), triggerIcon || jsx(MoreHorizontal, { className: "h-8 w-8" })] }) }), jsx(DropdownMenuContent, { align: "end", children: visibleActions.map((action, index) => (jsxs("div", { children: [jsxs(DropdownMenuItem, { disabled: action.disabled?.(data), className: cn(action.variant === "destructive" &&
1615
+ "text-destructive focus:text-destructive"), onClick: () => {
1594
1616
  if (action.href) {
1595
1617
  window.location.href = action.href(data);
1596
1618
  }
1597
1619
  else if (action.onClick) {
1598
1620
  action.onClick(data);
1599
1621
  }
1600
- }, children: [action.icon && jsx("span", { className: "mr-2", children: action.icon }), action.label] }), action.separator && index < visibleActions.length - 1 && jsx(DropdownMenuSeparator, {})] }, index))) })] }));
1622
+ }, children: [action.icon && jsx("span", { className: "mr-2", children: action.icon }), action.label] }), action.separator && index < visibleActions.length - 1 && (jsx(DropdownMenuSeparator, {}))] }, index))) })] }));
1601
1623
  },
1602
1624
  };
1603
1625
  }