@gobolt/genesis 0.4.7 → 0.4.10

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.
@@ -3,7 +3,7 @@ import { OverflowMenuItemProps } from '../OverflowMenuItem';
3
3
  export interface OverflowMenuProps {
4
4
  items?: OverflowMenuItemProps[];
5
5
  children?: React.ReactNode;
6
- trigger: React.ReactNode;
6
+ trigger?: React.ReactNode;
7
7
  isOpen?: boolean;
8
8
  onOpenChange?: (open: boolean) => void;
9
9
  placement?: "bottom" | "top" | "left" | "right";
@@ -28,6 +28,7 @@ export interface TableProps<T extends Record<string, any>> {
28
28
  name?: string;
29
29
  };
30
30
  };
31
+ onRowClick?: (record: T, index: number, event: React.MouseEvent) => void;
31
32
  onChange?: (pagination: TablePaginationConfig, filters: Record<string, any>, sorter: SorterResult<T> | SorterResult<T>[], extra: any) => void;
32
33
  loading?: boolean;
33
34
  pagination?: (TablePaginationConfig & {
@@ -58,5 +59,5 @@ export type SorterResult<T> = {
58
59
  field?: keyof T | string | React.Key | readonly React.Key[];
59
60
  columnKey?: React.Key;
60
61
  };
61
- declare function Table<T extends Record<string, any>>({ columns, dataSource, rowKey, size, onChange, rowSelection, pagination, isMainContentCell, isMaterializedView, materializedViewConfig, ...rest }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
62
+ declare function Table<T extends Record<string, any>>({ columns, dataSource, rowKey, size, onChange, rowSelection, onRowClick, pagination, isMainContentCell, isMaterializedView, materializedViewConfig, ...rest }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
62
63
  export default Table;
@@ -1,3 +1,4 @@
1
+ import { default as React } from 'react';
1
2
  import { PaginationStyle } from './TableControls/CustomPagination';
2
3
  import { ColumnType } from 'antd/es/table';
3
4
  export interface TablePaginationProps<T> {
@@ -5,9 +6,10 @@ export interface TablePaginationProps<T> {
5
6
  dataSource: T[];
6
7
  rowSelection?: any;
7
8
  onChange?: (...arguments_: any[]) => void;
9
+ onRowClick?: (record: T, index: number, event: React.MouseEvent) => void;
8
10
  paginationStyle?: PaginationStyle;
9
11
  pageSize?: number;
10
12
  isMainContentCell?: boolean;
11
13
  }
12
- declare const TablePagination: <T extends Record<string, any>>({ columns, dataSource, rowSelection, onChange, paginationStyle, pageSize, isMainContentCell, }: TablePaginationProps<T>) => import("react/jsx-runtime").JSX.Element;
14
+ declare const TablePagination: <T extends Record<string, any>>({ columns, dataSource, rowSelection, onChange, onRowClick, paginationStyle, pageSize, isMainContentCell, }: TablePaginationProps<T>) => import("react/jsx-runtime").JSX.Element;
13
15
  export default TablePagination;
@@ -15,15 +15,19 @@ export type UseTableConfig = {
15
15
  };
16
16
  export declare const useTable: <T extends Record<string, any>>(useTableConfig: any) => {
17
17
  isLoading: boolean;
18
+ hasErrored: boolean;
18
19
  rowSelection: {
19
20
  type: SelectionType;
20
- onChange: (selectedRowKeys: React.Key[], selectedRows: T[]) => void;
21
+ selectedRowKeys: import('react').Key[];
22
+ onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: T[]) => void;
21
23
  getCheckboxProps: (record: any) => unknown;
22
24
  };
23
25
  selectedRows: T[];
26
+ selectedRowKeys: import('react').Key[];
24
27
  hasSettings: boolean;
25
28
  hasFilter: boolean;
26
29
  updateDataSource: (newDataSource: T[]) => void;
30
+ retry: () => void;
27
31
  dataSource: T[];
28
32
  columns: ColumnsType<T>;
29
33
  error: Error | null;
@@ -1,3 +1,4 @@
1
+ import { default as React } from 'react';
1
2
  import { TableProps } from '../Table';
2
3
  import { TableControlsData } from '../Table/TableControls/TableControls';
3
4
  import { ActionEvent, TableEventPayload } from '../../types/events';
@@ -5,6 +6,7 @@ export interface TableWithControlsProps {
5
6
  tableControlsData: TableControlsData;
6
7
  tableData: TableProps<Record<string, any>>;
7
8
  onChange: (event: ActionEvent<TableEventPayload>) => void;
9
+ onRowClick?: (record: Record<string, any>, index: number, event: React.MouseEvent) => void;
8
10
  }
9
- declare const TableWithControls: ({ tableData, tableControlsData, onChange, }: TableWithControlsProps) => import("react/jsx-runtime").JSX.Element;
11
+ declare const TableWithControls: ({ tableData, tableControlsData, onChange, onRowClick, }: TableWithControlsProps) => import("react/jsx-runtime").JSX.Element;
10
12
  export default TableWithControls;
@@ -20,12 +20,15 @@ export declare const useTableWithControls: (tableConfig: UseTableConfig) => {
20
20
  };
21
21
  totalRecords: number;
22
22
  };
23
- dataSource: Record<string, any>[];
23
+ dataSource: any[];
24
24
  columns: import('antd').TableColumnsType<Record<string, any>>;
25
25
  rowSelection: {
26
26
  type: import('../Table/Table').SelectionType;
27
- onChange: (selectedRowKeys: React.Key[], selectedRows: Record<string, any>[]) => void;
27
+ selectedRowKeys: import('react').Key[];
28
+ onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: Record<string, any>[]) => void;
28
29
  getCheckboxProps: (record: any) => unknown;
29
30
  };
31
+ selectedRows: Record<string, any>[];
32
+ selectedRowKeys: import('react').Key[];
30
33
  updateDataSource: (newDataSource: Record<string, any>[]) => void;
31
- } | null;
34
+ };
package/dist/index.cjs CHANGED
@@ -60250,6 +60250,9 @@ function FaCircleCheck(props) {
60250
60250
  function HiClock(props) {
60251
60251
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", "clipRule": "evenodd" }, "child": [] }] })(props);
60252
60252
  }
60253
+ function HiDotsHorizontal(props) {
60254
+ return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "d": "M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" }, "child": [] }] })(props);
60255
+ }
60253
60256
  function HiExclamationCircle(props) {
60254
60257
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", "clipRule": "evenodd" }, "child": [] }] })(props);
60255
60258
  }
