mctable-react 1.0.0

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/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # mctable-react
2
+
3
+ React wrapper for the `mctable` package.
4
+
5
+ Base mctable: https://mormitech.com/mctable/
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install mctable-react
11
+ ```
12
+
13
+ `react` and `react-dom` are peer dependencies in your app.
14
+
15
+ ## Basic usage
16
+
17
+ Make sure the table container has an explicit size (height/width) so the table can render.
18
+
19
+ ```tsx
20
+ import * as React from "react";
21
+ import { McTable } from "mctable-react";
22
+ import "mctable-react/McTable.less";
23
+
24
+ const columns = [
25
+ { name: "id", title: "ID", type: "number" },
26
+ { name: "name", title: "Name", type: "text" },
27
+ { name: "active", title: "Active", type: "boolean" },
28
+ { name: "created", title: "Created", type: "date" },
29
+ ];
30
+
31
+ const records = [
32
+ { id: 1, name: "Ada", active: true, created: "2026-02-24" },
33
+ { id: 2, name: "Linus", active: false, created: "2026-02-23" },
34
+ ];
35
+
36
+ const settings = {
37
+ formatting: { displayDateFormat: "yyyy-MM-dd" },
38
+ paging: { pageSize: 25 },
39
+ scroll: { transition: "smooth" },
40
+ };
41
+
42
+ export function UsersTable() {
43
+ return (
44
+ <div style={{ height: 400 }}>
45
+ <McTable columns={columns} records={records} settings={settings} />
46
+ </div>
47
+ );
48
+ }
49
+ ```
50
+
51
+ You can also pass `settings`, `license`, or `onReady` if you need deeper access to the underlying `mctable` instance.
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import { MctColumn, MctInitSettings, MctLicense, McTable, MctApi } from 'mctable';
3
+ export { McTableCtor, MctApi, MctColumn, MctColumnData, MctInitSettings, MctLicense, MctRow, MctScrollPosition } from 'mctable';
4
+
5
+ type McTableReactHandle = {
6
+ table: McTable | null;
7
+ api: MctApi | null;
8
+ };
9
+ type McTableReactProps = {
10
+ records?: any[];
11
+ columns?: MctColumn[];
12
+ settings?: MctInitSettings;
13
+ license?: MctLicense;
14
+ onReady?: (table: McTable) => void;
15
+ className?: string;
16
+ style?: React.CSSProperties;
17
+ };
18
+ declare const McTableReact: React.ForwardRefExoticComponent<McTableReactProps & React.RefAttributes<McTableReactHandle>>;
19
+
20
+ export { McTableReact as McTable, McTableReact, type McTableReactHandle, type McTableReactProps };
package/dist/index.js ADDED
@@ -0,0 +1,170 @@
1
+ // src/McTable.tsx
2
+ import * as React from "react";
3
+ import { McTable } from "mctable";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var __sigIds = /* @__PURE__ */ new WeakMap();
6
+ var __nextSigId = 1;
7
+ function __getSigId(obj) {
8
+ const existing = __sigIds.get(obj);
9
+ if (existing !== void 0) return existing;
10
+ const next = __nextSigId++;
11
+ __sigIds.set(obj, next);
12
+ return next;
13
+ }
14
+ function __isPlainObject(value) {
15
+ if (!value || typeof value !== "object") return false;
16
+ const proto = Object.getPrototypeOf(value);
17
+ return proto === Object.prototype || proto === null;
18
+ }
19
+ function __signatureValue(value) {
20
+ if (value === null) return null;
21
+ const valueType = typeof value;
22
+ if (valueType === "string" || valueType === "number" || valueType === "boolean") return value;
23
+ if (valueType === "undefined") return ["u"];
24
+ if (valueType === "bigint") return ["bi", String(value)];
25
+ if (valueType === "symbol") return ["sy", String(value)];
26
+ if (valueType === "function") return ["fn", __getSigId(value)];
27
+ if (Array.isArray(value)) return value.map(__signatureValue);
28
+ if (value instanceof Date) return ["d", value.toISOString()];
29
+ if (!__isPlainObject(value)) {
30
+ return ["o", __getSigId(value), Object.prototype.toString.call(value)];
31
+ }
32
+ const obj = value;
33
+ const keys = Object.keys(obj).sort();
34
+ const out = {};
35
+ for (const key of keys) out[key] = __signatureValue(obj[key]);
36
+ return out;
37
+ }
38
+ function __stableSignature(value) {
39
+ try {
40
+ return JSON.stringify(__signatureValue(value));
41
+ } catch {
42
+ return "[unserializable]";
43
+ }
44
+ }
45
+ var __nextInstanceId = 1;
46
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
47
+ var McTableReact = React.forwardRef(
48
+ ({
49
+ records,
50
+ columns,
51
+ settings,
52
+ license,
53
+ onReady,
54
+ className,
55
+ style
56
+ }, ref) => {
57
+ const containerRef = React.useRef(null);
58
+ const tableRef = React.useRef(null);
59
+ const instanceIdRef = React.useRef(null);
60
+ const lastDataRef = React.useRef({
61
+ records: records ?? [],
62
+ columns: columns ?? []
63
+ });
64
+ const lastSigRef = React.useRef({
65
+ recordCount: (records ?? []).length,
66
+ columnsCount: (columns ?? []).length,
67
+ columnsSig: __stableSignature(columns ?? [])
68
+ });
69
+ const [readyTick, setReadyTick] = React.useState(0);
70
+ React.useImperativeHandle(
71
+ ref,
72
+ () => ({
73
+ table: tableRef.current,
74
+ api: tableRef.current?.api ?? null
75
+ }),
76
+ [readyTick]
77
+ );
78
+ useIsomorphicLayoutEffect(() => {
79
+ if (typeof window === "undefined") return;
80
+ if (tableRef.current) {
81
+ return;
82
+ }
83
+ const container = containerRef.current;
84
+ if (!container) {
85
+ return;
86
+ }
87
+ const instanceId = __nextInstanceId++;
88
+ instanceIdRef.current = instanceId;
89
+ const initialRecords = records ?? lastDataRef.current.records;
90
+ const initialColumns = columns ?? lastDataRef.current.columns;
91
+ const instance = new McTable({
92
+ container,
93
+ records: initialRecords,
94
+ columns: initialColumns,
95
+ settings,
96
+ license
97
+ });
98
+ tableRef.current = instance;
99
+ setReadyTick((x) => x + 1);
100
+ onReady?.(instance);
101
+ return () => {
102
+ const current = tableRef.current;
103
+ const currentInstanceId = instanceIdRef.current;
104
+ tableRef.current = null;
105
+ instanceIdRef.current = null;
106
+ setReadyTick((x) => x + 1);
107
+ try {
108
+ const anyTable = current;
109
+ if (typeof anyTable?.destroy === "function") anyTable.destroy();
110
+ else if (typeof anyTable?.dispose === "function") anyTable.dispose();
111
+ } catch {
112
+ }
113
+ if (containerRef.current) {
114
+ containerRef.current.innerHTML = "";
115
+ }
116
+ };
117
+ }, []);
118
+ React.useEffect(() => {
119
+ const table = tableRef.current;
120
+ if (!table) {
121
+ return;
122
+ }
123
+ const prevSig = lastSigRef.current;
124
+ const nextRecordCount = records !== void 0 ? records.length : prevSig.recordCount;
125
+ const nextColumnsCount = columns !== void 0 ? columns.length : prevSig.columnsCount;
126
+ const nextColumnsSig = columns !== void 0 ? __stableSignature(columns) : prevSig.columnsSig;
127
+ const recordCountChanged = records !== void 0 && nextRecordCount !== prevSig.recordCount;
128
+ const columnsChanged = columns !== void 0 && (nextColumnsCount !== prevSig.columnsCount || nextColumnsSig !== prevSig.columnsSig);
129
+ const didChange = recordCountChanged || columnsChanged;
130
+ if (records !== void 0) {
131
+ lastDataRef.current.records = records;
132
+ }
133
+ if (columns !== void 0) {
134
+ lastDataRef.current.columns = columns;
135
+ }
136
+ if (!didChange) {
137
+ return;
138
+ }
139
+ lastSigRef.current = {
140
+ recordCount: nextRecordCount,
141
+ columnsCount: nextColumnsCount,
142
+ columnsSig: nextColumnsSig
143
+ };
144
+ table.api.setData({
145
+ data: {
146
+ records: lastDataRef.current.records,
147
+ columns: lastDataRef.current.columns
148
+ }
149
+ });
150
+ }, [records, columns]);
151
+ React.useEffect(() => {
152
+ const table = tableRef.current;
153
+ if (!table) return;
154
+ if (!settings) return;
155
+ table.api.updateSettings(settings);
156
+ }, [settings]);
157
+ const combinedClassName = ["mctable-react", className].filter(Boolean).join(" ");
158
+ const combinedStyle = {
159
+ width: "100%",
160
+ height: "100%",
161
+ ...style
162
+ };
163
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className: combinedClassName, style: combinedStyle });
164
+ }
165
+ );
166
+ McTableReact.displayName = "McTable";
167
+ export {
168
+ McTableReact as McTable,
169
+ McTableReact
170
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "mctable-react",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./McTable.less": "./McTable.less"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "McTable.less"
19
+ ],
20
+ "scripts": {
21
+ "test": "echo \"Error: no test specified\" && exit 1",
22
+ "build": "tsup src/index.ts --format esm --dts --clean --out-dir dist --external react --external react-dom --external react/jsx-runtime --external react/jsx-dev-runtime",
23
+ "start": "vite --open",
24
+ "release:npm": "npm pack --pack-destination .",
25
+ "prepare": "npm run build",
26
+ "prepack": "npm run build"
27
+ },
28
+ "keywords": [],
29
+ "author": "",
30
+ "license": "ISC",
31
+ "peerDependencies": {
32
+ "react": "^18.0.0",
33
+ "react-dom": "^18.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/react": "^18.3.5",
37
+ "@types/react-dom": "^18.3.0",
38
+ "@vitejs/plugin-react": "^4.3.4",
39
+ "less": "^4.2.0",
40
+ "react": "^18.3.1",
41
+ "react-dom": "^18.3.1",
42
+ "tsup": "^8.5.1",
43
+ "typescript": "^5.9.3",
44
+ "vite": "^5.4.12"
45
+ },
46
+ "dependencies": {
47
+ "mctable": "^1.2.0"
48
+ }
49
+ }