qbs-react-grid 1.2.1 → 1.2.3

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 (62) hide show
  1. package/dist/css/qbs-react-grid.css +1 -1095
  2. package/dist/css/qbs-react-grid.min.css +1 -1
  3. package/dist/css/qbs-react-grid.min.css.map +1 -1
  4. package/es/Table.js +19 -19
  5. package/es/less/index.less +3 -0
  6. package/es/less/qbs-table.less +89 -22
  7. package/es/qbsTable/QbsTable.js +40 -7
  8. package/es/qbsTable/TableCardList.d.ts +5 -0
  9. package/es/qbsTable/TableCardList.js +564 -0
  10. package/es/qbsTable/Toolbar.js +21 -5
  11. package/es/qbsTable/commontypes.d.ts +12 -0
  12. package/es/qbsTable/utilities/CardComponent.d.ts +14 -0
  13. package/es/qbsTable/utilities/CardComponent.js +83 -0
  14. package/es/qbsTable/utilities/CardMenuDropdown.d.ts +13 -0
  15. package/es/qbsTable/utilities/CardMenuDropdown.js +93 -0
  16. package/es/qbsTable/utilities/SwitchCardColumns.d.ts +2 -0
  17. package/es/qbsTable/utilities/SwitchCardColumns.js +24 -0
  18. package/es/qbsTable/utilities/ToolTip.js +2 -5
  19. package/es/qbsTable/utilities/icons.d.ts +3 -0
  20. package/es/qbsTable/utilities/icons.js +45 -0
  21. package/es/qbsTable/utilities/store.d.ts +2 -0
  22. package/es/qbsTable/utilities/store.js +60 -0
  23. package/es/utils/getTotalByColumns.js +1 -1
  24. package/es/utils/mergeCells.js +1 -1
  25. package/es/utils/useCellDescriptor.js +11 -11
  26. package/es/utils/useClassNames.js +2 -0
  27. package/lib/Table.js +19 -19
  28. package/lib/less/index.less +3 -0
  29. package/lib/less/qbs-table.less +89 -22
  30. package/lib/qbsTable/QbsTable.js +40 -7
  31. package/lib/qbsTable/TableCardList.d.ts +5 -0
  32. package/lib/qbsTable/TableCardList.js +571 -0
  33. package/lib/qbsTable/Toolbar.js +20 -4
  34. package/lib/qbsTable/commontypes.d.ts +12 -0
  35. package/lib/qbsTable/utilities/CardComponent.d.ts +14 -0
  36. package/lib/qbsTable/utilities/CardComponent.js +91 -0
  37. package/lib/qbsTable/utilities/CardMenuDropdown.d.ts +13 -0
  38. package/lib/qbsTable/utilities/CardMenuDropdown.js +100 -0
  39. package/lib/qbsTable/utilities/SwitchCardColumns.d.ts +2 -0
  40. package/lib/qbsTable/utilities/SwitchCardColumns.js +30 -0
  41. package/lib/qbsTable/utilities/ToolTip.js +2 -5
  42. package/lib/qbsTable/utilities/icons.d.ts +3 -0
  43. package/lib/qbsTable/utilities/icons.js +50 -2
  44. package/lib/qbsTable/utilities/store.d.ts +2 -0
  45. package/lib/qbsTable/utilities/store.js +66 -0
  46. package/lib/utils/getTotalByColumns.js +1 -1
  47. package/lib/utils/mergeCells.js +1 -1
  48. package/lib/utils/useCellDescriptor.js +11 -11
  49. package/lib/utils/useClassNames.js +2 -0
  50. package/package.json +11 -6
  51. package/src/less/index.less +3 -0
  52. package/src/less/qbs-table.less +89 -22
  53. package/src/qbsTable/QbsTable.tsx +205 -173
  54. package/src/qbsTable/TableCardList.tsx +629 -0
  55. package/src/qbsTable/Toolbar.tsx +25 -4
  56. package/src/qbsTable/commontypes.ts +12 -0
  57. package/src/qbsTable/utilities/CardComponent.tsx +132 -0
  58. package/src/qbsTable/utilities/CardMenuDropdown.tsx +120 -0
  59. package/src/qbsTable/utilities/SwitchCardColumns.tsx +29 -0
  60. package/src/qbsTable/utilities/ToolTip.tsx +1 -4
  61. package/src/qbsTable/utilities/icons.tsx +51 -0
  62. package/src/qbsTable/utilities/store.ts +61 -0