@@ -77644,8 +77647,10 @@ const Tooltip2 = ({
77644
77647
  }
77645
77648
  ) }),
77646
77649
  open: isVisible2,
77647
- overlayStyle: {
77648
- pointerEvents: "none"
77650
+ styles: {
77651
+ root: {
77652
+ pointerEvents: "none"
77653
+ }
77649
77654
  },
77650
77655
  children: children2
77651
77656
  }
@@ -80515,10 +80520,13 @@ const OverflowMenuItem$1 = styled.div`
80515
80520
  const OverflowMenuItem = ({ children: children2, onClick }) => {
80516
80521
  return /* @__PURE__ */ jsxRuntime.jsx(OverflowMenuItem$1, { onClick, children: children2 });
80517
80522
  };
80523
+ const DefaultTrigger = () => {
80524
+ return /* @__PURE__ */ jsxRuntime.jsx(Button$1, { isIconButton: true, themeType: "secondary", size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(HiDotsHorizontal, {}) });
80525
+ };
80518
80526
  const OverflowMenu = ({
80519
80527
  items,
80520
80528
  children: children2,
80521
- trigger,
80529
+ trigger = /* @__PURE__ */ jsxRuntime.jsx(DefaultTrigger, {}),
80522
80530
  isOpen: controlledIsOpen,
80523
80531
  onOpenChange,
80524
80532
  placement = "bottom",
@@ -80795,7 +80803,7 @@ const getCombinedPercent = (firstBarData, secondBarData) => {
80795
80803
  if (firstBarData?.value !== void 0 && secondBarData?.value !== void 0) {
80796
80804
  const total = firstBarData.value + secondBarData.value;
80797
80805
  const dividedBy = total / 2;
80798
- return Math.round(dividedBy * 10) / 10;
80806
+ return Math.round(dividedBy);
80799
80807
  }
80800
80808
  return firstBarData?.value || 0;
80801
80809
  };
@@ -83519,6 +83527,12 @@ const getGenesisClass$1 = ({ colors: colors2, borderRadius: borderRadius2, sizin
83519
83527
  background-color: ${components2.tableCell.selected} !important;
83520
83528
  color: #fff !important;
83521
83529
  }
83530
+
83531
+ .ant-table-tbody > tr.ant-table-row-pressed > td,
83532
+ .ant-table-tbody > tr.ant-table-row-pressed > .ant-table-cell {
83533
+ background-color: ${components2.tableCell.selected} !important;
83534
+ color: #fff !important;
83535
+ }
83522
83536
  `;
83523
83537
  };
