tabler-react-2 0.1.153 → 0.1.154

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.
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.TableV2 = exports.SortIcon = exports.RangeText = exports.Pager = exports.PageSizeSelect = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var _reactTable = require("@tanstack/react-table");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
13
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
14
+ // TableV2.jsx
15
+ // TanStack Table v8 styled like the Original component's Tabler look.
16
+ // Adds `dense` mode for a compact layout.
17
+ // Controlled (server-side) pagination & sorting. ES modules, named exports, arrow functions only.
18
+
19
+ /** Small utilities */
20
+
21
+ var SortIcon = exports.SortIcon = function SortIcon(_ref) {
22
+ var state = _ref.state;
23
+ if (state === "asc") return /*#__PURE__*/_react["default"].createElement("span", {
24
+ "aria-label": "sorted ascending"
25
+ }, "\u25B2");
26
+ if (state === "desc") return /*#__PURE__*/_react["default"].createElement("span", {
27
+ "aria-label": "sorted descending"
28
+ }, "\u25BC");
29
+ return /*#__PURE__*/_react["default"].createElement("span", {
30
+ className: "text-muted",
31
+ "aria-hidden": true
32
+ }, "\u2195");
33
+ };
34
+ var RangeText = exports.RangeText = function RangeText(_ref2) {
35
+ var page = _ref2.page,
36
+ size = _ref2.size,
37
+ total = _ref2.total,
38
+ dense = _ref2.dense;
39
+ var start = total === 0 ? 0 : (page - 1) * size + 1;
40
+ var end = Math.min(page * size, total);
41
+ return /*#__PURE__*/_react["default"].createElement("span", {
42
+ className: dense ? "ms-2 small text-muted" : "ms-3 text-muted"
43
+ }, start.toLocaleString(), "\u2013", end.toLocaleString(), " of", " ", total.toLocaleString());
44
+ };
45
+ var PageSizeSelect = exports.PageSizeSelect = function PageSizeSelect(_ref3) {
46
+ var value = _ref3.value,
47
+ _onChange = _ref3.onChange,
48
+ _ref3$options = _ref3.options,
49
+ options = _ref3$options === void 0 ? [10, 25, 50, 100] : _ref3$options,
50
+ dense = _ref3.dense;
51
+ return /*#__PURE__*/_react["default"].createElement("select", {
52
+ className: dense ? "form-select form-select-sm" : "form-select",
53
+ value: value,
54
+ onChange: function onChange(e) {
55
+ return _onChange(Number(e.target.value));
56
+ },
57
+ "aria-label": "Rows per page",
58
+ style: {
59
+ width: dense ? 90 : 110
60
+ }
61
+ }, options.map(function (n) {
62
+ return /*#__PURE__*/_react["default"].createElement("option", {
63
+ key: n,
64
+ value: n
65
+ }, n, " / page");
66
+ }));
67
+ };
68
+ var Pager = exports.Pager = function Pager(_ref4) {
69
+ var page = _ref4.page,
70
+ size = _ref4.size,
71
+ total = _ref4.total,
72
+ onPageChange = _ref4.onPageChange,
73
+ disabled = _ref4.disabled,
74
+ _ref4$className = _ref4.className,
75
+ className = _ref4$className === void 0 ? "" : _ref4$className,
76
+ dense = _ref4.dense;
77
+ var totalPages = Math.max(1, Math.ceil(total / Math.max(1, size)));
78
+ var canPrev = page > 1 && !disabled;
79
+ var canNext = page < totalPages && !disabled;
80
+ var go = function go(p) {
81
+ var clamped = Math.min(Math.max(1, p), totalPages);
82
+ if (clamped !== page) onPageChange(clamped);
83
+ };
84
+ return /*#__PURE__*/_react["default"].createElement("div", {
85
+ className: "d-inline-flex align-items-center ".concat(dense ? "gap-2" : "", " ").concat(className)
86
+ }, /*#__PURE__*/_react["default"].createElement("button", {
87
+ className: "btn ".concat(dense ? "btn-sm" : "btn-sm", " ").concat(dense ? "px-2 py-1" : ""),
88
+ onClick: function onClick() {
89
+ return go(Math.max(1, page - 1));
90
+ },
91
+ disabled: !canPrev
92
+ }, "Previous"), /*#__PURE__*/_react["default"].createElement("button", {
93
+ className: "btn ".concat(dense ? "btn-sm ms-1" : "btn-sm ms-2", " ").concat(dense ? "px-2 py-1" : ""),
94
+ onClick: function onClick() {
95
+ return go(Math.min(totalPages, page + 1));
96
+ },
97
+ disabled: !canNext
98
+ }, "Next"), /*#__PURE__*/_react["default"].createElement("span", {
99
+ className: dense ? "ms-2 small text-muted" : "ms-3 text-muted"
100
+ }, "Page ", page, " of ", totalPages));
101
+ };
102
+
103
+ /** Main table */
104
+
105
+ var TableV2 = exports.TableV2 = function TableV2(_ref5) {
106
+ var columns = _ref5.columns,
107
+ data = _ref5.data,
108
+ totalRows = _ref5.totalRows,
109
+ page = _ref5.page,
110
+ size = _ref5.size,
111
+ onPageChange = _ref5.onPageChange,
112
+ onSizeChange = _ref5.onSizeChange,
113
+ sorting = _ref5.sorting,
114
+ onSortingChange = _ref5.onSortingChange,
115
+ getRowId = _ref5.getRowId,
116
+ rowSelection = _ref5.rowSelection,
117
+ onRowSelectionChange = _ref5.onRowSelectionChange,
118
+ _ref5$nowrap = _ref5.nowrap,
119
+ nowrap = _ref5$nowrap === void 0 ? false : _ref5$nowrap,
120
+ _ref5$stickyHeader = _ref5.stickyHeader,
121
+ stickyHeader = _ref5$stickyHeader === void 0 ? false : _ref5$stickyHeader,
122
+ _ref5$className = _ref5.className,
123
+ className = _ref5$className === void 0 ? "" : _ref5$className,
124
+ _ref5$tableClassName = _ref5.tableClassName,
125
+ tableClassName = _ref5$tableClassName === void 0 ? "" : _ref5$tableClassName,
126
+ _ref5$paginationClass = _ref5.paginationClassName,
127
+ paginationClassName = _ref5$paginationClass === void 0 ? "" : _ref5$paginationClass,
128
+ _ref5$parentClassName = _ref5.parentClassName,
129
+ parentClassName = _ref5$parentClassName === void 0 ? "" : _ref5$parentClassName,
130
+ _ref5$dense = _ref5.dense,
131
+ dense = _ref5$dense === void 0 ? false : _ref5$dense,
132
+ _ref5$emptyState = _ref5.emptyState,
133
+ emptyState = _ref5$emptyState === void 0 ? "No data" : _ref5$emptyState,
134
+ _ref5$loading = _ref5.loading,
135
+ loading = _ref5$loading === void 0 ? false : _ref5$loading,
136
+ _ref5$showPagination = _ref5.showPagination,
137
+ showPagination = _ref5$showPagination === void 0 ? true : _ref5$showPagination,
138
+ _ref5$pageSizeOptions = _ref5.pageSizeOptions,
139
+ pageSizeOptions = _ref5$pageSizeOptions === void 0 ? [10, 25, 50, 100] : _ref5$pageSizeOptions;
140
+ var table = (0, _reactTable.useReactTable)({
141
+ data: data,
142
+ columns: columns,
143
+ state: {
144
+ sorting: sorting,
145
+ rowSelection: rowSelection !== null && rowSelection !== void 0 ? rowSelection : {}
146
+ },
147
+ getCoreRowModel: (0, _reactTable.getCoreRowModel)(),
148
+ manualSorting: true,
149
+ enableSortingRemoval: false,
150
+ onSortingChange: onSortingChange,
151
+ getRowId: getRowId,
152
+ onRowSelectionChange: onRowSelectionChange
153
+ });
154
+ var headerCell = function headerCell(_ref6) {
155
+ var header = _ref6.header;
156
+ var canSort = header.column.getCanSort();
157
+ var sortState = header.column.getIsSorted();
158
+ var handleSort = function handleSort() {
159
+ if (!canSort) return;
160
+ var id = header.column.id;
161
+ var next = sortState === "asc" ? [{
162
+ id: id,
163
+ desc: true
164
+ }] : sortState === "desc" ? [] : [{
165
+ id: id,
166
+ desc: false
167
+ }];
168
+ onSortingChange(next);
169
+ };
170
+ var thClass = [header.column.columnDef.className || "", canSort ? "sortable" : "", dense ? "py-1" : ""].filter(Boolean).join(" ");
171
+ return /*#__PURE__*/_react["default"].createElement("th", {
172
+ key: header.id,
173
+ className: thClass,
174
+ onClick: canSort && !loading ? handleSort : undefined,
175
+ style: {
176
+ cursor: canSort && !loading ? "pointer" : "default"
177
+ },
178
+ "aria-sort": sortState === "asc" ? "ascending" : sortState === "desc" ? "descending" : "none"
179
+ }, /*#__PURE__*/_react["default"].createElement("span", {
180
+ style: {
181
+ marginRight: 8
182
+ }
183
+ }, (0, _reactTable.flexRender)(header.column.columnDef.header, header.getContext())), canSort && /*#__PURE__*/_react["default"].createElement(SortIcon, {
184
+ state: sortState || false
185
+ }));
186
+ };
187
+ var content = (0, _react.useMemo)(function () {
188
+ if (!loading && data.length === 0) {
189
+ return /*#__PURE__*/_react["default"].createElement("tr", null, /*#__PURE__*/_react["default"].createElement("td", {
190
+ colSpan: table.getAllLeafColumns().length,
191
+ className: "text-center ".concat(dense ? "py-3 small" : "py-3", " text-muted")
192
+ }, typeof emptyState === "function" ? emptyState() : emptyState));
193
+ }
194
+ return table.getRowModel().rows.map(function (row) {
195
+ return /*#__PURE__*/_react["default"].createElement("tr", {
196
+ key: row.id,
197
+ className: [row.getIsSelected() ? "table-active" : "", dense ? "align-middle" : ""].filter(Boolean).join(" ")
198
+ }, row.getVisibleCells().map(function (cell) {
199
+ return /*#__PURE__*/_react["default"].createElement("td", {
200
+ key: cell.id,
201
+ className: [cell.column.columnDef.className || "", dense ? "py-1" : ""].filter(Boolean).join(" ")
202
+ }, (0, _reactTable.flexRender)(cell.column.columnDef.cell, cell.getContext()));
203
+ }));
204
+ });
205
+ }, [data, loading, emptyState, table, dense]);
206
+ var total = totalRows !== null && totalRows !== void 0 ? totalRows : 0;
207
+ return /*#__PURE__*/_react["default"].createElement("div", {
208
+ className: parentClassName
209
+ }, /*#__PURE__*/_react["default"].createElement("div", {
210
+ className: "table-responsive ".concat(nowrap ? "table-nowrap" : "", " ").concat(className)
211
+ }, /*#__PURE__*/_react["default"].createElement("table", {
212
+ className: ["table table-vcenter", stickyHeader ? "sticky-top" : "", dense ? "table-sm" : "", tableClassName].filter(Boolean).join(" ")
213
+ }, /*#__PURE__*/_react["default"].createElement("thead", null, table.getHeaderGroups().map(function (hg) {
214
+ return /*#__PURE__*/_react["default"].createElement("tr", {
215
+ key: hg.id
216
+ }, hg.headers.map(function (h) {
217
+ return headerCell({
218
+ header: h
219
+ });
220
+ }));
221
+ })), /*#__PURE__*/_react["default"].createElement("tbody", null, loading && /*#__PURE__*/_react["default"].createElement("tr", null, /*#__PURE__*/_react["default"].createElement("td", {
222
+ colSpan: table.getAllLeafColumns().length,
223
+ className: "text-center ".concat(dense ? "py-2" : "py-3")
224
+ }, /*#__PURE__*/_react["default"].createElement("span", {
225
+ className: "spinner-border spinner-border-sm me-2",
226
+ role: "status",
227
+ "aria-hidden": true
228
+ }), /*#__PURE__*/_react["default"].createElement("span", {
229
+ className: dense ? "small text-muted" : "text-muted"
230
+ }, "Loading\u2026"))), content))), showPagination && /*#__PURE__*/_react["default"].createElement("div", {
231
+ className: "d-flex justify-content-between align-items-center ".concat(dense ? "mt-1" : "mt-2", " ").concat(paginationClassName)
232
+ }, /*#__PURE__*/_react["default"].createElement("div", {
233
+ className: "d-flex align-items-center ".concat(dense ? "gap-2" : "")
234
+ }, /*#__PURE__*/_react["default"].createElement(Pager, {
235
+ page: page,
236
+ size: size,
237
+ total: total,
238
+ onPageChange: onPageChange,
239
+ disabled: loading,
240
+ dense: dense
241
+ }), /*#__PURE__*/_react["default"].createElement(RangeText, {
242
+ page: page,
243
+ size: size,
244
+ total: total,
245
+ dense: dense
246
+ })), /*#__PURE__*/_react["default"].createElement(PageSizeSelect, {
247
+ value: size,
248
+ onChange: function onChange(n) {
249
+ onSizeChange === null || onSizeChange === void 0 || onSizeChange(n);
250
+ },
251
+ options: pageSizeOptions,
252
+ dense: dense
253
+ })));
254
+ };
255
+
256
+ /** PropTypes */
257
+
258
+ SortIcon.propTypes = {
259
+ state: _propTypes["default"].oneOf(["asc", "desc", false])
260
+ };
261
+ RangeText.propTypes = {
262
+ page: _propTypes["default"].number.isRequired,
263
+ size: _propTypes["default"].number.isRequired,
264
+ total: _propTypes["default"].number.isRequired,
265
+ dense: _propTypes["default"].bool
266
+ };
267
+ PageSizeSelect.propTypes = {
268
+ value: _propTypes["default"].number.isRequired,
269
+ onChange: _propTypes["default"].func.isRequired,
270
+ options: _propTypes["default"].arrayOf(_propTypes["default"].number),
271
+ dense: _propTypes["default"].bool
272
+ };
273
+ Pager.propTypes = {
274
+ page: _propTypes["default"].number.isRequired,
275
+ size: _propTypes["default"].number.isRequired,
276
+ total: _propTypes["default"].number.isRequired,
277
+ onPageChange: _propTypes["default"].func.isRequired,
278
+ disabled: _propTypes["default"].bool,
279
+ className: _propTypes["default"].string,
280
+ dense: _propTypes["default"].bool
281
+ };
282
+ TableV2.propTypes = {
283
+ columns: _propTypes["default"].array.isRequired,
284
+ data: _propTypes["default"].array.isRequired,
285
+ totalRows: _propTypes["default"].number.isRequired,
286
+ page: _propTypes["default"].number.isRequired,
287
+ size: _propTypes["default"].number.isRequired,
288
+ onPageChange: _propTypes["default"].func.isRequired,
289
+ onSizeChange: _propTypes["default"].func.isRequired,
290
+ sorting: _propTypes["default"].arrayOf(_propTypes["default"].shape({
291
+ id: _propTypes["default"].string.isRequired,
292
+ desc: _propTypes["default"].bool
293
+ })).isRequired,
294
+ onSortingChange: _propTypes["default"].func.isRequired,
295
+ getRowId: _propTypes["default"].func,
296
+ rowSelection: _propTypes["default"].object,
297
+ onRowSelectionChange: _propTypes["default"].func,
298
+ nowrap: _propTypes["default"].bool,
299
+ stickyHeader: _propTypes["default"].bool,
300
+ className: _propTypes["default"].string,
301
+ tableClassName: _propTypes["default"].string,
302
+ paginationClassName: _propTypes["default"].string,
303
+ parentClassName: _propTypes["default"].string,
304
+ emptyState: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
305
+ loading: _propTypes["default"].bool,
306
+ showPagination: _propTypes["default"].bool,
307
+ pageSizeOptions: _propTypes["default"].arrayOf(_propTypes["default"].number),
308
+ dense: _propTypes["default"].bool // <<< NEW
309
+ };
310
+
311
+ /** Usage (server-side)
312
+ *
313
+ * <TableV2
314
+ * dense // compact mode
315
+ * columns={columns}
316
+ * data={data}
317
+ * totalRows={total}
318
+ * page={page}
319
+ * size={size}
320
+ * onPageChange={setPage}
321
+ * onSizeChange={(n)=>{ setPage(1); setSize(n); }}
322
+ * sorting={sorting}
323
+ * onSortingChange={(next)=>{ setPage(1); setSorting(next); }}
324
+ * loading={loading}
325
+ * nowrap
326
+ * stickyHeader
327
+ * />
328
+ */
@@ -0,0 +1,36 @@
1
+ const path = require("path");
2
+
3
+ exports.onCreateWebpackConfig = ({ stage, actions, loaders }) => {
4
+ // Only alias to source during local development unless explicitly enabled
5
+ const enableSourceAlias =
6
+ stage === "develop" || process.env.DOCS_USE_SRC === "1";
7
+
8
+ if (!enableSourceAlias) return;
9
+
10
+ actions.setWebpackConfig({
11
+ resolve: {
12
+ alias: {
13
+ // Use library source directly during docs development
14
+ "tabler-react-2": path.resolve(__dirname, "../src"),
15
+
16
+ // Ensure a single React/DOM instance (avoid hooks mismatch)
17
+ react: path.resolve(__dirname, "node_modules/react"),
18
+ "react-dom": path.resolve(__dirname, "node_modules/react-dom"),
19
+ // Route dependency to the docs install so resolution is stable
20
+ "react-router-dom": path.resolve(
21
+ __dirname,
22
+ "node_modules/react-router-dom"
23
+ ),
24
+ },
25
+ },
26
+ module: {
27
+ rules: [
28
+ {
29
+ test: /\.jsx?$/,
30
+ include: [path.resolve(__dirname, "../src")],
31
+ use: [loaders.js()],
32
+ },
33
+ ],
34
+ },
35
+ });
36
+ };
package/docs/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "react": "^18.2.0",
23
23
  "react-dom": "^18.2.0",