@@ -9,6 +9,7 @@ export interface ColumnBase {
9
9
  field: string;
10
10
  sortable?: boolean;
11
11
  resizable?: boolean;
12
+ colSpan?: number;
12
13
  fixed?: boolean;
13
14
  align?: 'left' | 'right' | 'center';
14
15
  colWidth?: number;
@@ -46,6 +47,9 @@ export interface ActionProps {
46
47
  toolTip?: string;
47
48
  hidden?: boolean;
48
49
  hide?: (data: any, index?: number) => boolean;
50
+ isWarning?: boolean;
51
+ label?: string;
52
+ iconName?: string;
49
53
  }
50
54
 
51
55
  export interface QbsTableProps {
@@ -119,6 +123,10 @@ export interface QbsTableProps {
119
123
  renderEmpty?: (info: React.ReactNode) => React.ReactNode;
120
124
  emptySubTitle?: string;
121
125
  emptyTitle?: string;
126
+ enableTableToggle?: boolean;
127
+ tableView?: boolean;
128
+ cardColumLimit?: number;
129
+ childDetailHeading?: string;
122
130
  }
123
131
 
124
132
  export interface QbsTableToolbarProps {
@@ -144,6 +152,10 @@ export interface QbsTableToolbarProps {
144
152
  dataLength: number;
145
153
  headerHeight?: number;
146
154
  searchPlaceholder?: string;
155
+ tableView?: boolean;
156
+ enableTableToggle?: boolean;
157
+ tableViewToggle?: boolean;
158
+ setTableViewToggle?: (value: boolean) => void;
147
159
  selectedRowActions?: {
148
160
  actionTitle?: string;
149
161
  action: (checked: (number | string)[]) => void;
@@ -0,0 +1,132 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import { QbsColumnProps } from '../commontypes';
3
+ import CardMenuDropdown from './CardMenuDropdown';
4
+ import { CustomTableCell } from './SwitchCardColumns';
5
+ import { handleCellFormat } from './handleFormatCell';
6
+ import { ArrowUpIcon } from './icons';
7
+ import { getGridColsClass, getGridColSpanClass } from './store';
8
+ import TooltipComponent from './ToolTip';
9
+
10
+ type Props = {
11
+ columns: QbsColumnProps[];
12
+ data: any;
13
+ tableBodyRef: any;
14
+ actionProps?: any;
15
+ index?: number;
16
+ handleMenuActions?: () => void;
17
+ cardColumLimit?: number;
18
+ childDetailHeading?: string;
19
+ };
20
+
21
+ const CardComponent: React.FC<Props> = ({
22
+ columns,
23
+ data,
24
+ tableBodyRef,
25
+ actionProps,
26
+ index,
27
+ cardColumLimit = 5,
28
+ handleMenuActions,
29
+ childDetailHeading = ''
30
+ }) => {
31
+ const [viewMore, setViewMore] = useState(false);
32
+ const initialDisplayCount = cardColumLimit;
33
+
34
+ const toggleViewMore = () => {
35
+ setViewMore(!viewMore);
36
+ };
37
+ const useCardRef = useRef<HTMLDivElement>(null);
38
+ const displayedColumns = viewMore ? columns : columns.slice(0, initialDisplayCount);
39
+
40
+ return (
41
+ <div
42
+ ref={useCardRef}
43
+ className="p-3 gap-3 border-2 border-grey shadow-sm rounded-lg relative qbs-card-container"
44
+ >
45
+ <div className={`grid ${getGridColsClass(initialDisplayCount)} qbs-card-columns`}>
46
+ {displayedColumns.map((col: QbsColumnProps, index: number) => (
47
+ <div
48
+ key={index}
49
+ className={`grid ${getGridColSpanClass(
50
+ col.colSpan ?? 1
51
+ )} place-content-start text-sm qbs-card-column ${
52
+ index === initialDisplayCount - 1 ? 'mr-4' : ''
53
+ } `}
54
+ >
55
+ <p className=" text-grey ">{col.title}</p>
56
+ {col.customCell || col.link ? (
57
+ <span className={`qbs-card-column-content mt-1 ${!viewMore ? 'line-clamp-1' : ''}`}>
58
+ <CustomTableCell
59
+ dataKey={col.field}
60
+ rowData={data}
61
+ type={col.type}
62
+ path={col.getPath}
63
+ link={col.link}
64
+ viewMore={viewMore}
65
+ rowClick={col.rowClick}
66
+ renderCell={col.renderCell}
67
+ />
68
+ </span>
69
+ ) : (
70
+ <p
71
+ className={`mt-1 qbs-card-column-content ${!viewMore ? 'line-clamp-1' : ''}`}
72
+ key={index}
73
+ >
74
+ {handleCellFormat(data[col.field], col.type as string)}
75
+ </p>
76
+ )}
77
+ </div>
78
+ ))}
79
+
80
+ <div
81
+ className={`qbs-card-column-action absolute text-blue-500 mt-2 right-2 ${
82
+ columns.length > initialDisplayCount ? 'top-2' : 'top-4'
83
+ } text-xs`}
84
+ >
85
+ <div
86
+ className={`flex qbs-card-column-action-container
87
+ flex-col items-center gap-y-2
88
+ `}
89
+ >
90
+ <div className=" text-blue-500 qbs-card-column-action-menu ">
91
+ <CardMenuDropdown
92
+ tableBodyRef={tableBodyRef}
93
+ actionDropDown={actionProps}
94
+ rowData={data}
95
+ iconName="more"
96
+ rowIndex={index}
97
+ handleMenuActions={handleMenuActions}
98
+ />
99
+ </div>
100
+
101
+ {columns.length > initialDisplayCount && (
102
+ <TooltipComponent
103
+ tableBodyRef={useCardRef}
104
+ title={viewMore ? ' View Less' : 'View More'}
105
+ enabled={false}
106
+ >
107
+ <button
108
+ onClick={toggleViewMore}
109
+ className=" qbs-card-column-action-menu-view-more justify-end text-blue-500 text-xs"
110
+ >
111
+ <ArrowUpIcon className={`${viewMore ? 'rotate-180' : ''} `} />
112
+ </button>
113
+ </TooltipComponent>
114
+ )}
115
+ </div>
116
+ </div>
117
+ </div>
118
+ {viewMore && data?.childDetail && (
119
+ <div className="mt-4 p-3 border-t border-grey qbs-card-child-detail-container">
120
+ {childDetailHeading && (
121
+ <p className=" text-lg qbs-card-child-detail-head font-semibold ">
122
+ {childDetailHeading}
123
+ </p>
124
+ )}
125
+ {data?.childDetail}
126
+ </div>
127
+ )}
128
+ </div>
129
+ );
130
+ };
131
+
132
+ export default CardComponent;
@@ -0,0 +1,120 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import React from 'react';
3
+
4
+ import { ActionProps } from '../commontypes';
5
+ import { ThreeDotIcon } from './icons';
6
+ import TooltipComponent from './ToolTip';
7
+
8
+ type Props = {
9
+ iconName: string;
10
+ actionDropDown: ActionProps[];
11
+ handleMenuActions?: (slug: ActionProps, rowData?: any) => void;
12
+ rowData?: any;
13
+ dataTheme?: string;
14
+ tableBodyRef: React.RefObject<HTMLDivElement>;
15
+ rowIndex?: number;
16
+ };
17
+
18
+ const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions, rowData }) => {
19
+ const [openMenu, setOpenMenu] = useState(false);
20
+ const [menuPositionStyles, setMenuPositionStyles] = useState<{
21
+ top?: string;
22
+ bottom?: string;
23
+ right?: string;
24
+ }>({});
25
+ const menuButtonRef = useRef<HTMLButtonElement | null>(null);
26
+ const menuRef = useRef<HTMLDivElement | null>(null);
27
+
28
+ useEffect(() => {
29
+ const handleClickOutside = (event: MouseEvent) => {
30
+ if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
31
+ setOpenMenu(false);
32
+ }
33
+ };
34
+
35
+ document.addEventListener('click', handleClickOutside);
36
+
37
+ return () => {
38
+ document.removeEventListener('click', handleClickOutside);
39
+ };
40
+ }, []);
41
+
42
+ const toggleMenu = () => {
43
+ setOpenMenu(prevState => {
44
+ if (!prevState && menuButtonRef.current) {
45
+ const buttonRect = menuButtonRef.current.getBoundingClientRect();
46
+ const dropdownHeight = 200; // Adjust this if your dropdown height varies
47
+ const spaceBelow = window.innerHeight - buttonRect.bottom;
48
+ const spaceAbove = buttonRect.top;
49
+ console.log(spaceAbove, spaceBelow, dropdownHeight);
50
+ if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
51
+ setMenuPositionStyles({
52
+ bottom: '30px',
53
+ right: '10px'
54
+ });
55
+ } else {
56
+ setMenuPositionStyles({
57
+ top: `${buttonRect.height}px`,
58
+ right: '10px'
59
+ });
60
+ }
61
+ }
62
+ return !prevState;
63
+ });
64
+ };
65
+
66
+ const handleClose = () => {
67
+ setOpenMenu(false);
68
+ };
69
+
70
+ const handleMenuItemClick = (item: ActionProps) => {
71
+ item.action?.(item);
72
+ handleMenuActions?.(item, rowData);
73
+ handleClose();
74
+ };
75
+
76
+ return (
77
+ <div className="dropdown text-black dark:text-white dark:bg-[#424242] bg-white" ref={menuRef}>
78
+ <button className="dropdown-toggle" onClick={toggleMenu} ref={menuButtonRef}>
79
+ <TooltipComponent title="Actions" enabled={false} ref={menuButtonRef}>
80
+ <ThreeDotIcon />
81
+ </TooltipComponent>
82
+ </button>
83
+ {openMenu && (
84
+ <div
85
+ className=" qbs-card-dropdown rounded absolute right-0 mt-2 w-auto min-w-11 z-10 shadow-modalShadow bg-white dark:bg-[#424242] dark:text-white"
86
+ style={menuPositionStyles}
87
+ >
88
+ <div className="qbs-card-dropdown-menu px-2 bg-white rounded w-full border border-grey-border shadow-lg shadow-menudropdown dark:bg-[#424242] dark:text-white">
89
+ {actionDropDown?.map(
90
+ item =>
91
+ !item.hidden && (
92
+ <a
93
+ key={item.title}
94
+ href="#/"
95
+ className={'px-1 hover:bg-background no-underline whitespace-nowrap '}
96
+ onClick={e => {
97
+ e.preventDefault();
98
+ e.stopPropagation();
99
+ handleMenuItemClick(item);
100
+ }}
101
+ >
102
+ <div
103
+ className={` qbs-card-dropdown-menu-item no-underline ${
104
+ item.isWarning ? 'text-error-light' : ' text-black/70 dark:text-white'
105
+ } text-xxs flex items-center w-full tracking-[0.24px] font-medium `}
106
+ >
107
+ {item?.icon && <>{item.icon}</>}
108
+ <span className="pl-1.5 no-underline text-sm ">{'Edit this column'}</span>
109
+ </div>
110
+ </a>
111
+ )
112
+ )}
113
+ </div>
114
+ </div>
115
+ )}
116
+ </div>
117
+ );
118
+ };
119
+
120
+ export default CardMenuDropdown;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { Link } from 'react-router-dom';
3
+ import { handleCellFormat } from './handleFormatCell';
4
+
5
+ export const CustomTableCell: React.FC<any> = React.memo(
6
+ ({ rowData, renderCell, hideLink, dataKey, rowClick, type, path, link, viewMore }) => {
7
+ return (
8
+ <>
9
+ {link && !path && !hideLink?.(rowData) ? (
10
+ <a
11
+ onClick={() => rowClick?.(rowData)}
12
+ className={`qbs-table-row-link no-underline ${!viewMore ? 'line-clamp-1' : ''}`}
13
+ >
14
+ {renderCell ? renderCell(rowData)?.cell : handleCellFormat(rowData[dataKey], type)}
15
+ </a>
16
+ ) : path && !hideLink?.(rowData) ? (
17
+ <Link
18
+ to={path?.(rowData) ?? ''}
19
+ className={`qbs-table-row-link no-underline ${!viewMore ? 'line-clamp-1' : ''}`}
20
+ >
21
+ {renderCell ? renderCell(rowData)?.cell : handleCellFormat(rowData[dataKey], type)}
22
+ </Link>
23
+ ) : (
24
+ <>{renderCell ? renderCell(rowData)?.cell : handleCellFormat(rowData[dataKey], type)}</>
25
+ )}
26
+ </>
27
+ );
28
+ }
29
+ );
@@ -7,14 +7,11 @@ const TooltipComponent: React.FC<any> = ({ title, children, tableBodyRef }) => {
7
7
  const adjustDropdownPosition = () => {
8
8
  if (menuButtonRef.current && tableBodyRef?.current) {
9
9
  const inputBoxRect = menuButtonRef.current?.getBoundingClientRect();
10
- const viewportHeight = tableBodyRef?.current?.offsetHeight ?? window.innerHeight;
11
10
  const tableRect = tableBodyRef.current.getBoundingClientRect();
12
-
13
11
  // Calculate positions relative to the table
14
12
  const spaceAbove = inputBoxRect.top - tableRect.top;
15
13
  const spaceBelow = tableRect.bottom - inputBoxRect.bottom;
16
14
 
17
- console.log(viewportHeight, spaceAbove, spaceBelow);
18
15
  if (spaceAbove > spaceBelow) {
19
16
  setDropdownPosition('top-position');
20
17
  } else {
@@ -32,7 +29,7 @@ const TooltipComponent: React.FC<any> = ({ title, children, tableBodyRef }) => {
32
29
  >
33
30
  {children}
34
31
  </span>
35
- <span ref={dropRef} className={`tooltiptext `}>
32
+ <span ref={dropRef} className={'tooltiptext'}>
36
33
  {title}
37
34
  </span>
38
35
  </div>
@@ -36,3 +36,54 @@ export const SettingsIcon: React.FC<any> = () => {
36
36
  </svg>
37
37
  );
38
38
  };
39
+
40
+ export const ArrowUpIcon: React.FC<any> = ({ className }) => {
41
+ return (
42
+ <svg
43
+ xmlns="http://www.w3.org/2000/svg"
44
+ fill="none"
45
+ viewBox="0 0 24 24"
46
+ strokeWidth="3"
47
+ stroke="currentColor"
48
+ className={`${className} w-4 h-4`}
49
+ >
50
+ <path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
51
+ </svg>
52
+ );
53
+ };
54
+ export const TableIcon: React.FC<any> = ({ className }: any) => {
55
+ return (
56
+ <svg
57
+ xmlns="http://www.w3.org/2000/svg"
58
+ fill="none"
59
+ viewBox="0 0 24 24"
60
+ strokeWidth="1.5"
61
+ stroke="currentColor"
62
+ className={`${className} w-6 h-6`}
63
+ >
64
+ <path
65
+ strokeLinecap="round"
66
+ strokeLinejoin="round"
67
+ d="M2.25 8.25h19.5M2.25 9h19.5m-16.5 5.25h6m-6 2.25h3m-3.75 3h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25v10.5A2.25 2.25 0 0 0 4.5 19.5Z"
68
+ />
69
+ </svg>
70
+ );
71
+ };
72
+ export const CardIcon: React.FC<any> = ({ className }: any) => {
73
+ return (
74
+ <svg
75
+ xmlns="http://www.w3.org/2000/svg"
76
+ fill="none"
77
+ viewBox="0 0 24 24"
78
+ strokeWidth="1.5"
79
+ stroke="currentColor"
80
+ className={`${className} w-6 h-6`}
81
+ >
82
+ <path
83
+ strokeLinecap="round"
84
+ strokeLinejoin="round"
85
+ d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"
86
+ />
87
+ </svg>
88
+ );
89
+ };
@@ -0,0 +1,61 @@
1
+ export const getGridColsClass = (count: number) => {
2
+ switch (count) {
3
+ case 1:
4
+ return 'grid-cols-1';
5
+ case 2:
6
+ return 'grid-cols-2';
7
+ case 3:
8
+ return 'grid-cols-3';
9
+ case 4:
10
+ return 'grid-cols-4';
11
+ case 5:
12
+ return 'grid-cols-5';
13
+ case 6:
14
+ return 'grid-cols-6';
15
+ case 7:
16
+ return 'grid-cols-7';
17
+ case 8:
18
+ return 'grid-cols-8';
19
+ case 9:
20
+ return 'grid-cols-9';
21
+ case 10:
22
+ return 'grid-cols-10';
23
+ case 11:
24
+ return 'grid-cols-11';
25
+ case 12:
26
+ return 'grid-cols-12';
27
+ default:
28
+ return 'grid-cols-1';
29
+ }
30
+ };
31
+
32
+ export const getGridColSpanClass = (count: number) => {
33
+ switch (count) {
34
+ case 1:
35
+ return 'col-span-1';
36
+ case 2:
37
+ return 'col-span-2';
38
+ case 3:
39
+ return 'col-span-3';
40
+ case 4:
41
+ return 'col-span-4';
42
+ case 5:
43
+ return 'col-span-5';
44
+ case 6:
45
+ return 'col-span--6';
46
+ case 7:
47
+ return 'col-span--7';
48
+ case 8:
49
+ return 'col-span--8';
50
+ case 9:
51
+ return 'col-span--9';
52
+ case 10:
53
+ return 'col-span--10';
54
+ case 11:
55
+ return 'col-span--11';
56
+ case 12:
57
+ return 'col-span--12';
58
+ default:
59
+ return 'col-span--1';
60
+ }
61
+ };