83524
83538
  const Table$1 = styled(ForwardTable)`
@@ -83969,6 +83983,7 @@ function Table({
83969
83983
  size = "small",
83970
83984
  onChange,
83971
83985
  rowSelection,
83986
+ onRowClick,
83972
83987
  pagination,
83973
83988
  isMainContentCell = false,
83974
83989
  isMaterializedView = false,
@@ -83981,6 +83996,10 @@ function Table({
83981
83996
  const [dynamicHeight, setDynamicHeight] = React__namespace.useState(
83982
83997
  400
83983
83998
  );
83999
+ const [selectedRowKeys, setSelectedRowKeys] = React__namespace.useState([]);
84000
+ const [pressedRowKey, setPressedRowKey] = React__namespace.useState(
84001
+ null
84002
+ );
83984
84003
  const tableRef = React__namespace.useRef(null);
83985
84004
  const containerRef = React__namespace.useRef(null);
83986
84005
  React__namespace.useEffect(() => {
@@ -84083,6 +84102,60 @@ function Table({
84083
84102
  return rest.scroll;
84084
84103
  }, [isMaterializedView, materializedViewConfig, dynamicHeight, rest.scroll]);
84085
84104
  const tableDataSource = isMaterializedView ? materializedData : dataSource;
84105
+ const handleRowMouseDown = React__namespace.useCallback(
84106
+ (record, index2, event) => {
84107
+ const target = event.target;
84108
+ const isInteractiveElement = target.closest(
84109
+ 'button, a, input, select, textarea, [role="button"], [onclick], .ant-checkbox-wrapper, .ant-checkbox'
84110
+ );
84111
+ if (isInteractiveElement) {
84112
+ return;
84113
+ }
84114
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84115
+ setPressedRowKey(recordKey);
84116
+ },
84117
+ [rowKey]
84118
+ );
84119
+ const handleRowMouseUp = React__namespace.useCallback(
84120
+ (record, index2, event) => {
84121
+ setPressedRowKey(null);
84122
+ },
84123
+ []
84124
+ );
84125
+ const handleRowClick = React__namespace.useCallback(
84126
+ (record, index2, event) => {
84127
+ console.log("Row clicked:", record, "index:", index2);
84128
+ const target = event.target;
84129
+ const isInteractiveElement = target.closest(
84130
+ 'button, a, input, select, textarea, [role="button"], [onclick], .ant-checkbox-wrapper, .ant-checkbox'
84131
+ );
84132
+ console.log("Is interactive element:", isInteractiveElement);
84133
+ if (isInteractiveElement) {
84134
+ console.log("Skipping row click due to interactive element");
84135
+ return;
84136
+ }
84137
+ if (onRowClick) {
84138
+ onRowClick(record, index2, event);
84139
+ }
84140
+ },
84141
+ [onRowClick]
84142
+ );
84143
+ const enhancedRowSelection = React__namespace.useMemo(() => {
84144
+ if (!rowSelection) return;
84145
+ return {
84146
+ ...rowSelection,
84147
+ selectedRowKeys,
84148
+ // Use internal state
84149
+ // Override the onChange to ensure we get the latest data
84150
+ onChange: (selectedRowKeys2, selectedRows) => {
84151
+ console.log("Row selection changed:", selectedRowKeys2, selectedRows);
84152
+ setSelectedRowKeys(selectedRowKeys2);
84153
+ if (rowSelection.onChange) {
84154
+ rowSelection.onChange(selectedRowKeys2, selectedRows);
84155
+ }
84156
+ }
84157
+ };
84158
+ }, [rowSelection, selectedRowKeys]);
84086
84159
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsxRuntime.jsx(
84087
84160
  Table$1,
84088
84161
  {
@@ -84094,7 +84167,24 @@ function Table({
84094
84167
  locale: { emptyText: "No Data" },
84095
84168
  size,
84096
84169
  onChange,
84097
- rowSelection,
84170
+ rowSelection: enhancedRowSelection,
84171
+ onRow: (record, index2) => {
84172
+ const isDisabled = rowSelection?.getCheckboxProps?.(record)?.disabled ?? false;
84173
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84174
+ const isPressed = pressedRowKey === recordKey;
84175
+ return {
84176
+ onClick: (event) => handleRowClick(record, index2 ?? 0, event),
84177
+ onMouseDown: (event) => handleRowMouseDown(record, index2 ?? 0, event),
84178
+ onMouseUp: (event) => handleRowMouseUp(record, index2 ?? 0, event),
84179
+ onMouseLeave: () => setPressedRowKey(null),
84180
+ // Clear pressed state when mouse leaves
84181
+ style: {
84182
+ cursor: onRowClick ? "pointer" : "default",
84183
+ opacity: isDisabled ? 0.6 : 1
84184
+ },
84185
+ className: isPressed ? "ant-table-row-pressed" : ""
84186
+ };
84187
+ },
84098
84188
  pagination: paginationConfig,
84099
84189
  scroll: scrollConfig,
84100
84190
  onScroll: isMaterializedView ? handleScroll : void 0,
@@ -84108,6 +84198,7 @@ const TablePagination = ({
84108
84198
  dataSource,
84109
84199
  rowSelection,
84110
84200
  onChange,
84201
+ onRowClick,
84111
84202
  paginationStyle = PaginationStyle.SIMPLE,
84112
84203
  pageSize = 10,
84113
84204
  isMainContentCell
@@ -84126,6 +84217,7 @@ const TablePagination = ({
84126
84217
  dataSource: paginatedData,
84127
84218
  rowSelection,
84128
84219
  onChange,
84220
+ onRowClick,
84129
84221
  pagination: false,
84130
84222
  isMainContentCell
84131
84223
  }
@@ -84155,6 +84247,9 @@ const defaultRowSelection = (record) => ({
84155
84247
  });
84156
84248
  const useTable = (useTableConfig) => {
84157
84249
  const [isLoading, setLoading] = React.useState(true);
84250
+ const [hasErrored, setHasErrored] = React.useState(false);
84251
+ const hasFetchedRef = React.useRef(false);
84252
+ const isDisabledRef = React.useRef(false);
84158
84253
  const {
84159
84254
  columns,
84160
84255
  filters = null,
@@ -84181,14 +84276,39 @@ const useTable = (useTableConfig) => {
84181
84276
  error: null
84182
84277
  });
84183
84278
  const [selectedRows, setSelectedRows] = React.useState([]);
84279
+ const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
84280
+ const memoizedFetchOptions = React.useMemo(
84281
+ () => fetchOptions,
84282
+ [fetchOptions.method, fetchOptions.headers, fetchOptions.body]
84283
+ );
84184
84284
  React.useEffect(() => {
84185
- if (disableAutoFetch && initialDataSource.length > 0) {
84285
+ if (disableAutoFetch) {
84286
+ isDisabledRef.current = true;
84287
+ setLoading(false);
84288
+ return;
84289
+ }
84290
+ if (hasFetchedRef.current || hasErrored || isDisabledRef.current) {
84186
84291
  setLoading(false);
84187
84292
  return;
84188
84293
  }
84189
84294
  const fetchData = async () => {
84190
84295
  try {
84191
- const response = await fetch(fetchUrl, fetchOptions);
84296
+ hasFetchedRef.current = true;
84297
+ const response = await fetch(fetchUrl, memoizedFetchOptions);
84298
+ if (response.status === 404) {
84299
+ console.warn(`Table data not found at ${fetchUrl}, stopping retries`);
84300
+ setHasErrored(true);
84301
+ setData({
84302
+ dataSource: initialDataSource,
84303
+ columns,
84304
+ error: new Error(`Data not found at ${fetchUrl}`)
84305
+ });
84306
+ setLoading(false);
84307
+ return;
84308
+ }
84309
+ if (!response.ok) {
84310
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
84311
+ }
84192
84312
  const result = await response.json();
84193
84313
  const sourceData = result.data || [];
84194
84314
  setOriginalData(sourceData);
@@ -84197,10 +84317,12 @@ const useTable = (useTableConfig) => {
84197
84317
  columns,
84198
84318
  error: null
84199
84319
  });
84320
+ setHasErrored(false);
84200
84321
  } catch (error2) {
84201
84322
  console.error("Error fetching table data:", error2);
84323
+ setHasErrored(true);
84202
84324
  setData({
84203
- dataSource: [],
84325
+ dataSource: initialDataSource,
84204
84326
  columns,
84205
84327
  error: error2 instanceof Error ? error2 : new Error(String(error2))
84206
84328
  });
@@ -84213,11 +84335,19 @@ const useTable = (useTableConfig) => {
84213
84335
  } else {
84214
84336
  fetchData();
84215
84337
  }
84216
- }, [fetchOptions, disableAutoFetch, initialDataSource]);
84338
+ }, [
84339
+ memoizedFetchOptions,
84340
+ disableAutoFetch,
84341
+ hasErrored,
84342
+ fetchUrl,
84343
+ columns,
84344
+ initialDataSource
84345
+ ]);
84217
84346
  const handleRowSelection = React.useCallback(
84218
- (selectedRowKeys, selectedRows2) => {
84219
- console.log("Row Selected:", selectedRowKeys, selectedRows2);
84220
- setSelectedRows(selectedRows2);
84347
+ (newSelectedRowKeys, newSelectedRows) => {
84348
+ console.log("Row Selected:", newSelectedRowKeys, newSelectedRows);
84349
+ setSelectedRowKeys(newSelectedRowKeys);
84350
+ setSelectedRows(newSelectedRows);
84221
84351
  },
84222
84352
  []
84223
84353
  );
@@ -84228,19 +84358,29 @@ const useTable = (useTableConfig) => {
84228
84358
  dataSource: newDataSource
84229
84359
  }));
84230
84360
  }, []);
84361
+ const retry = React.useCallback(() => {
84362
+ setHasErrored(false);
84363
+ hasFetchedRef.current = false;
84364
+ isDisabledRef.current = false;
84365
+ setLoading(true);
84366
+ }, []);
84231
84367
  const rowSelection = {
84232
84368
  type: selectionType,
84369
+ selectedRowKeys,
84233
84370
  onChange: handleRowSelection,
84234
84371
  getCheckboxProps: disableRowSelection
84235
84372
  };
84236
84373
  return {
84237
84374
  ...data,
84238
84375
  isLoading,
84376
+ hasErrored,
84239
84377
  rowSelection,
84240
84378
  selectedRows,
84379
+ selectedRowKeys,
84241
84380
  hasSettings,
84242
84381
  hasFilter,
84243
- updateDataSource
84382
+ updateDataSource,
84383
+ retry
84244
84384
  };
84245
84385
  };
84246
84386
  function HiMiniAdjustmentsVertical(props) {
@@ -84514,7 +84654,8 @@ const TableControls = ({
84514
84654
  const TableWithControls = ({
84515
84655
  tableData,
84516
84656
  tableControlsData: tableControlsData2,
84517
- onChange
84657
+ onChange,
84658
+ onRowClick
84518
84659
  }) => {
84519
84660
  const { primaryTableRowData, secondaryTableRowData } = tableControlsData2;
84520
84661
  const {
@@ -84551,6 +84692,7 @@ const TableWithControls = ({
84551
84692
  columns,
84552
84693
  rowSelection,
84553
84694
  onChange: onTableChange,
84695
+ onRowClick,
84554
84696
  isMaterializedView,
84555
84697
  materializedViewConfig
84556
84698
  }
@@ -84628,6 +84770,36 @@ const mockColumns = [
84628
84770
  isProgressCombined: true
84629
84771
  });
84630
84772
  }
84773
+ },
84774
+ {
84775
+ title: "Actions",
84776
+ key: "actions",
84777
+ render: (record) => {
84778
+ const menuItems = [
84779
+ {
84780
+ id: "edit",
84781
+ children: "Edit",
84782
+ onClick: () => {
84783
+ console.log("Edit clicked for record:", record.id);
84784
+ }
84785
+ },
84786
+ {
84787
+ id: "delete",
84788
+ children: "Delete",
84789
+ onClick: () => {
84790
+ console.log("Delete clicked for record:", record.id);
84791
+ }
84792
+ }
84793
+ ];
84794
+ return React.createElement(OverflowMenu, {
84795
+ items: menuItems,
84796
+ onItemClick: (item) => {
84797
+ if (item.onClick) {
84798
+ item.onClick();
84799
+ }
84800
+ }
84801
+ });
84802
+ }
84631
84803
  }
84632
84804
  ];
84633
84805
  mockColumns.map((column2) => ({
@@ -85037,9 +85209,10 @@ const startingUseTableConfig = {
85037
85209
  dataSource: []
85038
85210
  };
85039
85211
  const useTableWithControls = (tableConfig) => {
85040
- const [useTableConfig, setUseTableConfig] = React.useState(
85041
- startingUseTableConfig
85042
- );
85212
+ const [useTableConfig, setUseTableConfig] = React.useState(() => ({
85213
+ ...startingUseTableConfig,
85214
+ ...tableConfig
85215
+ }));
85043
85216
  const [groups, setGroups] = React.useState(
85044
85217
  tableControlsData.secondaryTableRowData.groups
85045
85218
  );
@@ -85050,20 +85223,22 @@ const useTableWithControls = (tableConfig) => {
85050
85223
  });
85051
85224
  const { secondaryTableRowData } = tableControlsData;
85052
85225
  const {
85053
- dataSource,
85226
+ dataSource: hookDataSource,
85054
85227
  columns,
85055
85228
  rowSelection,
85229
+ selectedRows,
85230
+ selectedRowKeys,
85056
85231
  hasSettings,
85057
85232
  hasFilter,
85058
85233
  updateDataSource
85059
85234
  } = useTable(useTableConfig);
85235
+ const dataSource = tableConfig.dataSource || hookDataSource;
85060
85236
  const safeDataSource = dataSource || [];
85061
85237
  const newSecondaryTableRowData = {
85062
85238
  ...secondaryTableRowData,
85063
85239
  groups,
85064
85240
  totalRecords: safeDataSource.length
85065
85241
  };
85066
- if (!dataSource) return null;
85067
85242
  const onGroupItemClick = (title, item) => {
85068
85243
  const newGroups = { ...groups };
85069
85244
  newGroups[title] = newGroups[title].filter((group) => group !== item);
@@ -85153,6 +85328,8 @@ const useTableWithControls = (tableConfig) => {
85153
85328
  dataSource: safeDataSource,
85154
85329
  columns,
85155
85330
  rowSelection,
85331
+ selectedRows,
85332
+ selectedRowKeys,
85156
85333
  updateDataSource
85157
85334
  };
85158
85335
  };
package/dist/index.js CHANGED
@@ -60232,6 +60232,9 @@ function FaCircleCheck(props) {
60232
60232
  function HiClock(props) {
60233
60233
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", "clipRule": "evenodd" }, "child": [] }] })(props);
60234
60234
  }
60235
+ function HiDotsHorizontal(props) {
60236
+ return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "d": "M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" }, "child": [] }] })(props);
60237
+ }
60235
60238
  function HiExclamationCircle(props) {
60236
60239
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", "clipRule": "evenodd" }, "child": [] }] })(props);
60237
60240
  }
@@ -77626,8 +77629,10 @@ const Tooltip2 = ({
77626
77629
  }
77627
77630
  ) }),
77628
77631
  open: isVisible2,
77629
- overlayStyle: {
77630
- pointerEvents: "none"
77632
+ styles: {
77633
+ root: {
77634
+ pointerEvents: "none"
77635
+ }
77631
77636
  },
77632
77637
  children: children2
77633
77638
  }
@@ -80497,10 +80502,13 @@ const OverflowMenuItem$1 = styled.div`
80497
80502
  const OverflowMenuItem = ({ children: children2, onClick }) => {
80498
80503
  return /* @__PURE__ */ jsx(OverflowMenuItem$1, { onClick, children: children2 });
80499
80504
  };
