@dmsi/wedgekit-react 0.0.369 → 0.0.371

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 (205) hide show
  1. package/dist/{chunk-RLLQRVM7.js → chunk-2H35FETR.js} +18 -10
  2. package/dist/chunk-2IKT6IHB.js +190 -0
  3. package/dist/chunk-4UNWXB4A.js +89 -0
  4. package/dist/chunk-5IFPG6TS.js +17 -0
  5. package/dist/{chunk-6GAYJCFE.js → chunk-6DPFKSCT.js} +1 -1
  6. package/dist/{chunk-ZFOANBWG.js → chunk-AG43RS4Q.js} +2 -1
  7. package/dist/chunk-AJ5M6MVX.js +7 -0
  8. package/dist/chunk-AT4AWD6B.js +44 -0
  9. package/dist/chunk-BQNPOGD5.js +105 -0
  10. package/dist/chunk-CQFPNZTN.js +172 -0
  11. package/dist/chunk-EJSPFQCY.js +29 -0
  12. package/dist/chunk-ER6RCOH3.js +97 -0
  13. package/dist/{chunk-4VER5OEU.js → chunk-FBE2HGEF.js} +35 -11
  14. package/dist/chunk-HPQWEZJL.js +45 -0
  15. package/dist/{chunk-URCLLHO5.js → chunk-IBX6DVHU.js} +376 -102
  16. package/dist/{chunk-I3WFZOFY.js → chunk-J5V2JRIK.js} +1 -1
  17. package/dist/chunk-JGJUVJKD.js +283 -0
  18. package/dist/chunk-KEMCFN4U.js +78 -0
  19. package/dist/chunk-M6TSTDNZ.js +22 -0
  20. package/dist/chunk-M7INAUAJ.js +140 -0
  21. package/dist/chunk-MBZ55T2D.js +51 -0
  22. package/dist/chunk-N6PNLLNS.js +77 -0
  23. package/dist/{chunk-ZA5E7ZYM.js → chunk-NXGUDYRR.js} +1 -1
  24. package/dist/chunk-P36QKH26.js +143 -0
  25. package/dist/chunk-PTRZHGHA.js +89 -0
  26. package/dist/chunk-QVWYTQKL.js +29 -0
  27. package/dist/{chunk-6CPGOW6J.js → chunk-T36HX6QY.js} +6 -4
  28. package/dist/chunk-U6PUOGG4.js +114 -0
  29. package/dist/{chunk-NQXZBWDZ.js → chunk-V6U7LU6M.js} +15 -6
  30. package/dist/chunk-VJVY6NPF.js +32 -0
  31. package/dist/chunk-VVXPGI2P.js +61 -0
  32. package/dist/{chunk-ARQBSR3I.js → chunk-YCKRVNJ3.js} +4 -4
  33. package/dist/chunk-YYHQLQDQ.js +68 -0
  34. package/dist/components/Accordion.cjs +47 -14
  35. package/dist/components/Accordion.js +2 -2
  36. package/dist/components/CalendarRange.cjs +700 -46
  37. package/dist/components/CalendarRange.css +186 -3
  38. package/dist/components/CalendarRange.js +43 -11
  39. package/dist/components/CompactImagesPreview.cjs +485 -0
  40. package/dist/components/CompactImagesPreview.js +13 -0
  41. package/dist/components/ContentTabs.cjs +3 -2
  42. package/dist/components/ContentTabs.js +3 -2
  43. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.cjs +4687 -0
  44. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.css +5051 -0
  45. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.js +62 -0
  46. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.cjs +4687 -0
  47. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.css +5051 -0
  48. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.js +62 -0
  49. package/dist/components/DataGrid/PinnedColumns.cjs +4687 -0
  50. package/dist/components/DataGrid/PinnedColumns.css +5051 -0
  51. package/dist/components/DataGrid/PinnedColumns.js +62 -0
  52. package/dist/components/DataGrid/TableBody/LoadingCell.cjs +4689 -0
  53. package/dist/components/DataGrid/TableBody/LoadingCell.css +5051 -0
  54. package/dist/components/DataGrid/TableBody/LoadingCell.js +62 -0
  55. package/dist/components/DataGrid/TableBody/TableBodyRow.cjs +4689 -0
  56. package/dist/components/DataGrid/TableBody/TableBodyRow.css +5051 -0
  57. package/dist/components/DataGrid/TableBody/TableBodyRow.js +62 -0
  58. package/dist/components/DataGrid/TableBody/index.cjs +4689 -0
  59. package/dist/components/DataGrid/TableBody/index.css +5051 -0
  60. package/dist/components/DataGrid/TableBody/index.js +62 -0
  61. package/dist/components/DataGrid/index.cjs +4692 -0
  62. package/dist/components/DataGrid/index.css +5051 -0
  63. package/dist/components/DataGrid/index.js +65 -0
  64. package/dist/components/DataGrid/utils.cjs +4687 -0
  65. package/dist/components/DataGrid/utils.css +5051 -0
  66. package/dist/components/DataGrid/utils.js +62 -0
  67. package/dist/components/DataGridCell.js +6 -6
  68. package/dist/components/DateInput.cjs +721 -67
  69. package/dist/components/DateInput.css +186 -3
  70. package/dist/components/DateInput.js +45 -13
  71. package/dist/components/DateRangeInput.cjs +721 -67
  72. package/dist/components/DateRangeInput.css +186 -3
  73. package/dist/components/DateRangeInput.js +45 -13
  74. package/dist/components/FilterGroup.js +3 -3
  75. package/dist/components/Grid.cjs +3 -1
  76. package/dist/components/Grid.js +3 -92
  77. package/dist/components/ImagePlaceholder.cjs +65 -0
  78. package/dist/components/ImagePlaceholder.js +7 -0
  79. package/dist/components/Input.js +2 -2
  80. package/dist/components/MenuOption.js +2 -2
  81. package/dist/components/MobileDataGrid/ColumnList.cjs +845 -0
  82. package/dist/components/MobileDataGrid/ColumnList.js +17 -0
  83. package/dist/components/MobileDataGrid/ColumnSelector/index.cjs +4797 -0
  84. package/dist/components/MobileDataGrid/ColumnSelector/index.css +5051 -0
  85. package/dist/components/MobileDataGrid/ColumnSelector/index.js +62 -0
  86. package/dist/components/MobileDataGrid/GridContextProvider/GridContext.cjs +31 -0
  87. package/dist/components/MobileDataGrid/GridContextProvider/GridContext.js +7 -0
  88. package/dist/components/MobileDataGrid/GridContextProvider/index.cjs +177 -0
  89. package/dist/components/MobileDataGrid/GridContextProvider/index.js +8 -0
  90. package/dist/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.cjs +269 -0
  91. package/dist/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.js +9 -0
  92. package/dist/components/MobileDataGrid/MobileDataGridCard/index.cjs +790 -0
  93. package/dist/components/MobileDataGrid/MobileDataGridCard/index.js +16 -0
  94. package/dist/components/MobileDataGrid/MobileDataGridHeader.cjs +5059 -0
  95. package/dist/components/MobileDataGrid/MobileDataGridHeader.css +5051 -0
  96. package/dist/components/MobileDataGrid/MobileDataGridHeader.js +62 -0
  97. package/dist/components/MobileDataGrid/RowDetailModalProvider/ModalContent.cjs +509 -0
  98. package/dist/components/MobileDataGrid/RowDetailModalProvider/ModalContent.js +13 -0
  99. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.cjs +1261 -0
  100. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.js +27 -0
  101. package/dist/components/MobileDataGrid/index.cjs +5521 -0
  102. package/dist/components/MobileDataGrid/index.css +5051 -0
  103. package/dist/components/MobileDataGrid/index.js +62 -0
  104. package/dist/components/Modal.cjs +24 -13
  105. package/dist/components/Modal.js +3 -3
  106. package/dist/components/ModalHeader.cjs +6 -4
  107. package/dist/components/ModalHeader.js +1 -1
  108. package/dist/components/ModalScrim.cjs +2 -1
  109. package/dist/components/ModalScrim.js +1 -1
  110. package/dist/components/NestedMenu.js +4 -4
  111. package/dist/components/Notification.cjs +15 -6
  112. package/dist/components/Notification.js +1 -1
  113. package/dist/components/PDFViewer/DownloadIcon.cjs +394 -0
  114. package/dist/components/PDFViewer/DownloadIcon.js +10 -0
  115. package/dist/components/PDFViewer/PDFElement.cjs +515 -0
  116. package/dist/components/PDFViewer/PDFElement.js +11 -0
  117. package/dist/components/{MobileDataGrid.cjs → PDFViewer/PDFNavigation.cjs} +318 -402
  118. package/dist/components/PDFViewer/PDFNavigation.js +13 -0
  119. package/dist/components/PDFViewer/PDFPage.cjs +56 -0
  120. package/dist/components/PDFViewer/PDFPage.js +7 -0
  121. package/dist/components/{PDFViewer.cjs → PDFViewer/index.cjs} +290 -202
  122. package/dist/components/PDFViewer/index.js +29 -0
  123. package/dist/components/Password.js +2 -2
  124. package/dist/components/ProductImagePreview/CarouselPagination.cjs +75 -0
  125. package/dist/components/ProductImagePreview/CarouselPagination.js +7 -0
  126. package/dist/components/ProductImagePreview/MobileImageCarousel.cjs +214 -0
  127. package/dist/components/ProductImagePreview/MobileImageCarousel.js +7 -0
  128. package/dist/components/ProductImagePreview/ProductPrimaryImage.cjs +255 -0
  129. package/dist/components/ProductImagePreview/ProductPrimaryImage.js +9 -0
  130. package/dist/components/ProductImagePreview/Thumbnail.cjs +105 -0
  131. package/dist/components/ProductImagePreview/Thumbnail.js +8 -0
  132. package/dist/components/ProductImagePreview/ZoomWindow.cjs +198 -0
  133. package/dist/components/ProductImagePreview/ZoomWindow.js +8 -0
  134. package/dist/components/ProductImagePreview/index.cjs +1369 -0
  135. package/dist/components/ProductImagePreview/index.js +22 -0
  136. package/dist/components/Search.js +3 -3
  137. package/dist/components/Select.js +3 -3
  138. package/dist/components/SideMenuGroup.cjs +15 -6
  139. package/dist/components/SideMenuGroup.js +1 -1
  140. package/dist/components/SideMenuItem.cjs +15 -6
  141. package/dist/components/SideMenuItem.js +1 -1
  142. package/dist/components/SkeletonParagraph.cjs +33 -0
  143. package/dist/components/SkeletonParagraph.js +10 -0
  144. package/dist/components/Stack.cjs +15 -6
  145. package/dist/components/Stack.js +1 -1
  146. package/dist/components/Stepper.cjs +61 -53
  147. package/dist/components/Stepper.js +63 -55
  148. package/dist/components/Surface.js +3 -39
  149. package/dist/components/Swatch.cjs +15 -6
  150. package/dist/components/Swatch.js +4 -4
  151. package/dist/components/Time.cjs +15 -6
  152. package/dist/components/Time.js +5 -5
  153. package/dist/components/Upload.cjs +15 -6
  154. package/dist/components/Upload.js +1 -1
  155. package/dist/components/index.cjs +2559 -14
  156. package/dist/components/index.css +186 -3
  157. package/dist/components/index.js +57 -14
  158. package/dist/index.css +186 -3
  159. package/package.json +1 -1
  160. package/src/components/Accordion.tsx +23 -4
  161. package/src/components/CompactImagesPreview.tsx +99 -0
  162. package/src/components/ContentTabs.tsx +3 -1
  163. package/src/components/DataGrid/types.ts +5 -0
  164. package/src/components/Grid.tsx +2 -0
  165. package/src/components/ImagePlaceholder.tsx +22 -0
  166. package/src/components/MobileDataGrid/ColumnList.tsx +66 -0
  167. package/src/components/MobileDataGrid/ColumnSelector/index.tsx +97 -0
  168. package/src/components/MobileDataGrid/GridContextProvider/GridContext.tsx +25 -0
  169. package/src/components/MobileDataGrid/GridContextProvider/index.tsx +132 -0
  170. package/src/components/MobileDataGrid/GridContextProvider/useGridContext.ts +10 -0
  171. package/src/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.tsx +20 -0
  172. package/src/components/MobileDataGrid/MobileDataGridCard/index.tsx +129 -0
  173. package/src/components/MobileDataGrid/MobileDataGridHeader.tsx +80 -0
  174. package/src/components/MobileDataGrid/RowDetailModalProvider/ModalContent.tsx +42 -0
  175. package/src/components/MobileDataGrid/RowDetailModalProvider/index.tsx +68 -0
  176. package/src/components/MobileDataGrid/dataGridReducer.ts +55 -0
  177. package/src/components/MobileDataGrid/index.tsx +92 -0
  178. package/src/components/MobileDataGrid/types.ts +4 -0
  179. package/src/components/Modal.tsx +31 -12
  180. package/src/components/ModalButtons.tsx +1 -1
  181. package/src/components/ModalHeader.tsx +5 -2
  182. package/src/components/ModalScrim.tsx +3 -2
  183. package/src/components/PDFViewer/DownloadIcon.tsx +22 -0
  184. package/src/components/PDFViewer/PDFElement.tsx +90 -0
  185. package/src/components/PDFViewer/PDFNavigation.tsx +68 -0
  186. package/src/components/PDFViewer/PDFPage.tsx +34 -0
  187. package/src/components/PDFViewer/index.tsx +128 -0
  188. package/src/components/ProductImagePreview/CarouselPagination.tsx +54 -0
  189. package/src/components/ProductImagePreview/MobileImageCarousel.tsx +226 -0
  190. package/src/components/ProductImagePreview/ProductPrimaryImage.tsx +218 -0
  191. package/src/components/ProductImagePreview/Thumbnail.tsx +49 -0
  192. package/src/components/ProductImagePreview/ZoomWindow.tsx +136 -0
  193. package/src/components/ProductImagePreview/index.tsx +182 -0
  194. package/src/components/ProductImagePreview/useProductImagePreview.ts +211 -0
  195. package/src/components/SkeletonParagraph.tsx +5 -0
  196. package/src/components/Stack.tsx +29 -6
  197. package/src/components/Stepper.tsx +5 -1
  198. package/src/components/index.ts +4 -0
  199. package/src/types.ts +2 -1
  200. package/dist/components/MobileDataGrid.js +0 -150
  201. package/dist/components/PDFViewer.js +0 -250
  202. package/src/components/MobileDataGrid.tsx +0 -163
  203. package/src/components/PDFViewer.tsx +0 -264
  204. package/dist/{chunk-OXSBIBGT.js → chunk-CKQNJNU3.js} +3 -3
  205. package/dist/{chunk-RJUN52HJ.js → chunk-ZL5X7KP6.js} +3 -3
