@rehagro/ui 1.0.46 → 1.0.47

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.mts CHANGED
@@ -733,8 +733,18 @@ declare const Spinner: React__default.ForwardRefExoticComponent<React__default.H
733
733
  label?: string;
734
734
  } & React__default.RefAttributes<HTMLDivElement>>;
735
735
 
736
+ type CustomSelectOption = {
737
+ value: string;
738
+ label: string;
739
+ backgroundColor?: string;
740
+ };
741
+
736
742
  type TableSize = "sm" | "md" | "lg";
737
743
  type TableVariant = "default" | "striped";
744
+ type ColumnActionIcon<T> = {
745
+ icon: React__default.ReactNode;
746
+ onClick: (row: T, index: number) => void;
747
+ };
738
748
  type TableColumn<T> = {
739
749
  /** Unique key for this column */
740
750
  key: string;
@@ -744,16 +754,39 @@ type TableColumn<T> = {
744
754
  render: (row: T, index: number) => React__default.ReactNode;
745
755
  /** Column width (CSS value) */
746
756
  width?: string;
757
+ /** Maximum column width (CSS value) */
758
+ maxWidth?: string;
747
759
  /** Text alignment */
748
760
  align?: "left" | "center" | "right";
749
761
  /** Whether this column is sortable */
750
762
  sortable?: boolean;
763
+ /** Action icon to show in this column (clickable) */
764
+ actionIcon?: ColumnActionIcon<T>;
765
+ /** Whether this column is editable with a dropdown */
766
+ editable?: boolean;
767
+ /** List of choices for the editable dropdown */
768
+ choices?: CustomSelectOption[];
769
+ /** Function to get the current value for the editable field */
770
+ editableValue?: (row: T) => string;
771
+ /** Callback when the editable value changes */
772
+ onEditChange?: (row: T, index: number, value: string) => void;
751
773
  };
752
774
  type SortDirection = "asc" | "desc" | null;
753
775
  type TableSort = {
754
776
  key: string;
755
777
  direction: SortDirection;
756
778
  };
779
+ type HeaderTextStyle = {
780
+ color?: string;
781
+ fontFamily?: string;
782
+ fontSize?: string;
783
+ fontWeight?: string | number;
784
+ };
785
+ type HeaderStyle = {
786
+ backgroundColor?: string;
787
+ height?: string;
788
+ border?: string;
789
+ };
757
790
  type TableProps<T> = Omit<React__default.HTMLAttributes<HTMLTableElement>, "children"> & {
758
791
  /** Column definitions */
759
792
  columns: TableColumn<T>[];
@@ -778,9 +811,27 @@ type TableProps<T> = Omit<React__default.HTMLAttributes<HTMLTableElement>, "chil
778
811
  /** Whether the table has sticky header */
779
812
  stickyHeader?: boolean;
780
813
  /** Custom header row style */
781
- headerStyle?: React__default.CSSProperties;
814
+ headerStyle?: HeaderStyle;
815
+ /** Custom body row style */
816
+ bodyBackground?: string;
817
+ /** Custom body text style (color, font, weight) */
818
+ bodyTextStyle?: HeaderTextStyle;
782
819
  /** Custom header text class (overrides default rh-text-text-muted) */
783
820
  headerTextClassName?: string;
821
+ /** Custom header text style (color, font, weight) */
822
+ headerTextStyle?: HeaderTextStyle;
823
+ /** Custom row padding (CSS value for all sides or object with x/y) */
824
+ rowPadding?: string | {
825
+ x?: string;
826
+ y?: string;
827
+ };
828
+ /** Add row button */
829
+ addRowButton?: {
830
+ icon?: React__default.ReactNode;
831
+ text?: React__default.ReactNode;
832
+ };
833
+ /** Callback when add row is clicked */
834
+ onAddRow?: () => void;
784
835
  };
785
836
  declare const Table: <T>(props: TableProps<T> & {
786
837
  ref?: React__default.ForwardedRef<HTMLTableElement>;
package/dist/index.d.ts CHANGED
@@ -733,8 +733,18 @@ declare const Spinner: React__default.ForwardRefExoticComponent<React__default.H
733
733
  label?: string;
734
734
  } & React__default.RefAttributes<HTMLDivElement>>;
735
735
 
736
+ type CustomSelectOption = {
737
+ value: string;
738
+ label: string;
739
+ backgroundColor?: string;
740
+ };
741
+
736
742
  type TableSize = "sm" | "md" | "lg";
737
743
  type TableVariant = "default" | "striped";
744
+ type ColumnActionIcon<T> = {
745
+ icon: React__default.ReactNode;
746
+ onClick: (row: T, index: number) => void;
747
+ };
738
748
  type TableColumn<T> = {
739
749
  /** Unique key for this column */
740
750
  key: string;
@@ -744,16 +754,39 @@ type TableColumn<T> = {
744
754
  render: (row: T, index: number) => React__default.ReactNode;
745
755
  /** Column width (CSS value) */
746
756
  width?: string;
757
+ /** Maximum column width (CSS value) */
758
+ maxWidth?: string;
747
759
  /** Text alignment */
748
760
  align?: "left" | "center" | "right";
749
761
  /** Whether this column is sortable */
750
762
  sortable?: boolean;
763
+ /** Action icon to show in this column (clickable) */
764
+ actionIcon?: ColumnActionIcon<T>;
765
+ /** Whether this column is editable with a dropdown */
766
+ editable?: boolean;
767
+ /** List of choices for the editable dropdown */
768
+ choices?: CustomSelectOption[];
769
+ /** Function to get the current value for the editable field */
770
+ editableValue?: (row: T) => string;
771
+ /** Callback when the editable value changes */
772
+ onEditChange?: (row: T, index: number, value: string) => void;
751
773
  };
752
774
  type SortDirection = "asc" | "desc" | null;
753
775
  type TableSort = {
754
776
  key: string;
755
777
  direction: SortDirection;
756
778
  };
779
+ type HeaderTextStyle = {
780
+ color?: string;
781
+ fontFamily?: string;
782
+ fontSize?: string;
783
+ fontWeight?: string | number;
784
+ };
785
+ type HeaderStyle = {
786
+ backgroundColor?: string;
787
+ height?: string;
788
+ border?: string;
789
+ };
757
790
  type TableProps<T> = Omit<React__default.HTMLAttributes<HTMLTableElement>, "children"> & {
758
791
  /** Column definitions */
759
792
  columns: TableColumn<T>[];
@@ -778,9 +811,27 @@ type TableProps<T> = Omit<React__default.HTMLAttributes<HTMLTableElement>, "chil
778
811
  /** Whether the table has sticky header */
779
812
  stickyHeader?: boolean;
780
813
  /** Custom header row style */
781
- headerStyle?: React__default.CSSProperties;
814
+ headerStyle?: HeaderStyle;
815
+ /** Custom body row style */
816
+ bodyBackground?: string;
817
+ /** Custom body text style (color, font, weight) */
818
+ bodyTextStyle?: HeaderTextStyle;
782
819
  /** Custom header text class (overrides default rh-text-text-muted) */
783
820
  headerTextClassName?: string;
821
+ /** Custom header text style (color, font, weight) */
822
+ headerTextStyle?: HeaderTextStyle;
823
+ /** Custom row padding (CSS value for all sides or object with x/y) */
824
+ rowPadding?: string | {
825
+ x?: string;
826
+ y?: string;
827
+ };
828
+ /** Add row button */
829
+ addRowButton?: {
830
+ icon?: React__default.ReactNode;
831
+ text?: React__default.ReactNode;
832
+ };
833
+ /** Callback when add row is clicked */
834
+ onAddRow?: () => void;
784
835
  };
785
836
  declare const Table: <T>(props: TableProps<T> & {
786
837
  ref?: React__default.ForwardedRef<HTMLTableElement>;
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  var React9 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var reactDom = require('react-dom');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
@@ -2917,6 +2918,103 @@ var Spinner = React9.forwardRef(function Spinner2({ size = "md", color = "primar
2917
2918
  }
2918
2919
  );
2919
2920
  });
2921
+ var CustomSelect = ({ options, value, onChange, className = "" }) => {
2922
+ const [isOpen, setIsOpen] = React9.useState(false);
2923
+ const [dropdownStyle, setDropdownStyle] = React9.useState({});
2924
+ const containerRef = React9.useRef(null);
2925
+ const selectedOption = options.find((opt) => opt.value === value);
2926
+ const handleOpen = () => {
2927
+ if (!isOpen && containerRef.current) {
2928
+ const rect = containerRef.current.getBoundingClientRect();
2929
+ setDropdownStyle({
2930
+ position: "fixed",
2931
+ top: rect.bottom + 4,
2932
+ left: rect.left,
2933
+ zIndex: 2
2934
+ });
2935
+ }
2936
+ setIsOpen((prev) => !prev);
2937
+ };
2938
+ React9.useEffect(() => {
2939
+ const handleClickOutside = (e) => {
2940
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
2941
+ setIsOpen(false);
2942
+ }
2943
+ };
2944
+ if (isOpen) {
2945
+ document.addEventListener("mousedown", handleClickOutside);
2946
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2947
+ }
2948
+ }, [isOpen]);
2949
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: `rh-relative ${className}`, children: [
2950
+ /* @__PURE__ */ jsxRuntime.jsx(
2951
+ "button",
2952
+ {
2953
+ type: "button",
2954
+ onClick: handleOpen,
2955
+ className: "rh-w-full rh-h-full rh-flex rh-items-center rh-justify-between rh-py-1 rh-bg-transparent hover:rh-bg-background/50 rh-cursor-pointer rh-text-left",
2956
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rh-flex rh-items-center rh-gap-2 rh-flex-1 rh-truncate", children: /* @__PURE__ */ jsxRuntime.jsx(
2957
+ "span",
2958
+ {
2959
+ className: "rh-truncate rh-text-[14px] rh-px-2 rh-py-1 rh-rounded-xl",
2960
+ style: {
2961
+ backgroundColor: selectedOption?.backgroundColor || "transparent",
2962
+ fontFamily: "Inter, sans-serif",
2963
+ color: selectedOption?.backgroundColor ? "white" : "inherit"
2964
+ },
2965
+ children: selectedOption?.label || value
2966
+ }
2967
+ ) })
2968
+ }
2969
+ ),
2970
+ isOpen && reactDom.createPortal(
2971
+ /* @__PURE__ */ jsxRuntime.jsx(
2972
+ "div",
2973
+ {
2974
+ style: {
2975
+ ...dropdownStyle,
2976
+ boxShadow: "0 10px 20px 0 rgba(0, 0, 0, 0.05)"
2977
+ },
2978
+ className: "rh-bg-surface rh-border rh-border-border rh-rounded-xs rh-max-h-60 rh-overflow-auto rh-pr-3",
2979
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
2980
+ "button",
2981
+ {
2982
+ type: "button",
2983
+ onMouseDown: (e) => {
2984
+ e.preventDefault();
2985
+ onChange(option.value);
2986
+ setIsOpen(false);
2987
+ },
2988
+ className: "rh-flex rh-items-center rh-gap-2 rh-px-3 rh-py-2 rh-text-left hover:rh-bg-background/50 rh-cursor-pointer",
2989
+ children: [
2990
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rh-w-4 rh-h-4", children: option.value === value && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "13", height: "10", viewBox: "0 0 13 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx(
2991
+ "path",
2992
+ {
2993
+ d: "M12.7826 1.2813L4.78255 9.2813C4.71287 9.35122 4.63008 9.4067 4.53891 9.44455C4.44775 9.48241 4.35001 9.50189 4.2513 9.50189C4.15259 9.50189 4.05485 9.48241 3.96369 9.44455C3.87252 9.4067 3.78973 9.35122 3.72005 9.2813L0.220051 5.7813C0.150286 5.71154 0.0949458 5.62871 0.0571893 5.53756C0.0194329 5.44641 1.03958e-09 5.34871 0 5.25005C-1.03958e-09 5.15139 0.0194329 5.05369 0.0571893 4.96254C0.0949458 4.87139 0.150286 4.78857 0.220051 4.7188C0.289816 4.64904 0.372638 4.5937 0.46379 4.55594C0.554942 4.51818 0.652639 4.49875 0.751301 4.49875C0.849963 4.49875 0.947659 4.51818 1.03881 4.55594C1.12996 4.5937 1.21279 4.64904 1.28255 4.7188L4.25193 7.68818L11.7213 0.220051C11.8622 0.0791546 12.0533 0 12.2526 0C12.4518 0 12.6429 0.0791546 12.7838 0.220051C12.9247 0.360947 13.0039 0.552044 13.0039 0.751301C13.0039 0.950559 12.9247 1.14165 12.7838 1.28255L12.7826 1.2813Z",
2994
+ fill: "#374151"
2995
+ }
2996
+ ) }) }),
2997
+ /* @__PURE__ */ jsxRuntime.jsx(
2998
+ "span",
2999
+ {
3000
+ className: "rh-truncate rh-p-1 rh-px-2 rh-rounded-xl rh-text-white rh-text-[14px]",
3001
+ style: {
3002
+ backgroundColor: option.backgroundColor || "transparent",
3003
+ fontFamily: "Inter, sans-serif"
3004
+ },
3005
+ children: option.label
3006
+ }
3007
+ )
3008
+ ]
3009
+ },
3010
+ option.value
3011
+ ))
3012
+ }
3013
+ ),
3014
+ document.body
3015
+ )
3016
+ ] });
3017
+ };
2920
3018
  var sizeClasses12 = {
2921
3019
  sm: { cell: "rh-px-2 rh-py-2 rh-text-xs", header: "rh-px-2 rh-py-2 rh-text-xs" },
2922
3020
  md: { cell: "rh-px-3 rh-py-3 rh-text-sm", header: "rh-px-3 rh-py-3 rh-text-xs" },
@@ -2941,6 +3039,12 @@ function TableInner({
2941
3039
  stickyHeader = false,
2942
3040
  headerStyle,
2943
3041
  headerTextClassName,
3042
+ headerTextStyle,
3043
+ bodyBackground,
3044
+ bodyTextStyle,
3045
+ rowPadding,
3046
+ addRowButton,
3047
+ onAddRow,
2944
3048
  className = "",
2945
3049
  ...rest
2946
3050
  }, ref) {
@@ -2982,34 +3086,81 @@ function TableInner({
2982
3086
  };
2983
3087
  const isEmpty = !loading && data.length === 0;
2984
3088
  const colSpan = columns.length;
2985
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rh-w-full rh-overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs(
3089
+ const headerTextStyleInline = {
3090
+ color: headerTextStyle?.color,
3091
+ fontFamily: headerTextStyle?.fontFamily,
3092
+ fontSize: headerTextStyle?.fontSize,
3093
+ fontWeight: headerTextStyle?.fontWeight
3094
+ };
3095
+ const bodyStyleInline = {
3096
+ color: bodyTextStyle?.color,
3097
+ fontFamily: bodyTextStyle?.fontFamily,
3098
+ fontSize: bodyTextStyle?.fontSize,
3099
+ fontWeight: bodyTextStyle?.fontWeight
3100
+ };
3101
+ const getRowPaddingStyle = () => {
3102
+ if (typeof rowPadding === "string") {
3103
+ return { padding: rowPadding };
3104
+ }
3105
+ if (typeof rowPadding === "object") {
3106
+ const style = {};
3107
+ if (rowPadding.x) {
3108
+ style.paddingLeft = rowPadding.x;
3109
+ style.paddingRight = rowPadding.x;
3110
+ }
3111
+ if (rowPadding.y) {
3112
+ style.paddingTop = rowPadding.y;
3113
+ style.paddingBottom = rowPadding.y;
3114
+ }
3115
+ return style;
3116
+ }
3117
+ return {};
3118
+ };
3119
+ const rowPaddingStyle = getRowPaddingStyle();
3120
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rh-w-full rh-rounded rh-overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
2986
3121
  "table",
2987
3122
  {
2988
3123
  ref,
3124
+ style: { backgroundColor: bodyBackground },
2989
3125
  className: ["rh-w-full rh-border-collapse rh-font-body", className].filter(Boolean).join(" "),
2990
3126
  ...rest,
2991
3127
  children: [
2992
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "rh-border-b rh-border-border", style: headerStyle, children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
2993
- "th",
3128
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx(
3129
+ "tr",
2994
3130
  {
2995
- scope: "col",
2996
- style: { width: column.width },
2997
- className: [
2998
- sizeClasses12[size].header,
2999
- alignClasses[column.align || "left"],
3000
- `rh-font-semibold rh-whitespace-nowrap ${headerTextClassName || "rh-text-text-muted"}`,
3001
- stickyHeader ? "rh-sticky rh-top-0 rh-bg-surface rh-z-10" : "",
3002
- column.sortable ? "rh-cursor-pointer rh-select-none hover:rh-text-text" : ""
3003
- ].filter(Boolean).join(" "),
3004
- onClick: () => handleSort(column),
3005
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rh-inline-flex rh-items-center", children: [
3006
- column.header,
3007
- renderSortIcon(column)
3008
- ] })
3009
- },
3010
- column.key
3011
- )) }) }),
3012
- /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
3131
+ className: "rh-border-b rh-border-border",
3132
+ style: {
3133
+ backgroundColor: headerStyle?.backgroundColor,
3134
+ height: headerStyle?.height,
3135
+ border: headerStyle?.border
3136
+ },
3137
+ children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
3138
+ "th",
3139
+ {
3140
+ scope: "col",
3141
+ style: {
3142
+ width: column.width,
3143
+ maxWidth: column.maxWidth,
3144
+ ...rowPaddingStyle
3145
+ },
3146
+ className: [
3147
+ rowPadding ? "" : sizeClasses12[size].header,
3148
+ alignClasses[column.align || "left"],
3149
+ `rh-font-semibold rh-whitespace-nowrap ${headerTextClassName || "rh-text-text-muted"}`,
3150
+ stickyHeader ? "rh-sticky rh-top-0 rh-bg-surface rh-z-10" : "",
3151
+ column.sortable ? "rh-cursor-pointer rh-select-none hover:rh-text-text" : ""
3152
+ ].filter(Boolean).join(" "),
3153
+ onClick: () => handleSort(column),
3154
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rh-inline-flex rh-items-center", style: headerTextStyleInline, children: [
3155
+ column.header,
3156
+ renderSortIcon(column)
3157
+ ] })
3158
+ },
3159
+ column.key
3160
+ ))
3161
+ }
3162
+ ) }),
3163
+ /* @__PURE__ */ jsxRuntime.jsxs("tbody", { style: { backgroundColor: bodyBackground }, children: [
3013
3164
  loading && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, className: "rh-text-center rh-py-8", children: loadingContent || /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rh-flex rh-items-center rh-justify-center rh-gap-2 rh-text-text-muted", children: [
3014
3165
  /* @__PURE__ */ jsxRuntime.jsxs(
3015
3166
  "svg",
@@ -3047,6 +3198,7 @@ function TableInner({
3047
3198
  !loading && data.map((row, index) => /* @__PURE__ */ jsxRuntime.jsx(
3048
3199
  "tr",
3049
3200
  {
3201
+ style: bodyStyleInline,
3050
3202
  className: [
3051
3203
  "rh-border-b rh-border-border rh-transition-colors",
3052
3204
  "hover:rh-bg-background",
@@ -3055,18 +3207,56 @@ function TableInner({
3055
3207
  children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
3056
3208
  "td",
3057
3209
  {
3210
+ style: { width: column.width, maxWidth: column.maxWidth, ...rowPaddingStyle },
3058
3211
  className: [
3059
- sizeClasses12[size].cell,
3212
+ rowPadding ? "" : sizeClasses12[size].cell,
3060
3213
  alignClasses[column.align || "left"],
3061
3214
  "rh-text-text"
3062
3215
  ].filter(Boolean).join(" "),
3063
- children: column.render(row, index)
3216
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rh-flex rh-items-center rh-justify-between rh-gap-2", children: [
3217
+ column.editable && column.choices && column.editableValue ? /* @__PURE__ */ jsxRuntime.jsx(
3218
+ CustomSelect,
3219
+ {
3220
+ options: column.choices,
3221
+ value: column.editableValue(row),
3222
+ onChange: (value) => column.onEditChange?.(row, index, value),
3223
+ className: "rh-w-full rh-h-full"
3224
+ }
3225
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: column.render(row, index) }),
3226
+ column.actionIcon && /* @__PURE__ */ jsxRuntime.jsx(
3227
+ "span",
3228
+ {
3229
+ className: "rh-cursor-pointer hover:rh-bg-background/50 rh-p-1 rh-rounded",
3230
+ onClick: (e) => {
3231
+ e.stopPropagation();
3232
+ column.actionIcon?.onClick(row, index);
3233
+ },
3234
+ children: column.actionIcon.icon
3235
+ }
3236
+ )
3237
+ ] })
3064
3238
  },
3065
3239
  column.key
3066
3240
  ))
3067
3241
  },
3068
3242
  rowKey(row, index)
3069
- ))
3243
+ )),
3244
+ addRowButton && !loading && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "rh-border-border hover:rh-bg-background/100 rh-rounde-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
3245
+ "td",
3246
+ {
3247
+ colSpan,
3248
+ style: rowPaddingStyle,
3249
+ className: [
3250
+ rowPadding ? "" : sizeClasses12[size].cell,
3251
+ "rh-text-center rh-cursor-pointer rh-text-[#9CA3AF] rh-font-medium"
3252
+ ].filter(Boolean).join(" "),
3253
+ onClick: onAddRow,
3254
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rh-flex rh-items-center rh-justify-center rh-gap-2 rh-h-6 rh-font-bold rh-text-sm", children: [
3255
+ addRowButton.icon,
3256
+ addRowButton.text
3257
+ ] })
3258
+ }
3259
+ ) })
3070
3260
  ] })
3071
3261
  ]
3072
3262
  }