80505
+ const DefaultTrigger = () => {
80506
+ return /* @__PURE__ */ jsx(Button$1, { isIconButton: true, themeType: "secondary", size: "small", children: /* @__PURE__ */ jsx(HiDotsHorizontal, {}) });
80507
+ };
80500
80508
  const OverflowMenu = ({
80501
80509
  items,
80502
80510
  children: children2,
80503
- trigger,
80511
+ trigger = /* @__PURE__ */ jsx(DefaultTrigger, {}),
80504
80512
  isOpen: controlledIsOpen,
80505
80513
  onOpenChange,
80506
80514
  placement = "bottom",
@@ -80777,7 +80785,7 @@ const getCombinedPercent = (firstBarData, secondBarData) => {
80777
80785
  if (firstBarData?.value !== void 0 && secondBarData?.value !== void 0) {
80778
80786
  const total = firstBarData.value + secondBarData.value;
80779
80787
  const dividedBy = total / 2;
80780
- return Math.round(dividedBy * 10) / 10;
80788
+ return Math.round(dividedBy);
80781
80789
  }
80782
80790
  return firstBarData?.value || 0;
80783
80791
  };
@@ -83501,6 +83509,12 @@ const getGenesisClass$1 = ({ colors: colors2, borderRadius: borderRadius2, sizin
83501
83509
  background-color: ${components2.tableCell.selected} !important;
83502
83510
  color: #fff !important;
83503
83511
  }
83512
+
83513
+ .ant-table-tbody > tr.ant-table-row-pressed > td,
83514
+ .ant-table-tbody > tr.ant-table-row-pressed > .ant-table-cell {
83515
+ background-color: ${components2.tableCell.selected} !important;
83516
+ color: #fff !important;
83517
+ }
83504
83518
  `;
83505
83519
  };
83506
83520
  const Table$1 = styled(ForwardTable)`
@@ -83951,6 +83965,7 @@ function Table({
83951
83965
  size = "small",
83952
83966
  onChange,
83953
83967
  rowSelection,
83968
+ onRowClick,
83954
83969
  pagination,
83955
83970
  isMainContentCell = false,
83956
83971
  isMaterializedView = false,
@@ -83963,6 +83978,10 @@ function Table({
83963
83978
  const [dynamicHeight, setDynamicHeight] = React.useState(
83964
83979
  400
83965
83980
  );
83981
+ const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
83982
+ const [pressedRowKey, setPressedRowKey] = React.useState(
83983
+ null
83984
+ );
83966
83985
  const tableRef = React.useRef(null);
83967
83986
  const containerRef = React.useRef(null);
83968
83987
  React.useEffect(() => {
@@ -84065,6 +84084,60 @@ function Table({
84065
84084
  return rest.scroll;
84066
84085
  }, [isMaterializedView, materializedViewConfig, dynamicHeight, rest.scroll]);
84067
84086
  const tableDataSource = isMaterializedView ? materializedData : dataSource;
84087
+ const handleRowMouseDown = React.useCallback(
84088
+ (record, index2, event) => {
84089
+ const target = event.target;
84090
+ const isInteractiveElement = target.closest(
84091
+ 'button, a, input, select, textarea, [role="button"], [onclick], .ant-checkbox-wrapper, .ant-checkbox'
84092
+ );
84093
+ if (isInteractiveElement) {
84094
+ return;
84095
+ }
84096
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84097
+ setPressedRowKey(recordKey);
84098
+ },
84099
+ [rowKey]
84100
+ );
84101
+ const handleRowMouseUp = React.useCallback(
84102
+ (record, index2, event) => {
84103
+ setPressedRowKey(null);
84104
+ },
84105
+ []
84106
+ );
84107
+ const handleRowClick = React.useCallback(
84108
+ (record, index2, event) => {
84109
+ console.log("Row clicked:", record, "index:", index2);
84110
+ const target = event.target;
84111
+ const isInteractiveElement = target.closest(
84112
+ 'button, a, input, select, textarea, [role="button"], [onclick], .ant-checkbox-wrapper, .ant-checkbox'
84113
+ );
84114
+ console.log("Is interactive element:", isInteractiveElement);
84115
+ if (isInteractiveElement) {
84116
+ console.log("Skipping row click due to interactive element");
84117
+ return;
84118
+ }
84119
+ if (onRowClick) {
84120
+ onRowClick(record, index2, event);
84121
+ }
84122
+ },
84123
+ [onRowClick]
84124
+ );
84125
+ const enhancedRowSelection = React.useMemo(() => {
84126
+ if (!rowSelection) return;
84127
+ return {
84128
+ ...rowSelection,
84129
+ selectedRowKeys,
84130
+ // Use internal state
84131
+ // Override the onChange to ensure we get the latest data
84132
+ onChange: (selectedRowKeys2, selectedRows) => {
84133
+ console.log("Row selection changed:", selectedRowKeys2, selectedRows);
84134
+ setSelectedRowKeys(selectedRowKeys2);
84135
+ if (rowSelection.onChange) {
84136
+ rowSelection.onChange(selectedRowKeys2, selectedRows);
84137
+ }
84138
+ }
84139
+ };
84140
+ }, [rowSelection, selectedRowKeys]);
84068
84141
  return /* @__PURE__ */ jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsx(
84069
84142
  Table$1,
84070
84143
  {
@@ -84076,7 +84149,24 @@ function Table({
84076
84149
  locale: { emptyText: "No Data" },
84077
84150
  size,
84078
84151
  onChange,
84079
- rowSelection,
84152
+ rowSelection: enhancedRowSelection,
84153
+ onRow: (record, index2) => {
84154
+ const isDisabled = rowSelection?.getCheckboxProps?.(record)?.disabled ?? false;
84155
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84156
+ const isPressed = pressedRowKey === recordKey;
84157
+ return {
84158
+ onClick: (event) => handleRowClick(record, index2 ?? 0, event),
84159
+ onMouseDown: (event) => handleRowMouseDown(record, index2 ?? 0, event),
84160
+ onMouseUp: (event) => handleRowMouseUp(record, index2 ?? 0, event),
84161
+ onMouseLeave: () => setPressedRowKey(null),
84162
+ // Clear pressed state when mouse leaves
84163
+ style: {
84164
+ cursor: onRowClick ? "pointer" : "default",
84165
+ opacity: isDisabled ? 0.6 : 1
84166
+ },
84167
+ className: isPressed ? "ant-table-row-pressed" : ""
84168
+ };
84169
+ },
84080
84170
  pagination: paginationConfig,
84081
84171
  scroll: scrollConfig,
84082
84172
  onScroll: isMaterializedView ? handleScroll : void 0,
@@ -84090,6 +84180,7 @@ const TablePagination = ({
84090
84180
  dataSource,
84091
84181
  rowSelection,
84092
84182
  onChange,
84183
+ onRowClick,
84093
84184
  paginationStyle = PaginationStyle.SIMPLE,
84094
84185
  pageSize = 10,
84095
84186
  isMainContentCell
@@ -84108,6 +84199,7 @@ const TablePagination = ({
84108
84199
  dataSource: paginatedData,
84109
84200
  rowSelection,
84110
84201
  onChange,
84202
+ onRowClick,
84111
84203
  pagination: false,
84112
84204
  isMainContentCell
84113
84205
  }
@@ -84137,6 +84229,9 @@ const defaultRowSelection = (record) => ({
84137
84229
  });
84138
84230
  const useTable = (useTableConfig) => {
84139
84231
  const [isLoading, setLoading] = useState(true);
84232
+ const [hasErrored, setHasErrored] = useState(false);
84233
+ const hasFetchedRef = useRef(false);
84234
+ const isDisabledRef = useRef(false);
84140
84235
  const {
84141
84236
  columns,
84142
84237
  filters = null,
@@ -84163,14 +84258,39 @@ const useTable = (useTableConfig) => {
84163
84258
  error: null
84164
84259
  });
84165
84260
  const [selectedRows, setSelectedRows] = useState([]);
84261
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
84262
+ const memoizedFetchOptions = useMemo$1(
84263
+ () => fetchOptions,
84264
+ [fetchOptions.method, fetchOptions.headers, fetchOptions.body]
84265
+ );
84166
84266
  useEffect(() => {
84167
- if (disableAutoFetch && initialDataSource.length > 0) {
84267
+ if (disableAutoFetch) {
84268
+ isDisabledRef.current = true;
84269
+ setLoading(false);
84270
+ return;
84271
+ }
84272
+ if (hasFetchedRef.current || hasErrored || isDisabledRef.current) {
84168
84273
  setLoading(false);
84169
84274
  return;
84170
84275
  }
84171
84276
  const fetchData = async () => {
84172
84277
  try {
84173
- const response = await fetch(fetchUrl, fetchOptions);
84278
+ hasFetchedRef.current = true;
84279
+ const response = await fetch(fetchUrl, memoizedFetchOptions);
84280
+ if (response.status === 404) {
84281
+ console.warn(`Table data not found at ${fetchUrl}, stopping retries`);
84282
+ setHasErrored(true);
84283
+ setData({
84284
+ dataSource: initialDataSource,
84285
+ columns,
84286
+ error: new Error(`Data not found at ${fetchUrl}`)
84287
+ });
84288
+ setLoading(false);
84289
+ return;
84290
+ }
84291
+ if (!response.ok) {
84292
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
84293
+ }
84174
84294
  const result = await response.json();
84175
84295
  const sourceData = result.data || [];
84176
84296
  setOriginalData(sourceData);
@@ -84179,10 +84299,12 @@ const useTable = (useTableConfig) => {
84179
84299
  columns,
84180
84300
  error: null
84181
84301
  });
84302
+ setHasErrored(false);
84182
84303
  } catch (error2) {
84183
84304
  console.error("Error fetching table data:", error2);
84305
+ setHasErrored(true);
84184
84306
  setData({
84185
- dataSource: [],
84307
+ dataSource: initialDataSource,
84186
84308
  columns,
84187
84309
  error: error2 instanceof Error ? error2 : new Error(String(error2))
84188
84310
  });
@@ -84195,11 +84317,19 @@ const useTable = (useTableConfig) => {
84195
84317
  } else {
84196
84318
  fetchData();
84197
84319
  }
84198
- }, [fetchOptions, disableAutoFetch, initialDataSource]);
84320
+ }, [
84321
+ memoizedFetchOptions,
84322
+ disableAutoFetch,
84323
+ hasErrored,
84324
+ fetchUrl,
84325
+ columns,
84326
+ initialDataSource
84327
+ ]);
84199
84328
  const handleRowSelection = useCallback(
84200
- (selectedRowKeys, selectedRows2) => {
84201
- console.log("Row Selected:", selectedRowKeys, selectedRows2);
84202
- setSelectedRows(selectedRows2);
84329
+ (newSelectedRowKeys, newSelectedRows) => {
84330
+ console.log("Row Selected:", newSelectedRowKeys, newSelectedRows);
84331
+ setSelectedRowKeys(newSelectedRowKeys);
84332
+ setSelectedRows(newSelectedRows);
84203
84333
  },
84204
84334
  []
84205
84335
  );
@@ -84210,19 +84340,29 @@ const useTable = (useTableConfig) => {
84210
84340
  dataSource: newDataSource
84211
84341
  }));
84212
84342
  }, []);
84343
+ const retry = useCallback(() => {
84344
+ setHasErrored(false);
84345
+ hasFetchedRef.current = false;
84346
+ isDisabledRef.current = false;
84347
+ setLoading(true);
84348
+ }, []);
84213
84349
  const rowSelection = {
84214
84350
  type: selectionType,
84351
+ selectedRowKeys,
84215
84352
  onChange: handleRowSelection,
84216
84353
  getCheckboxProps: disableRowSelection
84217
84354
  };
84218
84355
  return {
84219
84356
  ...data,
84220
84357
  isLoading,
84358
+ hasErrored,
84221
84359
  rowSelection,
84222
84360
  selectedRows,
84361
+ selectedRowKeys,
84223
84362
  hasSettings,
84224
84363
  hasFilter,
84225
- updateDataSource
84364
+ updateDataSource,
84365
+ retry
84226
84366
  };
84227
84367
  };
84228
84368
  function HiMiniAdjustmentsVertical(props) {
@@ -84496,7 +84636,8 @@ const TableControls = ({
84496
84636
  const TableWithControls = ({
84497
84637
  tableData,
84498
84638
  tableControlsData: tableControlsData2,
84499
- onChange
84639
+ onChange,
84640
+ onRowClick
84500
84641
  }) => {
84501
84642
  const { primaryTableRowData, secondaryTableRowData } = tableControlsData2;
84502
84643
  const {
@@ -84533,6 +84674,7 @@ const TableWithControls = ({
84533
84674
  columns,
84534
84675
  rowSelection,
84535
84676
  onChange: onTableChange,
84677
+ onRowClick,
84536
84678
  isMaterializedView,
84537
84679
  materializedViewConfig
84538
84680
  }
@@ -84610,6 +84752,36 @@ const mockColumns = [
84610
84752
  isProgressCombined: true
84611
84753
  });
84612
84754
  }
84755
+ },
84756
+ {
84757
+ title: "Actions",
84758
+ key: "actions",
84759
+ render: (record) => {
84760
+ const menuItems = [
84761
+ {
84762
+ id: "edit",
84763
+ children: "Edit",
84764
+ onClick: () => {
84765
+ console.log("Edit clicked for record:", record.id);
84766
+ }
84767
+ },
84768
+ {
84769
+ id: "delete",
84770
+ children: "Delete",
84771
+ onClick: () => {
84772
+ console.log("Delete clicked for record:", record.id);
84773
+ }
84774
+ }
84775
+ ];
84776
+ return React__default.createElement(OverflowMenu, {
84777
+ items: menuItems,
84778
+ onItemClick: (item) => {
84779
+ if (item.onClick) {
84780
+ item.onClick();
84781
+ }
84782
+ }
84783
+ });
84784
+ }
84613
84785
  }
84614
84786
  ];
84615
84787
  mockColumns.map((column2) => ({
@@ -85019,9 +85191,10 @@ const startingUseTableConfig = {
85019
85191
  dataSource: []
85020
85192
  };
85021
85193
  const useTableWithControls = (tableConfig) => {
85022
- const [useTableConfig, setUseTableConfig] = useState(
85023
- startingUseTableConfig
85024
- );
85194
+ const [useTableConfig, setUseTableConfig] = useState(() => ({
85195
+ ...startingUseTableConfig,
85196
+ ...tableConfig
85197
+ }));
85025
85198
  const [groups, setGroups] = useState(
85026
85199
  tableControlsData.secondaryTableRowData.groups
85027
85200
  );
@@ -85032,20 +85205,22 @@ const useTableWithControls = (tableConfig) => {
85032
85205
  });
85033
85206
  const { secondaryTableRowData } = tableControlsData;
85034
85207
  const {
85035
- dataSource,
85208
+ dataSource: hookDataSource,
85036
85209
  columns,
85037
85210
  rowSelection,
85211
+ selectedRows,
85212
+ selectedRowKeys,
85038
85213
  hasSettings,
85039
85214
  hasFilter,
85040
85215
  updateDataSource
85041
85216
  } = useTable(useTableConfig);
85217
+ const dataSource = tableConfig.dataSource || hookDataSource;
85042
85218
  const safeDataSource = dataSource || [];
85043
85219
  const newSecondaryTableRowData = {
85044
85220
  ...secondaryTableRowData,
85045
85221
  groups,
85046
85222
  totalRecords: safeDataSource.length
85047
85223
  };
85048
- if (!dataSource) return null;
85049
85224
  const onGroupItemClick = (title, item) => {
85050
85225
  const newGroups = { ...groups };
85051
85226
  newGroups[title] = newGroups[title].filter((group) => group !== item);
@@ -85135,6 +85310,8 @@ const useTableWithControls = (tableConfig) => {
85135
85310
  dataSource: safeDataSource,
85136
85311
  columns,
85137
85312
  rowSelection,
85313
+ selectedRows,
85314
+ selectedRowKeys,
85138
85315
  updateDataSource
85139
85316
  };
85140
85317
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobolt/genesis",
3
- "version": "0.4.7",
3
+ "version": "0.4.10",
4
4
  "description": "genesis design system",
5
5
  "author": "gobolt",
6
6
  "license": "MIT",