tabler-react-2 0.1.153-alpha.1 → 0.1.153-alpha.2

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.
@@ -5,9 +5,16 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.Table = exports.IconSortDescending = exports.IconSortAscending = exports.IconArrowsSort = void 0;
8
+ Object.defineProperty(exports, "useTable", {
9
+ enumerable: true,
10
+ get: function get() {
11
+ return _useTable.useTable;
12
+ }
13
+ });
8
14
  var _react = _interopRequireWildcard(require("react"));
9
15
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
16
  var _index = require("../index");
17
+ var _useTable = require("./useTable");
11
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
19
  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
20
  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; }
@@ -128,6 +135,11 @@ var Table = exports.Table = function Table(_ref4) {
128
135
  onRowsPerPageChange = _ref4.onRowsPerPageChange,
129
136
  onSetPage = _ref4.onSetPage,
130
137
  onSetSize = _ref4.onSetSize,
138
+ orderBy = _ref4.orderBy,
139
+ order = _ref4.order,
140
+ onSetOrder = _ref4.onSetOrder,
141
+ _ref4$loading = _ref4.loading,
142
+ loading = _ref4$loading === void 0 ? false : _ref4$loading,
131
143
  _ref4$pageSizeOptions = _ref4.pageSizeOptions,
132
144
  pageSizeOptions = _ref4$pageSizeOptions === void 0 ? [10, 25, 50, 100] : _ref4$pageSizeOptions,
133
145
  _ref4$tableClassName = _ref4.tableClassName,
@@ -163,14 +175,27 @@ var Table = exports.Table = function Table(_ref4) {
163
175
  return a > b ? 1 : -1;
164
176
  };
165
177
  var handleSort = function handleSort(accessor, sortFn) {
166
- var direction = "asc";
167
- if (sortConfig.key === accessor && sortConfig.direction === "asc") {
168
- direction = "desc";
178
+ var isSortControlled = typeof orderBy === "string" || typeof onSetOrder === "function";
179
+ if (isSortControlled) {
180
+ var currentKey = typeof orderBy === "string" ? orderBy : null;
181
+ var currentDir = order === "desc" ? "desc" : "asc";
182
+ var nextDir = "asc";
183
+ if (currentKey === accessor) {
184
+ nextDir = currentDir === "asc" ? "desc" : "asc";
185
+ }
186
+ if (typeof onSetOrder === "function") {
187
+ onSetOrder(accessor, nextDir);
188
+ }
189
+ } else {
190
+ var direction = "asc";
191
+ if (sortConfig.key === accessor && sortConfig.direction === "asc") {
192
+ direction = "desc";
193
+ }
194
+ setSortConfig({
195
+ key: accessor,
196
+ direction: direction
197
+ });
169
198
  }
170
- setSortConfig({
171
- key: accessor,
172
- direction: direction
173
- });
174
199
  if (useExternalPagination) {
175
200
  if (typeof onSetPage === "function") {
176
201
  onSetPage(1);
@@ -184,6 +209,9 @@ var Table = exports.Table = function Table(_ref4) {
184
209
  }
185
210
  };
186
211
  var sortedData = (0, _react.useMemo)(function () {
212
+ // If sorting is controlled externally, do not sort here
213
+ var isSortControlled = typeof orderBy === "string" || typeof onSetOrder === "function";
214
+ if (isSortControlled) return data;
187
215
  if (!sortConfig.key) return data;
188
216
  var key = sortConfig.key,
189
217
  direction = sortConfig.direction;
@@ -197,7 +225,7 @@ var Table = exports.Table = function Table(_ref4) {
197
225
  var bValue = getValueByAccessor(b, key);
198
226
  return sortFunction(aValue, bValue) * order;
199
227
  });
200
- }, [data, sortConfig, columns]);
228
+ }, [data, sortConfig, columns, orderBy, order, onSetOrder]);
201
229
  var totalRowCount = (0, _react.useMemo)(function () {
202
230
  return useExternalPagination ? totalRows !== null && totalRows !== void 0 ? totalRows : data.length : sortedData.length;
203
231
  }, [useExternalPagination, totalRows, data.length, sortedData]);
@@ -211,16 +239,30 @@ var Table = exports.Table = function Table(_ref4) {
211
239
  return sortedData.slice(start, start + effectivePageSize);
212
240
  }, [sortedData, effectivePage, effectivePageSize, showPagination, useExternalPagination]);