@@ -0,0 +1,97 @@
1
+ import { useCallback, useRef, useState } from "react";
2
+ import { Button, Icon, Menu } from "../..";
3
+ import { Checkbox, MenuOption } from "../..";
4
+ import { useGridContext } from "../GridContextProvider/useGridContext";
5
+
6
+ export function ColumnSelector<T>() {
7
+ const context = useGridContext<T>();
8
+ const ref = useRef<HTMLDivElement>(null);
9
+ const [show, setShow] = useState(false);
10
+ const {
11
+ columns,
12
+ id,
13
+ testid,
14
+ visibleColumns,
15
+ numberOfColumnsToShow,
16
+ primaryKey,
17
+ resetColumnVisibility,
18
+ dispatch,
19
+ } = context;
20
+
21
+ const toggleColumnVisibility = useCallback(
22
+ (index: number, visible: boolean) => {
23
+ dispatch({ type: "UPDATE", index, payload: { meta: { visible } } });
24
+ },
25
+ [dispatch],
26
+ );
27
+
28
+ return (
29
+ <div
30
+ id={id ? `${id}-column-selector` : undefined}
31
+ data-testid={testid}
32
+ className="text-text-secondary-normal border-l border-brand-200 p-mobile-container-padding"
33
+ ref={ref}
34
+ >
35
+ <Button
36
+ id={id ? `${id}-button` : undefined}
37
+ testid={testid ? `${testid}-button` : undefined}
38
+ onClick={() => setShow((prev) => !prev)}
39
+ variant="navigation"
40
+ iconOnly
41
+ size={24}
42
+ leftIcon={<Icon name="tune" />}
43
+ ></Button>
44
+ <Menu
45
+ id={id ? `${id}-menu` : undefined}
46
+ testid={testid ? `${testid}-menu` : undefined}
47
+ positionTo={ref}
48
+ position="bottom-right"
49
+ show={show}
50
+ setShow={setShow}
51
+ calculateMinMaxHeight
52
+ >
53
+ <Button
54
+ id={id ? `${id}-reset-button` : undefined}
55
+ testid={testid ? `${testid}-reset-button` : undefined}
56
+ variant="tertiary"
57
+ onClick={() => {
58
+ resetColumnVisibility();
59
+ setShow(false);
60
+ }}
61
+ >
62
+ Reset to default
63
+ </Button>
64
+ {columns
65
+ .filter((x) => x.meta?.inVisibilityMenu)
66
+ .map((column) => (
67
+ <MenuOption
68
+ key={id ? `${id}-option-${column.id}` : undefined}
69
+ testid={testid ? `${testid}-option-${column.id}` : undefined}
70
+ >
71
+ <Checkbox
72
+ id={id ? `${id}-checkbox-${column.id}` : undefined}
73
+ testid={testid ? `${testid}-checkbox-${column.id}` : undefined}
74
+ label={column.header?.toString()}
75
+ checked={
76
+ !!column.meta?.visible || column.id === String(primaryKey)
77
+ }
78
+ disabled={
79
+ (typeof numberOfColumnsToShow !== "undefined" &&
80
+ // account for header+link occupying one slot
81
+ visibleColumns.length >= numberOfColumnsToShow - 1 &&
82
+ column.meta?.visible !== true) ||
83
+ column.id === String(primaryKey)
84
+ }
85
+ onChange={(e) => {
86
+ toggleColumnVisibility(
87
+ columns.findIndex(({ id }) => id === column.id),
88
+ e.target.checked,
89
+ );
90
+ }}
91
+ />
92
+ </MenuOption>
93
+ ))}
94
+ </Menu>
95
+ </div>
96
+ );
97
+ }
@@ -0,0 +1,25 @@
1
+ import { ColumnDef } from "@tanstack/react-table";
2
+ import { createContext, Dispatch } from "react";
3
+ import { Action } from "../dataGridReducer";
4
+
5
+ export type GridContextType<T = unknown> = {
6
+ columns: ColumnDef<T>[];
7
+ selectedRowIds: (string | number)[];
8
+ data: T[];
9
+ dispatch: Dispatch<Action<T>>;
10
+ getId: (data: T) => string | number | undefined;
11
+ resetColumnVisibility: () => void;
12
+ handleRowSelect: (item: T) => void;
13
+ handleRowSelectAll: () => void;
14
+ id?: string;
15
+ testid?: string;
16
+ numberOfColumnsToShow?: number;
17
+ visibleColumns: ColumnDef<T>[];
18
+ primaryKey?: keyof T;
19
+ isRowDetailOpen: boolean;
20
+ currentRow: T | null;
21
+ openRowDetail: (row: T) => void;
22
+ closeRowDetail: () => void;
23
+ };
24
+
25
+ export const GridContext = createContext<GridContextType | null>(null);
@@ -0,0 +1,132 @@
1
+ import { useCallback, useMemo, useReducer, useState } from "react";
2
+ import { dataGridReducer } from "../dataGridReducer";
3
+ import { GridContext, GridContextType } from "./GridContext";
4
+ import { ColumnDef } from "@tanstack/react-table";
5
+
6
+ type GridContextProps<T> = {
7
+ initialColumns: ColumnDef<T>[];
8
+ data: T[];
9
+ getId: (data: T) => string | number | undefined;
10
+ id?: string;
11
+ testid?: string;
12
+ children?: React.ReactNode;
13
+ onRowSelect?: (row: T, selectedIds: (string | number)[]) => void;
14
+ numberOfColumnsToShow?: number;
15
+ primaryKey?: keyof T;
16
+ };
17
+
18
+ export function GridContextProvider<T>(props: GridContextProps<T>) {
19
+ const {
20
+ initialColumns,
21
+ id,
22
+ testid,
23
+ children,
24
+ data,
25
+ numberOfColumnsToShow,
26
+ primaryKey,
27
+ getId,
28
+ onRowSelect,
29
+ } = props;
30
+ const [columns, dispatch] = useReducer(dataGridReducer<T>, initialColumns);
31
+ const [selectedRowIds, setSelectedRowIds] = useState<(string | number)[]>([]);
32
+ const [currentRow, setCurrentRow] = useState<T | null>(null);
33
+
34
+ const resetColumnVisibility = useCallback(() => {
35
+ // use initialColumns' meta?.visible data in columns.
36
+ const newColumns = columns.map((column) => {
37
+ const initialColumn = initialColumns.find((c) => c.id === column.id);
38
+ return {
39
+ ...column,
40
+ meta: {
41
+ ...column.meta,
42
+ visible: initialColumn?.meta?.visible,
43
+ },
44
+ };
45
+ });
46
+ dispatch({ type: "SET", payload: newColumns });
47
+ }, [columns, initialColumns]);
48
+
49
+ const handleRowSelect = useCallback(
50
+ (item: T) => {
51
+ const rowId = getId(item) ?? "";
52
+ if (!rowId) return;
53
+ const nextSelected = selectedRowIds.includes(rowId)
54
+ ? selectedRowIds.filter((id) => id !== rowId)
55
+ : [...selectedRowIds, rowId];
56
+
57
+ setSelectedRowIds(nextSelected);
58
+ if (onRowSelect) onRowSelect(item, nextSelected);
59
+ },
60
+ [getId, onRowSelect, selectedRowIds],
61
+ );
62
+
63
+ const handleRowSelectAll = useCallback(() => {
64
+ setSelectedRowIds((prev) => {
65
+ if (prev.length === data.length) {
66
+ // Select none
67
+ return [];
68
+ }
69
+ // Select all
70
+ return data.map(getId).filter((id) => id !== undefined);
71
+ });
72
+ }, [data, getId]);
73
+
74
+ const openRowDetail = useCallback((row: T) => {
75
+ setCurrentRow(row);
76
+ }, []);
77
+
78
+ const closeRowDetail = useCallback(() => {
79
+ setCurrentRow(null);
80
+ }, []);
81
+
82
+ const visibleColumns = useMemo(() => {
83
+ // header+link counts as the first column when limiting
84
+ const effectiveLimit =
85
+ typeof numberOfColumnsToShow === "number"
86
+ ? Math.max(numberOfColumnsToShow - 1, 0)
87
+ : undefined;
88
+ if (primaryKey) {
89
+ const pkColumn = columns.find((col) => col.id === String(primaryKey));
90
+ const otherColumns = columns.filter(
91
+ (col) => col.id !== String(primaryKey),
92
+ );
93
+ const orderedColumns = pkColumn
94
+ ? [pkColumn, ...otherColumns]
95
+ : [...otherColumns];
96
+ return orderedColumns
97
+ .filter((x) => x.meta?.visible !== false)
98
+ .slice(0, effectiveLimit);
99
+ }
100
+ return columns
101
+ .filter((x) => x.meta?.visible !== false)
102
+ .slice(0, effectiveLimit);
103
+ }, [columns, numberOfColumnsToShow, primaryKey]);
104
+
105
+ return (
106
+ <GridContext.Provider
107
+ value={
108
+ {
109
+ columns,
110
+ testid,
111
+ id,
112
+ data,
113
+ selectedRowIds,
114
+ visibleColumns,
115
+ numberOfColumnsToShow,
116
+ primaryKey,
117
+ dispatch,
118
+ getId,
119
+ resetColumnVisibility,
120
+ handleRowSelect,
121
+ handleRowSelectAll,
122
+ isRowDetailOpen: !!currentRow,
123
+ currentRow,
124
+ openRowDetail,
125
+ closeRowDetail,
126
+ } as GridContextType<unknown> | null
127
+ }
128
+ >
129
+ {children}
130
+ </GridContext.Provider>
131
+ );
132
+ }
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { GridContext, GridContextType } from "./GridContext";
3
+
4
+ export function useGridContext<T>() {
5
+ const ctx = useContext(GridContext) as GridContextType<T> | null;
6
+ if (!ctx) {
7
+ throw new Error("useGridContext must be used within GridContextProvider");
8
+ }
9
+ return ctx;
10
+ }
@@ -0,0 +1,20 @@
1
+ import { Paragraph } from "../../Paragraph";
2
+ import { ColumnDef } from "@tanstack/react-table";
3
+
4
+ export function MobileDataGridColumn<T extends Record<string, unknown>>(props: {
5
+ column: ColumnDef<T>;
6
+ data: T;
7
+ }) {
8
+ const { column, data } = props;
9
+
10
+ return (
11
+ <div className="mb-2 grid grid-cols-2 gap-2 px-3 flex-1">
12
+ <Paragraph color="text-secondary-normal" className="text-left">
13
+ {column.header?.toString()}:
14
+ </Paragraph>{" "}
15
+ {column.id && data[column.id]
16
+ ? (data[column.id] as React.ReactNode)
17
+ : null}
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,129 @@
1
+ import { Icon } from "../../Icon";
2
+ import { Paragraph } from "../../Paragraph";
3
+ import { Stack } from "../../Stack";
4
+ import { useGridContext } from "../GridContextProvider/useGridContext";
5
+ import { Checkbox } from "../../Checkbox";
6
+ import clsx from "clsx";
7
+ import { MobileDataGridColumn } from "./MobileDataGridColumn";
8
+ import { Subheader } from "../../Subheader";
9
+ import { RowActions } from "../types";
10
+
11
+ export function MobileDataGridCard<T extends Record<string, unknown>>({
12
+ renderLink,
13
+ renderChevron = true,
14
+ data,
15
+ enableRowSelection,
16
+ selected,
17
+ rowActions,
18
+ }: {
19
+ renderLink?: (data: T) => React.ReactNode;
20
+ renderChevron?: boolean;
21
+ data: T;
22
+ enableRowSelection?: boolean;
23
+ selected?: boolean;
24
+ rowActions?: RowActions<T>;
25
+ }) {
26
+ const context = useGridContext<T>();
27
+ const { id, testid, visibleColumns, getId, handleRowSelect, openRowDetail } =
28
+ context;
29
+
30
+ return (
31
+ <li
32
+ id={id ? `${id}-card-${getId(data)}` : undefined}
33
+ data-testid={testid ? `${testid}-card-${getId(data)}` : undefined}
34
+ className={clsx(
35
+ "hover:bg-action-100 cursor-pointer list-none",
36
+ selected ? "bg-action-100" : "bg-background-grouped-primary-normal",
37
+ )}
38
+ onClick={() => openRowDetail(data)}
39
+ >
40
+ <Stack sizing="component">
41
+ <Stack horizontal horizontalMobile items="center" justify="between">
42
+ {enableRowSelection && (
43
+ <Stack
44
+ sizing="component"
45
+ padding
46
+ width="fit"
47
+ onClick={(e) => e.stopPropagation()}
48
+ >
49
+ <Checkbox
50
+ id={id ? `${id}-${getId(data)}-select-checkbox` : undefined}
51
+ testid={
52
+ testid
53
+ ? `${testid}-${getId(data)}-select-checkbox`
54
+ : undefined
55
+ }
56
+ checked={selected}
57
+ onChange={() => handleRowSelect(data)}
58
+ />
59
+ </Stack>
60
+ )}
61
+ <Stack
62
+ sizing="component"
63
+ padding
64
+ onClick={(e) => e.stopPropagation()}
65
+ >
66
+ {renderLink ? (
67
+ renderLink(data)
68
+ ) : (
69
+ <Subheader>
70
+ {String(data[context.primaryKey as string] ?? "")}
71
+ </Subheader>
72
+ )}
73
+ </Stack>
74
+ <Stack
75
+ horizontal
76
+ horizontalMobile
77
+ items="center"
78
+ justify="end"
79
+ sizing="component"
80
+ onClick={(e) => e.stopPropagation()}
81
+ >
82
+ {rowActions &&
83
+ (typeof rowActions === "function"
84
+ ? rowActions(data)
85
+ : rowActions)}
86
+ </Stack>
87
+ </Stack>
88
+
89
+ <Stack sizing="layout-group">
90
+ {visibleColumns
91
+ .filter((x) => x.meta?.visible !== false && !x.id?.startsWith("__"))
92
+ .map((column, index) =>
93
+ column.meta?.useCustomRenderer &&
94
+ column.meta.mobileCell &&
95
+ column.id ? (
96
+ <div
97
+ key={`${column.id}-${index}`}
98
+ className="mb-2 grid grid-cols-2 gap-2 px-3 items-center flex-1"
99
+ >
100
+ <Paragraph
101
+ color="text-secondary-normal"
102
+ className="text-left"
103
+ >
104
+ {column.header?.toString()}:
105
+ </Paragraph>{" "}
106
+ <column.meta.mobileCell
107
+ column={column}
108
+ row={data}
109
+ cellValue={data[column.id]}
110
+ />
111
+ </div>
112
+ ) : (
113
+ <MobileDataGridColumn
114
+ key={`${column.id}-${index}`}
115
+ column={column}
116
+ data={data}
117
+ />
118
+ ),
119
+ )}
120
+ </Stack>
121
+ </Stack>
122
+ {renderChevron && (
123
+ <Stack items="center" justify="center" horizontal horizontalMobile>
124
+ <Icon name="keyboard_arrow_down" />
125
+ </Stack>
126
+ )}
127
+ </li>
128
+ );
129
+ }
@@ -0,0 +1,80 @@
1
+ import { Checkbox } from "../Checkbox";
2
+ import { Heading3 } from "../Heading";
3
+ import { Stack } from "../Stack";
4
+ import { Theme } from "../Theme";
5
+ import { ColumnSelector } from "./ColumnSelector";
6
+ import { GridContextType } from "./GridContextProvider/GridContext";
7
+ import { useGridContext } from "./GridContextProvider/useGridContext";
8
+
9
+ export function MobileDataGridHeader<T>({
10
+ header: Header,
11
+ enableColumnSelector,
12
+ enableRowSelection,
13
+ }: {
14
+ header?: string | ((ctx: GridContextType<T>) => React.ReactNode);
15
+ enableColumnSelector?: boolean;
16
+ enableRowSelection?: boolean;
17
+ }) {
18
+ const ctx = useGridContext<T>();
19
+ const {
20
+ id,
21
+ testid,
22
+ selectedRowIds,
23
+ data,
24
+ primaryKey,
25
+ columns,
26
+ handleRowSelectAll,
27
+ } = ctx;
28
+
29
+ if (typeof Header === "undefined" && !primaryKey) return null;
30
+ if (typeof Header === "function") return <Header {...ctx} />;
31
+ if (typeof Header === "string" || primaryKey)
32
+ return (
33
+ <div
34
+ id={id ? `${id}-header` : undefined}
35
+ data-testid={testid ? `${testid}-header` : undefined}
36
+ className="sticky top-0"
37
+ >
38
+ <Theme theme="brand">
39
+ <Stack
40
+ horizontal
41
+ horizontalMobile
42
+ items="center"
43
+ justify="between"
44
+ backgroundColor="background-primary-normal"
45
+ >
46
+ {enableRowSelection && (
47
+ <div className="p-mobile-component-padding border-r border-brand-200 max-w-fit h-full">
48
+ <Checkbox
49
+ id={id ? `${id}-select-all-checkbox` : undefined}
50
+ testid={testid ? `${testid}-select-all-checkbox` : undefined}
51
+ checked={selectedRowIds.length === data.length}
52
+ indeterminate={
53
+ !!selectedRowIds.length &&
54
+ selectedRowIds.length !== data.length
55
+ }
56
+ onChange={handleRowSelectAll}
57
+ />
58
+ </div>
59
+ )}
60
+ <Stack
61
+ horizontal
62
+ horizontalMobile
63
+ items="center"
64
+ sizing="component"
65
+ padding
66
+ >
67
+ <Heading3 as="span" color="text-primary-normal">
68
+ {typeof Header === "string"
69
+ ? Header
70
+ : columns
71
+ .find((col) => col.id === primaryKey)
72
+ ?.header?.toString()}
73
+ </Heading3>
74
+ </Stack>
75
+ {enableColumnSelector && <ColumnSelector />}
76
+ </Stack>
77
+ </Theme>
78
+ </div>
79
+ );
80
+ }
@@ -0,0 +1,42 @@
1
+ import { Paragraph } from "../../Paragraph";
2
+ import { Stack } from "../../Stack";
3
+ import { useGridContext } from "../GridContextProvider/useGridContext";
4
+ import { MobileDataGridColumn } from "../MobileDataGridCard/MobileDataGridColumn";
5
+
6
+ export function ModalContent() {
7
+ const context = useGridContext<Record<string, unknown>>();
8
+ const { columns, currentRow } = context;
9
+
10
+ if (!currentRow) return null;
11
+ return (
12
+ <Stack sizing="layout-group">
13
+ {columns
14
+ .filter((x) => !x.id?.startsWith("__"))
15
+ .map((column, index) =>
16
+ column.meta?.useCustomRenderer &&
17
+ column.meta.mobileCell &&
18
+ column.id ? (
19
+ <div
20
+ key={`${column.id}-${index}`}
21
+ className="mb-2 grid grid-cols-2 gap-2 px-3 items-center flex-1"
22
+ >
23
+ <Paragraph color="text-secondary-normal" className="text-left">
24
+ {column.header?.toString()}:
25
+ </Paragraph>{" "}
26
+ <column.meta.mobileCell
27
+ column={column}
28
+ row={currentRow}
29
+ cellValue={currentRow?.[column.id as string]}
30
+ />
31
+ </div>
32
+ ) : (
33
+ <MobileDataGridColumn
34
+ key={`${column.id}-${index}`}
35
+ column={column}
36
+ data={currentRow}
37
+ />
38
+ ),
39
+ )}
40
+ </Stack>
41
+ );
42
+ }
@@ -0,0 +1,68 @@
1
+ import { Button } from "../../Button";
2
+ import { Heading2 } from "../../Heading";
3
+ import { Icon } from "../../Icon";
4
+ import { Modal } from "../../Modal";
5
+ import { Stack } from "../../Stack";
6
+ import { useGridContext } from "../GridContextProvider/useGridContext";
7
+ import { ModalContent } from "./ModalContent";
8
+
9
+ export function RowDetailModalProvider() {
10
+ const context = useGridContext<Record<string, unknown>>();
11
+ const {
12
+ id,
13
+ testid,
14
+ isRowDetailOpen,
15
+ currentRow,
16
+ primaryKey,
17
+ closeRowDetail,
18
+ } = context;
19
+
20
+ // TODO: implement modal UI later
21
+ // Also verify if modal is opening in orders screen.doesn't seem to work in storybooks
22
+ return (
23
+ <Modal
24
+ fixedHeightScrolling
25
+ open={isRowDetailOpen}
26
+ onClose={closeRowDetail}
27
+ hideCloseIcon
28
+ size="medium"
29
+ className="!p-0"
30
+ headerIcon={
31
+ <Stack
32
+ horizontal
33
+ horizontalMobile
34
+ items="center"
35
+ justify="between"
36
+ width="full"
37
+ >
38
+ <Heading2>
39
+ {(currentRow?.[primaryKey ?? "id"] as string | undefined) ??
40
+ "Grid Detail"}
41
+ </Heading2>
42
+ <Button
43
+ id={id ? `${id}-open-in-new-button` : undefined}
44
+ testid={testid ? `${testid}-open-in-new-button` : undefined}
45
+ iconOnly
46
+ variant="tertiary"
47
+ onClick={closeRowDetail}
48
+ leftIcon={
49
+ <span className="text-icon-primary-normal contents">
50
+ <Icon name="open_in_new" size={24} />
51
+ </span>
52
+ }
53
+ />
54
+ </Stack>
55
+ }
56
+ customActions={
57
+ <Button onClick={closeRowDetail} className="w-full">
58
+ Close
59
+ </Button>
60
+ }
61
+ showButtons
62
+ >
63
+ <div className="bg-white max-h-full flex flex-col flex-grow-1">
64
+ <ModalContent />
65
+ </div>
66
+ </Modal>
67
+ );
68
+ }
@@ -0,0 +1,55 @@
1
+ import { ColumnDef } from "@tanstack/react-table";
2
+
3
+ export type Action<T> =
4
+ | {
5
+ payload: ColumnDef<T>[];
6
+ type: "SET";
7
+ }
8
+ | {
9
+ type: "INSERT";
10
+ pos: "LEADING" | "TRAILING";
11
+ payload: ColumnDef<T>;
12
+ }
13
+ | { type: "INSERT"; pos: "INDEX"; index: number; payload: ColumnDef<T> }
14
+ | {
15
+ type: "UPDATE";
16
+ index?: number;
17
+ id?: string | number;
18
+ payload: Partial<ColumnDef<T>>;
19
+ };
20
+ export function dataGridReducer<T>(
21
+ state: ColumnDef<T>[],
22
+ action: Action<T>,
23
+ ): ColumnDef<T>[] {
24
+ const { type, payload } = action;
25
+
26
+ let itemIndex: number | null = null;
27
+ if (action.type === "INSERT" && action.pos === "INDEX")
28
+ itemIndex = action.index;
29
+ if (action.type === "UPDATE")
30
+ itemIndex =
31
+ action.index ??
32
+ state.filter(({ id }) => !!id).findIndex(({ id }) => id === action.id);
33
+ switch (type) {
34
+ case "SET":
35
+ return [...payload];
36
+ case "UPDATE":
37
+ if (typeof itemIndex !== "number" || itemIndex < 0)
38
+ throw new Error("action.(id | index) must be provided.");
39
+
40
+ return [
41
+ ...state.slice(0, itemIndex),
42
+ {
43
+ ...state[itemIndex],
44
+ ...payload,
45
+ meta: {
46
+ ...(state[itemIndex].meta ?? {}),
47
+ ...(payload.meta ?? {}),
48
+ },
49
+ },
50
+ ...state.slice(itemIndex + 1),
51
+ ] as ColumnDef<T>[];
52
+ default:
53
+ throw new Error("Action type not implemented.");
54
+ }
55
+ }