24
24
  "styled-components": "^6.1.15",
25
- "tabler-react-2": "^0.1.140"
25
+ "tabler-react-2": "0.1.153-alpha.0"
26
26
  },
27
27
  "devDependencies": {},
28
28
  "keywords": [
@@ -57,6 +57,9 @@ export const Table = loadable(() =>
57
57
  export const Timeline = loadable(() =>
58
58
  import("tabler-react-2").then((mod) => mod.Timeline)
59
59
  );
60
+ export const TableV2 = loadable(() =>
61
+ import("tabler-react-2").then((mod) => mod.TableV2)
62
+ );
60
63
 
61
64
  // Util
62
65
  const Hr = loadable(() => import("tabler-react-2").then((mod) => mod.Util.Hr));
@@ -1,63 +1,140 @@
1
- import React, { useEffect, useRef, useState } from "react";
1
+ import React, { useEffect, useMemo, useRef, useState } from "react";
2
2
  import ReactDOM from "react-dom";
3
3
 
4
- export const Tabler = ({ children }) => {
5
- const containerRef = useRef(null);
6
- const shadowRef = useRef(null);
7
- const [wrapper, setWrapper] = useState(null);
4
+ const TABLER_CSS_URL =
5
+ "https://cdn.jsdelivr.net/npm/@tabler/core@1.3.0/dist/css/tabler.min.css";
6
+ const TABLER_JS_URL =
7
+ "https://cdn.jsdelivr.net/npm/@tabler/core@1.3.0/dist/js/tabler.min.js";
8
+
9
+ /**
10
+ * <Tabler>
11
+ * Same public API as before:
12
+ * - children
13
+ * - theme?: "light" | "dark" (defaults to "light")
14
+ * Also accepts className and style for the outer iframe element.
15
+ */
16
+ export const Tabler = ({
17
+ children,
18
+ theme = "light",
19
+ className,
20
+ style,
21
+ headExtras = "",
22
+ cssUrl = TABLER_CSS_URL,
23
+ jsUrl = TABLER_JS_URL,
24
+ }) => {
25
+ const iframeRef = useRef(null);
26
+ const [mountNode, setMountNode] = useState(null);
27
+ const roRef = useRef(null);
28
+
29
+ const srcDoc = useMemo(() => {
30
+ const t = theme === "dark" ? "dark" : "light";
31
+ return `<!DOCTYPE html>
32
+ <html lang="en" data-bs-theme="${t}">
33
+ <head>
34
+ <meta charset="utf-8" />
35
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
36
+ <link rel="stylesheet" href="${cssUrl}">
37
+ ${headExtras}
38
+ <style>
39
+ html, body { margin: 0; padding: 0; }
40
+ body { display: block; background-color: transparent!important; }
41
+ #app { min-height: 0; }
42
+ </style>
43
+ </head>
44
+ <body>
45
+ <div id="app"></div>
46
+ </body>
47
+ </html>`;
48
+ }, [cssUrl, headExtras, theme]);
8
49
 
9
50
  useEffect(() => {
10
- const initialize = async () => {
11
- if (containerRef.current && !shadowRef.current) {
12
- // Create a shadow root for this instance
13
- const shadowRoot = containerRef.current.attachShadow({ mode: "open" });
14
- shadowRef.current = shadowRoot;
15
-
16
- // Inject Tabler stylesheet
17
- const styleLink = document.createElement("link");
18
- styleLink.rel = "stylesheet";
19
- styleLink.href =
20
- "https://cdn.jsdelivr.net/npm/@tabler/core@1.3.2/dist/css/tabler.min.css";
21
-
22
- // Create a wrapper div for children
23
- const wrapperDiv = document.createElement("div");
24
- wrapperDiv.style.display = "inline-block";
25
- wrapperDiv.style.width = "auto";
26
- wrapperDiv.style.height = "auto";
27
-
28
- shadowRoot.appendChild(styleLink);
29
- shadowRoot.appendChild(wrapperDiv);
30
- setWrapper(wrapperDiv);
31
-
32
- // Load and run Tabler script in an isolated context
51
+ const iframe = iframeRef.current;
52
+ if (!iframe) return;
53
+
54
+ iframe.srcdoc = srcDoc;
55
+
56
+ const onLoad = () => {
57
+ const doc = iframe.contentDocument;
58
+ const win = iframe.contentWindow;
59
+ if (!doc || !win) return;
60
+
61
+ // Ensure theme attribute is correct
62
+ doc.documentElement.setAttribute(
63
+ "data-bs-theme",
64
+ theme === "dark" ? "dark" : "light"
65
+ );
66
+
67
+ const app = doc.getElementById("app");
68
+ setMountNode(app || null);
69
+
70
+ // Inject Tabler JS in iframe context
71
+ const s = doc.createElement("script");
72
+ s.src = jsUrl;
73
+ s.defer = true;
74
+ doc.head.appendChild(s);
75
+
76
+ // Auto-resize to content
77
+ if (roRef.current) {
33
78
  try {
34
- const response = await fetch("/tabler.min.js");
35
- const scriptText = await response.text();
36
-
37
- // Wrap the code in a function that temporarily sets window.SHADOW_DOC
38
- const runTablerScript = new Function(
39
- "shadowRoot",
40
- `
41
- window.USE_FALLBACK_ANCHOR = true;
42
- const originalShadowDoc = window.SHADOW_DOC;
43
- window.SHADOW_DOC = shadowRoot;
44
- ${scriptText}
45
- window.SHADOW_DOC = originalShadowDoc;
46
- `
47
- );
48
- runTablerScript(shadowRoot);
49
- } catch (err) {
50
- console.error("Failed to load Tabler script:", err);
51
- }
79
+ roRef.current.disconnect();
80
+ } catch {}
52
81
  }
82
+ const ro = new win.ResizeObserver(() => {
83
+ const h =
84
+ doc.documentElement.scrollHeight ||
85
+ doc.body.scrollHeight ||
86
+ app?.scrollHeight ||
87
+ 0;
88
+ // iframe.style.height = `${Math.ceil(h) + 1}px`;
89
+ });
90
+ roRef.current = ro;
91
+ ro.observe(doc.documentElement);
92
+
93
+ // Initial sizing tick
94
+ setTimeout(() => {
95
+ const h =
96
+ doc.documentElement.scrollHeight ||
97
+ doc.body.scrollHeight ||
98
+ app?.scrollHeight ||
99
+ 0;
100
+ iframe.style.height = `${Math.ceil(h) + 1}px`;
101
+ }, 0);
53
102
  };
54
103
 
55
- initialize();
56
- }, []);
104
+ iframe.addEventListener("load", onLoad);
105
+ return () => {
106
+ iframe.removeEventListener("load", onLoad);
107
+ if (roRef.current) {
108
+ try {
109
+ roRef.current.disconnect();
110
+ } catch {}
111
+ roRef.current = null;
112
+ }
113
+ setMountNode(null);
114
+ };
115
+ }, [srcDoc, jsUrl, theme]);
116
+
117
+ // Keep theme in sync if it changes
118
+ useEffect(() => {
119
+ const doc = iframeRef.current?.contentDocument;
120
+ if (doc) {
121
+ doc.documentElement.setAttribute(
122
+ "data-bs-theme",
123
+ theme === "dark" ? "dark" : "light"
124
+ );
125
+ }
126
+ }, [theme]);
57
127
 
58
128
  return (
59
- <div ref={containerRef}>
60
- {wrapper && ReactDOM.createPortal(children, wrapper)}
61
- </div>
129
+ <>
130
+ <iframe
131
+ ref={iframeRef}
132
+ className={className}
133
+ style={{ width: "100%", border: 0, display: "block", ...(style || {}) }}
134
+ // Add sandbox if you want stricter isolation; e.g.:
135
+ // sandbox="allow-scripts allow-same-origin"
136
+ />
137
+ {mountNode ? ReactDOM.createPortal(children, mountNode) : null}
138
+ </>
62
139
  );
63
140
  };
@@ -50,6 +50,8 @@
50
50
  link: "/components/steps"
51
51
  - label: "Tables"
52
52
  link: "/components/tables"
53
+ - label: "Tables v2"
54
+ link: "/components/table-v2"
53
55
  - label: "Timeline"
54
56
  link: "/components/timeline"
55
57
  - label: "Navbar"
@@ -86,5 +86,93 @@
86
86
  "district": "3rd"
87
87
  },
88
88
  "website": "https://susielee.house.gov"
89
+ },
90
+ {
91
+ "name": "Ashley Hinson",
92
+ "email": "ashley.hinson@mail.house.gov",
93
+ "party": "republican",
94
+ "region": {
95
+ "state": "Iowa",
96
+ "abbr": "IA",
97
+ "district": "2nd"
98
+ },
99
+ "website": "https://hinson.house.gov"
100
+ },
101
+ {
102
+ "name": "Ilhan Omar",
103
+ "email": "ilhan.omar@mail.house.gov",
104
+ "party": "democrat",
105
+ "region": {
106
+ "state": "Minnesota",
107
+ "abbr": "MN",
108
+ "district": "5th"
109
+ },
110
+ "website": "https://omar.house.gov"
111
+ },
112
+ {
113
+ "name": "Nancy Mace",
114
+ "email": "nancy.mace@mail.house.gov",
115
+ "party": "republican",
116
+ "region": {
117
+ "state": "South Carolina",
118
+ "abbr": "SC",
119
+ "district": "1st"
120
+ },
121
+ "website": "https://mace.house.gov"
122
+ },
123
+ {
124
+ "name": "Maxwell Frost",
125
+ "email": "maxwell.frost@mail.house.gov",
126
+ "party": "democrat",
127
+ "region": {
128
+ "state": "Florida",
129
+ "abbr": "FL",
130
+ "district": "10th"
131
+ },
132
+ "website": "https://frost.house.gov"
133
+ },
134
+ {
135
+ "name": "Dan Crenshaw",
136
+ "email": "dan.crenshaw@mail.house.gov",
137
+ "party": "republican",
138
+ "region": {
139
+ "state": "Texas",
140
+ "abbr": "TX",
141
+ "district": "2nd"
142
+ },
143
+ "website": "https://crenshaw.house.gov"
144
+ },
145
+ {
146
+ "name": "Ayanna Pressley",
147
+ "email": "ayanna.pressley@mail.house.gov",
148
+ "party": "democrat",
149
+ "region": {
150
+ "state": "Massachusetts",
151
+ "abbr": "MA",
152
+ "district": "7th"
153
+ },
154
+ "website": "https://pressley.house.gov"
155
+ },
156
+ {
157
+ "name": "Lauren Boebert",
158
+ "email": "lauren.boebert@mail.house.gov",
159
+ "party": "republican",
160
+ "region": {
161
+ "state": "Colorado",
162
+ "abbr": "CO",
163
+ "district": "3rd"
164
+ },
165
+ "website": "https://boebert.house.gov"
166
+ },
167
+ {
168
+ "name": "Ruben Gallego",
169
+ "email": "ruben.gallego@mail.house.gov",
170
+ "party": "democrat",
171
+ "region": {
172
+ "state": "Arizona",
173
+ "abbr": "AZ",
174
+ "district": "3rd"
175
+ },
176
+ "website": "https://gallego.house.gov"
89
177
  }
90
178
  ]