213
241
  var getSortIcon = function getSortIcon(column) {
214
- if (sortConfig.key === column.accessor) {
215
- return sortConfig.direction === "asc" ? /*#__PURE__*/_react["default"].createElement(IconSortAscending, {
242
+ var isSortControlled = typeof orderBy === "string" || typeof onSetOrder === "function";
243
+ if (isSortControlled) {
244
+ if (orderBy === column.accessor) {
245
+ return order === "desc" ? /*#__PURE__*/_react["default"].createElement(IconSortDescending, {
246
+ size: 16
247
+ }) : /*#__PURE__*/_react["default"].createElement(IconSortAscending, {
248
+ size: 16
249
+ });
250
+ }
251
+ return /*#__PURE__*/_react["default"].createElement(IconArrowsSort, {
216
252
  size: 16
217
- }) : /*#__PURE__*/_react["default"].createElement(IconSortDescending, {
253
+ });
254
+ } else {
255
+ if (sortConfig.key === column.accessor) {
256
+ return sortConfig.direction === "asc" ? /*#__PURE__*/_react["default"].createElement(IconSortAscending, {
257
+ size: 16
258
+ }) : /*#__PURE__*/_react["default"].createElement(IconSortDescending, {
259
+ size: 16
260
+ });
261
+ }
262
+ return /*#__PURE__*/_react["default"].createElement(IconArrowsSort, {
218
263
  size: 16
219
264
  });
220
265
  }
221
- return /*#__PURE__*/_react["default"].createElement(IconArrowsSort, {
222
- size: 16
223
- });
224
266
  };
225
267
  return /*#__PURE__*/_react["default"].createElement("div", {
226
268
  className: parentClassName
@@ -232,11 +274,11 @@ var Table = exports.Table = function Table(_ref4) {
232
274
  return /*#__PURE__*/_react["default"].createElement("th", {
233
275
  key: idx,
234
276
  className: "".concat(column.className || "", " ").concat(column.sortable ? "sortable" : ""),
235
- onClick: column.sortable ? function () {
277
+ onClick: column.sortable && !loading ? function () {
236
278
  return handleSort(column.accessor, column.sortFn);
237
279
  } : undefined,
238
280
  style: {
239
- cursor: column.sortable ? "pointer" : "default"
281
+ cursor: column.sortable && !loading ? "pointer" : "default"
240
282
  }
241
283
  }, column.icon && /*#__PURE__*/_react["default"].createElement("span", {
242
284
  style: {
@@ -247,7 +289,10 @@ var Table = exports.Table = function Table(_ref4) {
247
289
  marginRight: 8
248
290
  }
249
291
  }, column.label), column.sortable && getSortIcon(column));
250
- }))), /*#__PURE__*/_react["default"].createElement("tbody", null, paginatedData.map(function (row, rowIndex) {
292
+ }))), /*#__PURE__*/_react["default"].createElement("tbody", null, loading && /*#__PURE__*/_react["default"].createElement("tr", null, /*#__PURE__*/_react["default"].createElement("td", {
293
+ colSpan: columns.length,
294
+ className: "text-center py-3"
295
+ }, /*#__PURE__*/_react["default"].createElement(_index.Spinner, null))), paginatedData.map(function (row, rowIndex) {
251
296
  return /*#__PURE__*/_react["default"].createElement("tr", {
252
297
  key: rowIndex
253
298
  }, columns.map(function (column, colIndex) {
@@ -267,7 +312,7 @@ var Table = exports.Table = function Table(_ref4) {
267
312
  }
268
313
  setCurrentPage(prev);
269
314
  },
270
- disabled: effectivePage === 1
315
+ disabled: loading || effectivePage === 1
271
316
  }, "Previous"), /*#__PURE__*/_react["default"].createElement(_index.Button, {
272
317
  onClick: function onClick() {
273
318
  var next = Math.min(effectivePage + 1, totalPages);
@@ -277,7 +322,7 @@ var Table = exports.Table = function Table(_ref4) {
277
322
  }
278
323
  setCurrentPage(next);
279
324
  },
280
- disabled: effectivePage === totalPages,
325
+ disabled: loading || effectivePage === totalPages,
281
326
  style: {
282
327
  marginLeft: 8
283
328
  }
@@ -303,6 +348,7 @@ var Table = exports.Table = function Table(_ref4) {
303
348
  };
304
349
  }),
305
350
  value: effectivePageSize,
351
+ disabled: loading,
306
352
  onChange: function onChange(selected) {
307
353
  if (useExternalPagination) {
308
354
  if (typeof onSetSize === "function") return onSetSize(selected.id);
@@ -338,5 +384,11 @@ Table.propTypes = {
338
384
  onRowsPerPageChange: _propTypes["default"].func,
339
385
  onSetPage: _propTypes["default"].func,
340
386
  onSetSize: _propTypes["default"].func,
341
- pageSizeOptions: _propTypes["default"].arrayOf(_propTypes["default"].number)
387
+ pageSizeOptions: _propTypes["default"].arrayOf(_propTypes["default"].number),
388
+ // external ordering
389
+ orderBy: _propTypes["default"].string,
390
+ order: _propTypes["default"].oneOf(["asc", "desc"]),
391
+ onSetOrder: _propTypes["default"].func,
392
+ // loading
393
+ loading: _propTypes["default"].bool
342
394
  };
@@ -0,0 +1,192 @@
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.useTable = useTable;
8
+ var _react = require("react");
9
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
10
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
11
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
12
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
13
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
15
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
16
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
17
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
18
+ /**
19
+ * useTable - helper hook to coordinate controlled Table props and async flows
20
+ *
21
+ * Options:
22
+ * - initialPage?: number (default 1)
23
+ * - initialSize?: number (default 10)
24
+ * - initialOrderBy?: string
25
+ * - initialOrder?: 'asc' | 'desc' (default 'asc')
26
+ * - initialCount?: number (default 0)
27
+ * - autoLoading?: boolean (default true) — auto toggle loading if callbacks return a Promise
28
+ * - onPageChange?: (page: number, size: number, sort: { orderBy?: string, order?: 'asc'|'desc' }) => (void|Promise)
29
+ * - onCountChange?: (count: number) => void
30
+ * - onSortChange?: (orderBy: string, order: 'asc' | 'desc') => (void|Promise)
31
+ */
32
+ function useTable() {
33
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
34
+ var _options$initialPage = options.initialPage,
35
+ initialPage = _options$initialPage === void 0 ? 1 : _options$initialPage,
36
+ _options$initialSize = options.initialSize,
37
+ initialSize = _options$initialSize === void 0 ? 10 : _options$initialSize,
38
+ initialOrderBy = options.initialOrderBy,
39
+ _options$initialOrder = options.initialOrder,
40
+ initialOrder = _options$initialOrder === void 0 ? "asc" : _options$initialOrder,
41
+ _options$initialCount = options.initialCount,
42
+ initialCount = _options$initialCount === void 0 ? 0 : _options$initialCount,
43
+ _options$autoLoading = options.autoLoading,
44
+ autoLoading = _options$autoLoading === void 0 ? true : _options$autoLoading,
45
+ onPageChange = options.onPageChange,
46
+ onCountChange = options.onCountChange,
47
+ onSortChange = options.onSortChange;
48
+ var _useState = (0, _react.useState)(initialPage),
49
+ _useState2 = _slicedToArray(_useState, 2),
50
+ page = _useState2[0],
51
+ setPageState = _useState2[1];
52
+ var _useState3 = (0, _react.useState)(initialSize),
53
+ _useState4 = _slicedToArray(_useState3, 2),
54
+ size = _useState4[0],
55
+ setSizeState = _useState4[1];
56
+ var _useState5 = (0, _react.useState)(initialOrderBy),
57
+ _useState6 = _slicedToArray(_useState5, 2),
58
+ orderBy = _useState6[0],
59
+ setOrderByState = _useState6[1];
60
+ var _useState7 = (0, _react.useState)(initialOrder),
61
+ _useState8 = _slicedToArray(_useState7, 2),
62
+ order = _useState8[0],
63
+ setOrderState = _useState8[1];
64
+ var _useState9 = (0, _react.useState)(initialCount),
65
+ _useState10 = _slicedToArray(_useState9, 2),
66
+ count = _useState10[0],
67
+ setCountState = _useState10[1];
68
+ var _useState11 = (0, _react.useState)(false),
69
+ _useState12 = _slicedToArray(_useState11, 2),
70
+ loading = _useState12[0],
71
+ setLoading = _useState12[1];
72
+ var latest = (0, _react.useRef)({
73
+ onPageChange: onPageChange,
74
+ onCountChange: onCountChange,
75
+ onSortChange: onSortChange,
76
+ autoLoading: autoLoading
77
+ });
78
+ latest.current = {
79
+ onPageChange: onPageChange,
80
+ onCountChange: onCountChange,
81
+ onSortChange: onSortChange,
82
+ autoLoading: autoLoading
83
+ };
84
+ var wrapMaybeAsync = (0, _react.useCallback)(/*#__PURE__*/function () {
85
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(fn) {
86
+ var autoLoading, result;
87
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
88
+ while (1) switch (_context.prev = _context.next) {
89
+ case 0:
90
+ if (fn) {
91
+ _context.next = 2;
92
+ break;
93
+ }
94
+ return _context.abrupt("return");
95
+ case 2:
96
+ autoLoading = latest.current.autoLoading;
97
+ _context.prev = 3;
98
+ result = fn();
99
+ if (!(result && typeof result.then === "function")) {
100
+ _context.next = 9;
101
+ break;
102
+ }
103
+ if (autoLoading) setLoading(true);
104
+ _context.next = 9;
105
+ return result["finally"](function () {
106
+ if (autoLoading) setLoading(false);
107
+ });
108
+ case 9:
109
+ _context.next = 15;
110
+ break;
111
+ case 11:
112
+ _context.prev = 11;
113
+ _context.t0 = _context["catch"](3);
114
+ if (autoLoading) setLoading(false);
115
+ throw _context.t0;
116
+ case 15:
117
+ case "end":
118
+ return _context.stop();
119
+ }
120
+ }, _callee, null, [[3, 11]]);
121
+ }));
122
+ return function (_x) {
123
+ return _ref.apply(this, arguments);
124
+ };
125
+ }(), []);
126
+ var setPage = (0, _react.useCallback)(function (nextPage) {
127
+ setPageState(nextPage);
128
+ wrapMaybeAsync(function () {
129
+ var _latest$current$onPag, _latest$current;
130
+ return (_latest$current$onPag = (_latest$current = latest.current).onPageChange) === null || _latest$current$onPag === void 0 ? void 0 : _latest$current$onPag.call(_latest$current, nextPage, size, {
131
+ orderBy: orderBy,
132
+ order: order
133
+ });
134
+ });
135
+ }, [size, orderBy, order, wrapMaybeAsync]);
136
+ var setSize = (0, _react.useCallback)(function (nextSize) {
137
+ setSizeState(nextSize);
138
+ // Common UX: reset to first page on size change
139
+ setPageState(1);
140
+ wrapMaybeAsync(function () {
141
+ var _latest$current$onPag2, _latest$current2;
142
+ return (_latest$current$onPag2 = (_latest$current2 = latest.current).onPageChange) === null || _latest$current$onPag2 === void 0 ? void 0 : _latest$current$onPag2.call(_latest$current2, 1, nextSize, {
143
+ orderBy: orderBy,
144
+ order: order
145
+ });
146
+ });
147
+ }, [orderBy, order, wrapMaybeAsync]);
148
+ var setCount = (0, _react.useCallback)(function (nextCount) {
149
+ var _latest$current$onCou, _latest$current3;
150
+ setCountState(nextCount);
151
+ (_latest$current$onCou = (_latest$current3 = latest.current).onCountChange) === null || _latest$current$onCou === void 0 || _latest$current$onCou.call(_latest$current3, nextCount);
152
+ }, []);
153
+ var setOrder = (0, _react.useCallback)(function (by, dir) {
154
+ setOrderByState(by);
155
+ setOrderState(dir);
156
+ wrapMaybeAsync(function () {
157
+ var _latest$current$onSor, _latest$current4;
158
+ return (_latest$current$onSor = (_latest$current4 = latest.current).onSortChange) === null || _latest$current$onSor === void 0 ? void 0 : _latest$current$onSor.call(_latest$current4, by, dir);
159
+ });
160
+ }, [wrapMaybeAsync]);
161
+ var tableProps = (0, _react.useMemo)(function () {
162
+ return {
163
+ // controlled pagination
164
+ page: page,
165
+ size: size,
166
+ totalRows: count,
167
+ onSetPage: setPage,
168
+ onSetSize: setSize,
169
+ // controlled ordering
170
+ orderBy: orderBy,
171
+ order: order,
172
+ onSetOrder: setOrder,
173
+ // loading state
174
+ loading: loading,
175
+ showPagination: true
176
+ };
177
+ }, [page, size, count, orderBy, order, setPage, setSize, setOrder, loading]);
178
+ return {
179
+ tableProps: tableProps,
180
+ page: page,
181
+ size: size,
182
+ count: count,
183
+ orderBy: orderBy,
184
+ order: order,
185
+ loading: loading,
186
+ setLoading: setLoading,
187
+ setPage: setPage,
188
+ setSize: setSize,
189
+ setCount: setCount,
190
+ setOrder: setOrder
191
+ };
192
+ }
@@ -455,6 +455,88 @@ const customSortFn = (a, b) => {
455
455
 
456
456
  > **Note**: Sorting only works for the data in the table. If, for example, you have thousands of rows and are only rendering a few, you will need to handle the sorting yourself, outside of the table. Incorporating internal pagination that supports sorting is a planned feature but not yet implemented.
457
457
 
458
+ ### External ordering
459
+
460
+ You can control ordering from the parent (e.g., server-side sort) and still use the table’s sortable headers. Provide the props below. When controlled, the table will not sort your `data`; it assumes you already passed rows in the desired order.
461
+
462
+ - orderBy: accessor of the active column
463
+ - order: either `"asc"` or `"desc"`
464
+ - onSetOrder: called with `(orderBy, order)` when the user clicks a header
465
+
466
+ <Excerpt>
467
+ {(() => {
468
+ const React = require("react");
469
+ const [page, setPage] = React.useState(1);
470
+ const [size, setSize] = React.useState(5);
471
+ const [orderBy, setOrderBy] = React.useState("name");
472
+ const [order, setOrder] = React.useState("asc");
473
+ const total = congressPeople.length;
474
+
475
+ const sorted = [...congressPeople].sort((a, b) => {
476
+ const av = orderBy.split('.').reduce((acc, k) => acc?.[k], a);
477
+ const bv = orderBy.split('.').reduce((acc, k) => acc?.[k], b);
478
+ if (av === bv) return 0;
479
+ const cmp = av > bv ? 1 : -1;
480
+ return order === 'asc' ? cmp : -cmp;
481
+ });
482
+ const start = (page - 1) * size;
483
+ const pageData = sorted.slice(start, start + size);
484
+
485
+ return (
486
+ <Table
487
+ columns={[
488
+ { label: "Name", accessor: "name", sortable: true },
489
+ { label: "Party", accessor: "party", sortable: true },
490
+ { label: "State", accessor: "region.state", sortable: true },
491
+ ]}
492
+ data={pageData}
493
+ showPagination
494
+ page={page}
495
+ size={size}
496
+ totalRows={total}
497
+ orderBy={orderBy}
498
+ order={order}
499
+ onSetOrder={(by, dir) => { setOrderBy(by); setOrder(dir); }}
500
+ onSetPage={setPage}
501
+ onSetSize={(n) => { setPage(1); setSize(n); }}
502
+ />
503
+ );
504
+ })()}
505
+ </Excerpt>
506
+
507
+ ```jsx
508
+ // Parent controls ordering and pagination
509
+ const [orderBy, setOrderBy] = useState('name');
510
+ const [order, setOrder] = useState('asc');
511
+ const [page, setPage] = useState(1);
512
+ const [size, setSize] = useState(10);
513
+
514
+ const ordered = [...allRows].sort((a, b) => {
515
+ const av = orderBy.split('.').reduce((acc, k) => acc?.[k], a);
516
+ const bv = orderBy.split('.').reduce((acc, k) => acc?.[k], b);
517
+ if (av === bv) return 0;
518
+ const cmp = av > bv ? 1 : -1;
519
+ return order === 'asc' ? cmp : -cmp;
520
+ });
521
+
522
+ const start = (page - 1) * size;
523
+ const currentData = ordered.slice(start, start + size);
524
+
525
+ <Table
526
+ columns={columns}
527
+ data={currentData}
528
+ showPagination
529
+ page={page}
530
+ size={size}
531
+ totalRows={allRows.length}
532
+ orderBy={orderBy}
533
+ order={order}
534
+ onSetOrder={(by, dir) => { setOrderBy(by); setOrder(dir); }}
535
+ onSetPage={setPage}
536
+ onSetSize={(n) => { setPage(1); setSize(n); }}
537
+ />;
538
+ ```
539
+
458
540
  ## Pagination
459
541
 
460
542
  The `Table` supports built-in pagination UI. Enable it with `showPagination`.
@@ -552,3 +634,51 @@ const currentData = allRows.slice(start, start + rowsPerPage);
552
634
  ```
553
635
 
554
636
  If you don’t supply these controlled props, the table falls back to its internal pagination state, preserving backwards compatibility.
637
+
638
+ ## useTable hook
639
+
640
+ For async workflows, use the helper hook to centralize loading, pagination, count, and ordering while preserving the Table’s controlled API.
641
+
642
+ ```jsx
643
+ import { useEffect, useState } from 'react';
644
+ import { Table, useTable } from 'tabler-react-2';
645
+
646
+ function PeopleTable() {
647
+ const [rows, setRows] = useState([]);
648
+ const { tableProps, setLoading, setPage, setCount, setOrder } = useTable({
649
+ autoLoading: false,
650
+ onPageChange: async (page, size, sort) => {
651
+ setLoading(true);
652
+ try {
653
+ // fetch your data here using page, size, and sort
654
+ const res = await fetchPeople({ page, size, sort });
655
+ setRows(res.items);
656
+ setCount(res.total);
657
+ } finally {
658
+ setLoading(false);
659
+ }
660
+ },
661
+ onSortChange: async (by, dir) => {
662
+ // optionally kick off a fetch based on new sort
663
+ // setOrder(by, dir) is already called for you
664
+ },
665
+ });
666
+
667
+ useEffect(() => {
668
+ // initial load
669
+ setPage(1);
670
+ }, [setPage]);
671
+
672
+ return <Table {...tableProps} columns={[
673
+ { label: 'Name', accessor: 'name', sortable: true },
674
+ { label: 'Party', accessor: 'party', sortable: true },
675
+ { label: 'State', accessor: 'region.state', sortable: true },
676
+ ]} data={rows} />;
677
+ }
678
+ ```
679
+
680
+ The hook returns:
681
+
682
+ - tableProps: spread onto `<Table />` to enable controlled pagination, ordering, and loading
683
+ - setLoading, setPage, setCount: imperative helpers for async flows
684
+ - Also available: page, size, count, orderBy, order, setSize, setOrder
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tabler-react-2",
3
- "version": "0.1.153-alpha.1",
3
+ "version": "0.1.153-alpha.2",
4
4
  "description": "A react implementation of Tabler ui",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {