@dreamtree-org/twreact-ui 1.1.63 → 1.1.64
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/dist/components/core/Table/Table.d.ts +2 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/feedback/Alert.d.ts +2 -9
- package/dist/components/feedback/Alert.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts +1 -30
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Toast.d.ts +1 -10
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/navigation/Breadcrumbs.d.ts +2 -9
- package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts +2 -5
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- package/dist/components/navigation/Navbar.d.ts +2 -29
- package/dist/components/navigation/Navbar.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts +2 -15
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/utility/Avatar.d.ts +2 -10
- package/dist/components/utility/Avatar.d.ts.map +1 -1
- package/dist/components/utility/Badge.d.ts +2 -8
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/Card.d.ts +2 -38
- package/dist/components/utility/Card.d.ts.map +1 -1
- package/dist/components/utility/Carousel.d.ts +2 -1
- package/dist/components/utility/Carousel.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts +2 -11
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Pagination.d.ts +2 -10
- package/dist/components/utility/Pagination.d.ts.map +1 -1
- package/dist/components/utility/Stepper.d.ts +2 -9
- package/dist/components/utility/Stepper.d.ts.map +1 -1
- package/dist/index.esm.js +92 -46
- package/dist/index.js +92 -46
- package/mcp/catalog.snapshot.json +15 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4761,7 +4761,7 @@ function MobileCard(_ref) {
|
|
|
4761
4761
|
}, key);
|
|
4762
4762
|
}
|
|
4763
4763
|
|
|
4764
|
-
var _excluded$x = ["data", "columns", "sortable", "filterable", "selectable", "pagination", "pageSize", "onSort", "onFilter", "onFetch", "onFilterChange", "onSelectionChange", "onRowClick", "hasDetails", "DetailsComponent", "className", "withAction", "onAction", "actions", "showSerial", "cellClass", "rowClass", "globalSearch", "limitOptions", "showLimitSelector", "onLimitChange", "showReloadButton", "renderReloadButton", "onReload", "stripedRows", "theme", "responsiveBreakpoint", "serverSide", "totalRecords", "pageNumber", "TheadComponent", "TfootComponent"];
|
|
4764
|
+
var _excluded$x = ["data", "columns", "sortable", "filterable", "selectable", "pagination", "pageSize", "onSort", "onFilter", "onFetch", "onFilterChange", "onSelectionChange", "onRowClick", "hasDetails", "DetailsComponent", "className", "withAction", "onAction", "actions", "showSerial", "cellClass", "rowClass", "globalSearch", "limitOptions", "showLimitSelector", "onLimitChange", "showReloadButton", "renderReloadButton", "onReload", "stripedRows", "theme", "responsiveBreakpoint", "serverSide", "totalRecords", "pageNumber", "onPageChange", "TheadComponent", "TfootComponent"];
|
|
4765
4765
|
function ownKeys$B(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4766
4766
|
function _objectSpread$B(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$B(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$B(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4767
4767
|
var DEFAULT_DATA = [];
|
|
@@ -4829,6 +4829,7 @@ var Table = function Table(_ref) {
|
|
|
4829
4829
|
_ref$totalRecords = _ref.totalRecords,
|
|
4830
4830
|
totalRecords = _ref$totalRecords === void 0 ? 0 : _ref$totalRecords,
|
|
4831
4831
|
pageNumber = _ref.pageNumber,
|
|
4832
|
+
onPageChange = _ref.onPageChange,
|
|
4832
4833
|
_ref$TheadComponent = _ref.TheadComponent,
|
|
4833
4834
|
TheadComponent = _ref$TheadComponent === void 0 ? null : _ref$TheadComponent,
|
|
4834
4835
|
_ref$TfootComponent = _ref.TfootComponent,
|
|
@@ -5169,7 +5170,8 @@ var Table = function Table(_ref) {
|
|
|
5169
5170
|
}, [applyGlobalSearch]);
|
|
5170
5171
|
var handlePageChange = React.useCallback(function (newPage) {
|
|
5171
5172
|
setCurrentPage(newPage);
|
|
5172
|
-
|
|
5173
|
+
onPageChange === null || onPageChange === void 0 || onPageChange(newPage);
|
|
5174
|
+
}, [onPageChange]);
|
|
5173
5175
|
var renderCell = React.useCallback(function (column, row, globalIndex) {
|
|
5174
5176
|
if (column.render) return column.render(row, globalIndex);
|
|
5175
5177
|
return row === null || row === void 0 ? void 0 : row[column.key];
|
|
@@ -16576,7 +16578,7 @@ function _objectSpread$h(e) { for (var r = 1; r < arguments.length; r++) { var t
|
|
|
16576
16578
|
* - isMobileOpen, setIsMobileOpen
|
|
16577
16579
|
* - showCollapsedTooltips: boolean (default true)
|
|
16578
16580
|
*/
|
|
16579
|
-
var Sidebar = function
|
|
16581
|
+
var Sidebar = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
16580
16582
|
var _ref2$items = _ref2.items,
|
|
16581
16583
|
items = _ref2$items === void 0 ? [] : _ref2$items,
|
|
16582
16584
|
_ref2$collapsed = _ref2.collapsed,
|
|
@@ -16819,6 +16821,7 @@ var Sidebar = function Sidebar(_ref2) {
|
|
|
16819
16821
|
children: [jsxRuntime.jsx("div", {
|
|
16820
16822
|
className: "hidden md:flex sticky top-0 h-screen",
|
|
16821
16823
|
children: jsxRuntime.jsx("div", _objectSpread$h(_objectSpread$h({
|
|
16824
|
+
ref: ref,
|
|
16822
16825
|
className: cn$1(desktopPlacementClass, className)
|
|
16823
16826
|
}, props), {}, {
|
|
16824
16827
|
children: SidebarContent
|
|
@@ -16839,7 +16842,8 @@ var Sidebar = function Sidebar(_ref2) {
|
|
|
16839
16842
|
children: SidebarContent
|
|
16840
16843
|
})]
|
|
16841
16844
|
});
|
|
16842
|
-
};
|
|
16845
|
+
});
|
|
16846
|
+
Sidebar.displayName = "Sidebar";
|
|
16843
16847
|
|
|
16844
16848
|
var _excluded$c = ["trigger", "children", "placement", "className"];
|
|
16845
16849
|
function ownKeys$g(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -16891,7 +16895,7 @@ var Dropdown = function Dropdown(_ref) {
|
|
|
16891
16895
|
};
|
|
16892
16896
|
|
|
16893
16897
|
var _excluded$b = ["emitter", "content", "notifications"],
|
|
16894
|
-
_excluded2$2 = ["emitter", "logo", "items", "user", "notifications", "searchable", "onSearch", "leftIcon", "rightMenuContent", "onLeftIconClick", "onLoginClick", "onLogoutClick", "className"];
|
|
16898
|
+
_excluded2$2 = ["emitter", "logo", "items", "user", "notifications", "searchable", "onSearch", "leftIcon", "rightMenuContent", "onLeftIconClick", "onLoginClick", "onLogoutClick", "className", "onFetch", "isMobileOpen", "setIsMobileOpen"];
|
|
16895
16899
|
function ownKeys$f(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16896
16900
|
function _objectSpread$f(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$f(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$f(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
16897
16901
|
// Simplified Notifications, uses notifications from props and a single effect for fetch/update
|
|
@@ -17038,7 +17042,7 @@ var styledClassNames = {
|
|
|
17038
17042
|
icon: "h-6 w-6",
|
|
17039
17043
|
dropdown: "w-56 rounded-md border border-gray-200 bg-white py-1 shadow-lg"
|
|
17040
17044
|
};
|
|
17041
|
-
var Navbar = function
|
|
17045
|
+
var Navbar = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
17042
17046
|
var emitter = _ref3.emitter,
|
|
17043
17047
|
logo = _ref3.logo,
|
|
17044
17048
|
_ref3$items = _ref3.items,
|
|
@@ -17062,7 +17066,10 @@ var Navbar = function Navbar(_ref3) {
|
|
|
17062
17066
|
return console.log("invoked onLogoutClick");
|
|
17063
17067
|
} : _ref3$onLogoutClick,
|
|
17064
17068
|
className = _ref3.className,
|
|
17065
|
-
|
|
17069
|
+
onFetch = _ref3.onFetch;
|
|
17070
|
+
_ref3.isMobileOpen;
|
|
17071
|
+
_ref3.setIsMobileOpen;
|
|
17072
|
+
var props = _objectWithoutProperties$1(_ref3, _excluded2$2);
|
|
17066
17073
|
var _useState3 = React.useState(false),
|
|
17067
17074
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
17068
17075
|
isMobileMenuOpen = _useState4[0],
|
|
@@ -17131,6 +17138,7 @@ var Navbar = function Navbar(_ref3) {
|
|
|
17131
17138
|
}, rest));
|
|
17132
17139
|
};
|
|
17133
17140
|
return jsxRuntime.jsxs("nav", _objectSpread$f(_objectSpread$f({
|
|
17141
|
+
ref: ref,
|
|
17134
17142
|
className: cn$1("bg-white border-b border-gray-200 px-4 sm:px-6 lg:px-8", className)
|
|
17135
17143
|
}, props), {}, {
|
|
17136
17144
|
children: [jsxRuntime.jsxs("div", {
|
|
@@ -17175,7 +17183,8 @@ var Navbar = function Navbar(_ref3) {
|
|
|
17175
17183
|
})]
|
|
17176
17184
|
})
|
|
17177
17185
|
}), jsxRuntime.jsx(RightMenuComponent, {
|
|
17178
|
-
notifications: notifications
|
|
17186
|
+
notifications: notifications,
|
|
17187
|
+
onFetch: onFetch
|
|
17179
17188
|
}), !user && jsxRuntime.jsx("button", {
|
|
17180
17189
|
className: styledClassNames.button,
|
|
17181
17190
|
onClick: handleLoginClick,
|
|
@@ -17267,7 +17276,7 @@ var Navbar = function Navbar(_ref3) {
|
|
|
17267
17276
|
})
|
|
17268
17277
|
})]
|
|
17269
17278
|
}));
|
|
17270
|
-
};
|
|
17279
|
+
});
|
|
17271
17280
|
Navbar.displayName = "Navbar";
|
|
17272
17281
|
Navbar.propTypes = {
|
|
17273
17282
|
emitter: PropTypes.object.isRequired,
|
|
@@ -17282,12 +17291,13 @@ Navbar.propTypes = {
|
|
|
17282
17291
|
var _excluded$a = ["items", "className"];
|
|
17283
17292
|
function ownKeys$e(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17284
17293
|
function _objectSpread$e(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$e(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$e(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17285
|
-
var FootNav = function
|
|
17294
|
+
var FootNav = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17286
17295
|
var _ref$items = _ref.items,
|
|
17287
17296
|
items = _ref$items === void 0 ? [] : _ref$items,
|
|
17288
17297
|
className = _ref.className,
|
|
17289
17298
|
props = _objectWithoutProperties$1(_ref, _excluded$a);
|
|
17290
17299
|
return jsxRuntime.jsx("nav", _objectSpread$e(_objectSpread$e({
|
|
17300
|
+
ref: ref,
|
|
17291
17301
|
className: cn$1('fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 px-4 py-2 md:hidden', className)
|
|
17292
17302
|
}, props), {}, {
|
|
17293
17303
|
children: jsxRuntime.jsx("div", {
|
|
@@ -17315,12 +17325,13 @@ var FootNav = function FootNav(_ref) {
|
|
|
17315
17325
|
})
|
|
17316
17326
|
})
|
|
17317
17327
|
}));
|
|
17318
|
-
};
|
|
17328
|
+
});
|
|
17329
|
+
FootNav.displayName = 'FootNav';
|
|
17319
17330
|
|
|
17320
17331
|
var _excluded$9 = ["items", "separator", "showHome", "homeIcon", "onHomeClick", "className"];
|
|
17321
17332
|
function ownKeys$d(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17322
17333
|
function _objectSpread$d(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$d(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$d(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17323
|
-
var Breadcrumbs = function
|
|
17334
|
+
var Breadcrumbs = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17324
17335
|
var _ref$items = _ref.items,
|
|
17325
17336
|
items = _ref$items === void 0 ? [] : _ref$items,
|
|
17326
17337
|
_ref$separator = _ref.separator,
|
|
@@ -17344,6 +17355,7 @@ var Breadcrumbs = function Breadcrumbs(_ref) {
|
|
|
17344
17355
|
onClick: onHomeClick
|
|
17345
17356
|
}].concat(_toConsumableArray$1(items)) : items;
|
|
17346
17357
|
return jsxRuntime.jsx("nav", _objectSpread$d(_objectSpread$d({
|
|
17358
|
+
ref: ref,
|
|
17347
17359
|
className: cn$1('flex items-center space-x-1 text-sm', className),
|
|
17348
17360
|
"aria-label": "Breadcrumb"
|
|
17349
17361
|
}, props), {}, {
|
|
@@ -17377,7 +17389,8 @@ var Breadcrumbs = function Breadcrumbs(_ref) {
|
|
|
17377
17389
|
}, item.id);
|
|
17378
17390
|
})
|
|
17379
17391
|
}));
|
|
17380
|
-
};
|
|
17392
|
+
});
|
|
17393
|
+
Breadcrumbs.displayName = 'Breadcrumbs';
|
|
17381
17394
|
|
|
17382
17395
|
var _excluded$8 = ["isOpen", "onClose", "title", "children", "size", "dismissible", "showCloseButton", "footer", "className", "onOpen"],
|
|
17383
17396
|
_excluded2$1 = ["children", "className"],
|
|
@@ -17393,7 +17406,19 @@ var getFocusable = function getFocusable(root) {
|
|
|
17393
17406
|
return el.getAttribute('aria-hidden') !== 'true';
|
|
17394
17407
|
}) : [];
|
|
17395
17408
|
};
|
|
17396
|
-
|
|
17409
|
+
// Assign one node to several refs (callback or object). Lets the dialog keep
|
|
17410
|
+
// its internal `dialogRef` for the focus trap while still exposing the panel
|
|
17411
|
+
// node to a consumer-supplied `ref` (issue #56).
|
|
17412
|
+
var setRefs = function setRefs(node) {
|
|
17413
|
+
for (var _len = arguments.length, refs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
17414
|
+
refs[_key - 1] = arguments[_key];
|
|
17415
|
+
}
|
|
17416
|
+
refs.forEach(function (ref) {
|
|
17417
|
+
if (!ref) return;
|
|
17418
|
+
if (typeof ref === 'function') ref(node);else ref.current = node;
|
|
17419
|
+
});
|
|
17420
|
+
};
|
|
17421
|
+
var Dialog = /*#__PURE__*/React.forwardRef(function (_ref, _ref3) {
|
|
17397
17422
|
var isOpen = _ref.isOpen,
|
|
17398
17423
|
onClose = _ref.onClose,
|
|
17399
17424
|
title = _ref.title,
|
|
@@ -17484,7 +17509,9 @@ var Dialog = function Dialog(_ref) {
|
|
|
17484
17509
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4",
|
|
17485
17510
|
onClick: handleBackdropClick,
|
|
17486
17511
|
children: jsxRuntime.jsxs("div", _objectSpread$c(_objectSpread$c({
|
|
17487
|
-
ref:
|
|
17512
|
+
ref: function ref(node) {
|
|
17513
|
+
return setRefs(node, dialogRef, _ref3);
|
|
17514
|
+
},
|
|
17488
17515
|
className: cn$1('w-full rounded-lg bg-white shadow-xl animate-scale-in motion-reduce:animate-none', sizeClasses[size], className),
|
|
17489
17516
|
tabIndex: -1,
|
|
17490
17517
|
role: "dialog",
|
|
@@ -17515,32 +17542,33 @@ var Dialog = function Dialog(_ref) {
|
|
|
17515
17542
|
})]
|
|
17516
17543
|
}))
|
|
17517
17544
|
}), document.body);
|
|
17518
|
-
};
|
|
17545
|
+
});
|
|
17546
|
+
Dialog.displayName = 'Dialog';
|
|
17519
17547
|
// Dialog components for composition
|
|
17520
|
-
Dialog.Header = function (
|
|
17521
|
-
var children =
|
|
17522
|
-
className =
|
|
17523
|
-
props = _objectWithoutProperties$1(
|
|
17548
|
+
Dialog.Header = function (_ref4) {
|
|
17549
|
+
var children = _ref4.children,
|
|
17550
|
+
className = _ref4.className,
|
|
17551
|
+
props = _objectWithoutProperties$1(_ref4, _excluded2$1);
|
|
17524
17552
|
return jsxRuntime.jsx("div", _objectSpread$c(_objectSpread$c({
|
|
17525
17553
|
className: cn$1('border-b border-gray-200 px-6 py-4', className)
|
|
17526
17554
|
}, props), {}, {
|
|
17527
17555
|
children: children
|
|
17528
17556
|
}));
|
|
17529
17557
|
};
|
|
17530
|
-
Dialog.Body = function (
|
|
17531
|
-
var children =
|
|
17532
|
-
className =
|
|
17533
|
-
props = _objectWithoutProperties$1(
|
|
17558
|
+
Dialog.Body = function (_ref5) {
|
|
17559
|
+
var children = _ref5.children,
|
|
17560
|
+
className = _ref5.className,
|
|
17561
|
+
props = _objectWithoutProperties$1(_ref5, _excluded3$1);
|
|
17534
17562
|
return jsxRuntime.jsx("div", _objectSpread$c(_objectSpread$c({
|
|
17535
17563
|
className: cn$1('px-6 py-4', className)
|
|
17536
17564
|
}, props), {}, {
|
|
17537
17565
|
children: children
|
|
17538
17566
|
}));
|
|
17539
17567
|
};
|
|
17540
|
-
Dialog.Footer = function (
|
|
17541
|
-
var children =
|
|
17542
|
-
className =
|
|
17543
|
-
props = _objectWithoutProperties$1(
|
|
17568
|
+
Dialog.Footer = function (_ref6) {
|
|
17569
|
+
var children = _ref6.children,
|
|
17570
|
+
className = _ref6.className,
|
|
17571
|
+
props = _objectWithoutProperties$1(_ref6, _excluded4$1);
|
|
17544
17572
|
return jsxRuntime.jsx("div", _objectSpread$c(_objectSpread$c({
|
|
17545
17573
|
className: cn$1('flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4', className)
|
|
17546
17574
|
}, props), {}, {
|
|
@@ -17551,7 +17579,7 @@ Dialog.Footer = function (_ref5) {
|
|
|
17551
17579
|
var _excluded$7 = ["id", "title", "message", "type", "duration", "onClose", "position"];
|
|
17552
17580
|
function ownKeys$b(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17553
17581
|
function _objectSpread$b(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$b(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$b(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17554
|
-
var Toast = function
|
|
17582
|
+
var Toast = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17555
17583
|
var id = _ref.id,
|
|
17556
17584
|
title = _ref.title,
|
|
17557
17585
|
message = _ref.message,
|
|
@@ -17607,6 +17635,7 @@ var Toast = function Toast(_ref) {
|
|
|
17607
17635
|
};
|
|
17608
17636
|
if (!isVisible) return null;
|
|
17609
17637
|
return /*#__PURE__*/ReactDOM.createPortal(jsxRuntime.jsx("div", _objectSpread$b(_objectSpread$b({
|
|
17638
|
+
ref: ref,
|
|
17610
17639
|
className: cn$1('fixed z-50 max-w-sm rounded-lg border border-gray-200 bg-white p-4 shadow-lg animate-slide-up', positionClasses[position])
|
|
17611
17640
|
}, props), {}, {
|
|
17612
17641
|
children: jsxRuntime.jsxs("div", {
|
|
@@ -17633,7 +17662,8 @@ var Toast = function Toast(_ref) {
|
|
|
17633
17662
|
})]
|
|
17634
17663
|
})
|
|
17635
17664
|
})), document.body);
|
|
17636
|
-
};
|
|
17665
|
+
});
|
|
17666
|
+
Toast.displayName = 'Toast';
|
|
17637
17667
|
// Toast Container Component
|
|
17638
17668
|
var ToastContainer = function ToastContainer(_ref2) {
|
|
17639
17669
|
var _ref2$toasts = _ref2.toasts,
|
|
@@ -17713,7 +17743,7 @@ var useToast = function useToast() {
|
|
|
17713
17743
|
var _excluded$6 = ["variant", "title", "children", "dismissible", "onDismiss", "className"];
|
|
17714
17744
|
function ownKeys$a(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17715
17745
|
function _objectSpread$a(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$a(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$a(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17716
|
-
var Alert = function
|
|
17746
|
+
var Alert = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17717
17747
|
var _ref$variant = _ref.variant,
|
|
17718
17748
|
variant = _ref$variant === void 0 ? 'info' : _ref$variant,
|
|
17719
17749
|
title = _ref.title,
|
|
@@ -17759,6 +17789,7 @@ var Alert = function Alert(_ref) {
|
|
|
17759
17789
|
};
|
|
17760
17790
|
var variantStyles = variants[variant];
|
|
17761
17791
|
return jsxRuntime.jsx("div", _objectSpread$a(_objectSpread$a({
|
|
17792
|
+
ref: ref,
|
|
17762
17793
|
className: cn$1('rounded-md border p-4', variantStyles.container, className),
|
|
17763
17794
|
role: "alert"
|
|
17764
17795
|
}, props), {}, {
|
|
@@ -17796,12 +17827,13 @@ var Alert = function Alert(_ref) {
|
|
|
17796
17827
|
})]
|
|
17797
17828
|
})
|
|
17798
17829
|
}));
|
|
17799
|
-
};
|
|
17830
|
+
});
|
|
17831
|
+
Alert.displayName = 'Alert';
|
|
17800
17832
|
|
|
17801
17833
|
var _excluded$5 = ["children", "variant", "size", "rounded", "className"];
|
|
17802
17834
|
function ownKeys$9(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17803
17835
|
function _objectSpread$9(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$9(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$9(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17804
|
-
var Badge = function
|
|
17836
|
+
var Badge = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17805
17837
|
var children = _ref.children,
|
|
17806
17838
|
_ref$variant = _ref.variant,
|
|
17807
17839
|
variant = _ref$variant === void 0 ? 'default' : _ref$variant,
|
|
@@ -17826,6 +17858,7 @@ var Badge = function Badge(_ref) {
|
|
|
17826
17858
|
lg: 'px-3 py-1 text-base'
|
|
17827
17859
|
};
|
|
17828
17860
|
return jsxRuntime.jsx("span", _objectSpread$9(_objectSpread$9({
|
|
17861
|
+
ref: ref,
|
|
17829
17862
|
className: cn$1('inline-flex items-center font-medium', variants[variant], sizes[size], {
|
|
17830
17863
|
'rounded-full': rounded,
|
|
17831
17864
|
'rounded-md': !rounded
|
|
@@ -17833,12 +17866,13 @@ var Badge = function Badge(_ref) {
|
|
|
17833
17866
|
}, props), {}, {
|
|
17834
17867
|
children: children
|
|
17835
17868
|
}));
|
|
17836
|
-
};
|
|
17869
|
+
});
|
|
17870
|
+
Badge.displayName = 'Badge';
|
|
17837
17871
|
|
|
17838
17872
|
var _excluded$4 = ["src", "alt", "name", "size", "shape", "status", "className"];
|
|
17839
17873
|
function ownKeys$8(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17840
17874
|
function _objectSpread$8(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$8(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$8(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17841
|
-
var Avatar = function
|
|
17875
|
+
var Avatar = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17842
17876
|
var src = _ref.src,
|
|
17843
17877
|
alt = _ref.alt,
|
|
17844
17878
|
name = _ref.name,
|
|
@@ -17878,6 +17912,7 @@ var Avatar = function Avatar(_ref) {
|
|
|
17878
17912
|
'2xl': 'h-5 w-5'
|
|
17879
17913
|
};
|
|
17880
17914
|
return jsxRuntime.jsxs("div", {
|
|
17915
|
+
ref: ref,
|
|
17881
17916
|
className: "relative inline-block",
|
|
17882
17917
|
children: [jsxRuntime.jsxs("div", _objectSpread$8(_objectSpread$8({
|
|
17883
17918
|
className: cn$1('flex items-center justify-center bg-gray-100 text-primary-600 font-medium', sizes[size], {
|
|
@@ -17914,7 +17949,8 @@ var Avatar = function Avatar(_ref) {
|
|
|
17914
17949
|
className: cn$1('absolute bottom-0 right-0 rounded-full border-2 border-white', statusColors[status], statusSizes[size])
|
|
17915
17950
|
})]
|
|
17916
17951
|
});
|
|
17917
|
-
};
|
|
17952
|
+
});
|
|
17953
|
+
Avatar.displayName = 'Avatar';
|
|
17918
17954
|
|
|
17919
17955
|
var _excluded$3 = ["children", "className", "hover"],
|
|
17920
17956
|
_excluded2 = ["children", "className"],
|
|
@@ -17924,20 +17960,22 @@ var _excluded$3 = ["children", "className", "hover"],
|
|
|
17924
17960
|
_excluded6 = ["children", "className"];
|
|
17925
17961
|
function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17926
17962
|
function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17927
|
-
var Card = function
|
|
17963
|
+
var Card = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
17928
17964
|
var children = _ref.children,
|
|
17929
17965
|
className = _ref.className,
|
|
17930
17966
|
_ref$hover = _ref.hover,
|
|
17931
17967
|
hover = _ref$hover === void 0 ? false : _ref$hover,
|
|
17932
17968
|
props = _objectWithoutProperties$1(_ref, _excluded$3);
|
|
17933
17969
|
return jsxRuntime.jsx("div", _objectSpread$7(_objectSpread$7({
|
|
17970
|
+
ref: ref,
|
|
17934
17971
|
className: cn$1('rounded-lg border border-gray-200 bg-white shadow-sm', {
|
|
17935
17972
|
'hover:shadow-md transition-shadow': hover
|
|
17936
17973
|
}, className)
|
|
17937
17974
|
}, props), {}, {
|
|
17938
17975
|
children: children
|
|
17939
17976
|
}));
|
|
17940
|
-
};
|
|
17977
|
+
});
|
|
17978
|
+
Card.displayName = 'Card';
|
|
17941
17979
|
var CardHeader = function CardHeader(_ref2) {
|
|
17942
17980
|
var children = _ref2.children,
|
|
17943
17981
|
className = _ref2.className,
|
|
@@ -17997,7 +18035,7 @@ Card.Footer = CardFooter;
|
|
|
17997
18035
|
var _excluded$2 = ["currentPage", "totalPages", "onPageChange", "showFirstLast", "showPrevNext", "maxVisiblePages", "className"];
|
|
17998
18036
|
function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17999
18037
|
function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
18000
|
-
var Pagination = function
|
|
18038
|
+
var Pagination = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
18001
18039
|
var _ref$currentPage = _ref.currentPage,
|
|
18002
18040
|
currentPage = _ref$currentPage === void 0 ? 1 : _ref$currentPage,
|
|
18003
18041
|
_ref$totalPages = _ref.totalPages,
|
|
@@ -18037,6 +18075,7 @@ var Pagination = function Pagination(_ref) {
|
|
|
18037
18075
|
};
|
|
18038
18076
|
if (totalPages <= 1) return null;
|
|
18039
18077
|
return jsxRuntime.jsxs("nav", _objectSpread$6(_objectSpread$6({
|
|
18078
|
+
ref: ref,
|
|
18040
18079
|
className: cn$1('flex items-center justify-center space-x-1', className),
|
|
18041
18080
|
"aria-label": "Pagination"
|
|
18042
18081
|
}, props), {}, {
|
|
@@ -18095,12 +18134,13 @@ var Pagination = function Pagination(_ref) {
|
|
|
18095
18134
|
children: totalPages
|
|
18096
18135
|
})]
|
|
18097
18136
|
}));
|
|
18098
|
-
};
|
|
18137
|
+
});
|
|
18138
|
+
Pagination.displayName = 'Pagination';
|
|
18099
18139
|
|
|
18100
18140
|
var _excluded$1 = ["steps", "currentStep", "orientation", "variant", "onStepClick", "className"];
|
|
18101
18141
|
function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18102
18142
|
function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
18103
|
-
var Stepper = function
|
|
18143
|
+
var Stepper = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
18104
18144
|
var _ref$steps = _ref.steps,
|
|
18105
18145
|
steps = _ref$steps === void 0 ? [] : _ref$steps,
|
|
18106
18146
|
_ref$currentStep = _ref.currentStep,
|
|
@@ -18134,6 +18174,7 @@ var Stepper = function Stepper(_ref) {
|
|
|
18134
18174
|
}
|
|
18135
18175
|
};
|
|
18136
18176
|
return jsxRuntime.jsx("nav", _objectSpread$5(_objectSpread$5({
|
|
18177
|
+
ref: ref,
|
|
18137
18178
|
className: cn$1('flex', {
|
|
18138
18179
|
'flex-col': orientation === 'vertical',
|
|
18139
18180
|
'flex-row': orientation === 'horizontal'
|
|
@@ -18188,12 +18229,13 @@ var Stepper = function Stepper(_ref) {
|
|
|
18188
18229
|
}, step.id || stepIndex);
|
|
18189
18230
|
})
|
|
18190
18231
|
}));
|
|
18191
|
-
};
|
|
18232
|
+
});
|
|
18233
|
+
Stepper.displayName = 'Stepper';
|
|
18192
18234
|
|
|
18193
18235
|
var _excluded = ["accept", "multiple", "maxSize", "onFileSelect", "onFileRemove", "files", "disabled", "className"];
|
|
18194
18236
|
function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18195
18237
|
function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
18196
|
-
var FileUpload = function
|
|
18238
|
+
var FileUpload = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
18197
18239
|
var accept = _ref.accept,
|
|
18198
18240
|
_ref$multiple = _ref.multiple,
|
|
18199
18241
|
multiple = _ref$multiple === void 0 ? false : _ref$multiple,
|
|
@@ -18285,6 +18327,7 @@ var FileUpload = function FileUpload(_ref) {
|
|
|
18285
18327
|
}
|
|
18286
18328
|
};
|
|
18287
18329
|
return jsxRuntime.jsxs("div", _objectSpread$4(_objectSpread$4({
|
|
18330
|
+
ref: ref,
|
|
18288
18331
|
className: cn$1('w-full', className)
|
|
18289
18332
|
}, props), {}, {
|
|
18290
18333
|
children: [jsxRuntime.jsxs("div", {
|
|
@@ -18357,7 +18400,8 @@ var FileUpload = function FileUpload(_ref) {
|
|
|
18357
18400
|
})
|
|
18358
18401
|
})]
|
|
18359
18402
|
}));
|
|
18360
|
-
};
|
|
18403
|
+
});
|
|
18404
|
+
FileUpload.displayName = 'FileUpload';
|
|
18361
18405
|
|
|
18362
18406
|
var Condition = function Condition(_ref) {
|
|
18363
18407
|
var condition = _ref.condition,
|
|
@@ -18367,7 +18411,7 @@ var Condition = function Condition(_ref) {
|
|
|
18367
18411
|
return condition ? children : fallback;
|
|
18368
18412
|
};
|
|
18369
18413
|
|
|
18370
|
-
function Carousel(props) {
|
|
18414
|
+
var Carousel = /*#__PURE__*/React.forwardRef(function Carousel(props, ref) {
|
|
18371
18415
|
var children = props.children,
|
|
18372
18416
|
_props$autoPlay = props.autoPlay,
|
|
18373
18417
|
autoPlay = _props$autoPlay === void 0 ? false : _props$autoPlay,
|
|
@@ -18407,6 +18451,7 @@ function Carousel(props) {
|
|
|
18407
18451
|
}, [autoPlay, isPaused, next, interval]);
|
|
18408
18452
|
var childrenArray = React.Children.toArray(children);
|
|
18409
18453
|
return jsxRuntime.jsxs("div", {
|
|
18454
|
+
ref: ref,
|
|
18410
18455
|
className: cn$1("relative group overflow-hidden rounded-xl bg-card border border-border/50 shadow-sm", className),
|
|
18411
18456
|
onMouseEnter: function onMouseEnter() {
|
|
18412
18457
|
return setIsPaused(true);
|
|
@@ -18452,7 +18497,8 @@ function Carousel(props) {
|
|
|
18452
18497
|
})
|
|
18453
18498
|
})]
|
|
18454
18499
|
});
|
|
18455
|
-
}
|
|
18500
|
+
});
|
|
18501
|
+
Carousel.displayName = "Carousel";
|
|
18456
18502
|
|
|
18457
18503
|
var ThemeContext = /*#__PURE__*/React.createContext(undefined);
|
|
18458
18504
|
var useTheme = function useTheme() {
|
|
@@ -538,6 +538,12 @@
|
|
|
538
538
|
"default": "",
|
|
539
539
|
"description": "Controlled page"
|
|
540
540
|
},
|
|
541
|
+
{
|
|
542
|
+
"prop": "onPageChange",
|
|
543
|
+
"type": "`(page: number) => void`",
|
|
544
|
+
"default": "",
|
|
545
|
+
"description": "Called with the new page number when the page changes. Consumed by the table — it is **not** forwarded onto the `<table>`."
|
|
546
|
+
},
|
|
541
547
|
{
|
|
542
548
|
"prop": "responsiveBreakpoint",
|
|
543
549
|
"type": "`number`",
|
|
@@ -2396,6 +2402,12 @@
|
|
|
2396
2402
|
"default": "",
|
|
2397
2403
|
"description": "Called when logout button is clicked."
|
|
2398
2404
|
},
|
|
2405
|
+
{
|
|
2406
|
+
"prop": "onFetch",
|
|
2407
|
+
"type": "`({ setNotifications }) => void`",
|
|
2408
|
+
"default": "",
|
|
2409
|
+
"description": "Refresh handler for the default notifications dropdown. Called on mount and when `notifications` changes. Consumed by the right menu — it is **not** forwarded onto `<nav>`."
|
|
2410
|
+
},
|
|
2399
2411
|
{
|
|
2400
2412
|
"prop": "className",
|
|
2401
2413
|
"type": "`string`",
|
|
@@ -2406,7 +2418,7 @@
|
|
|
2406
2418
|
"prop": "...rest",
|
|
2407
2419
|
"type": "—",
|
|
2408
2420
|
"default": "",
|
|
2409
|
-
"description": "
|
|
2421
|
+
"description": "Only DOM-valid attributes (e.g. `id`, `aria-*`, `data-*`, event handlers) are forwarded to the root `<nav>`. The component's own control props (`isMobileOpen`, `setIsMobileOpen`, `onFetch`, …) are consumed and never leak to the DOM."
|
|
2410
2422
|
}
|
|
2411
2423
|
],
|
|
2412
2424
|
"examples": "```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\nimport MyEmitter from './emitter';\n\n<Navbar\n emitter={MyEmitter}\n logo={<a href=\"/\"><img src=\"/logo.svg\" alt=\"Home\" /></a>}\n items={[\n { id: '1', label: 'Home', href: '/', active: pathname === '/' },\n { id: '2', label: 'About', href: '/about' },\n { id: '3', label: 'Settings', onClick: () => openSettings() },\n ]}\n user={user}\n notifications={notifications}\n searchable\n onSearch={(term) => doSearch(term)}\n onLoginClick={() => navigate('/login')}\n onLogoutClick={logout}\n onFetch={async ({ setNotifications }) => {\n const res = await fetch('/api/notifications');\n const data = await res.json();\n setNotifications(data.items);\n }}\n/>\n```\n\n[← Component overview](README.md)"
|
|
@@ -3136,7 +3148,7 @@
|
|
|
3136
3148
|
"Input": "# Input\n\nText input with optional label, error/success states, clear button, character count, and password visibility toggle.\n\n## Import\n\n```jsx\nimport { Input } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `id` | `string` | — | Input id (auto-generated if not set) |\n| `className` | `string` | — | Extra CSS classes |\n| `type` | `string` | `\"text\"` | `text`, `search`, `password`, etc. |\n| `label` | `string` | — | Label text |\n| `placeholder` | `string` | — | Placeholder |\n| `error` | `string` | — | Error message (shows error state) |\n| `success` | `boolean` | — | Success state |\n| `disabled` | `boolean` | `false` | Disable input |\n| `required` | `boolean` | `false` | Required field |\n| `clearable` | `boolean` | `false` | Show clear button when has value |\n| `icon` | `ReactNode` | — | Left or right icon |\n| `iconPosition` | `\"left\"` \\| `\"right\"` | `\"left\"` | Icon position |\n| `onClear` | `function` | — | Called when clear is clicked |\n| `showCount` | `boolean` | `false` | Show character count |\n| `maxLength` | `number` | — | Max length (used with showCount) |\n| `readOnly` | `boolean` | `false` | Read-only |\n| `value` | `string` | — | Controlled value |\n| `defaultValue` | `string` | — | Uncontrolled default |\n| `onChange` | `function` | — | Change handler |\n| ...rest | — | — | Passed to native `<input>` |\n\n## Examples\n\n### Basic\n\n```jsx\n<Input label=\"Email\" placeholder=\"you@example.com\" />\n```\n\n### With error\n\n```jsx\n<Input label=\"Email\" error=\"Invalid email address\" />\n```\n\n### Password with toggle\n\n```jsx\n<Input type=\"password\" label=\"Password\" placeholder=\"Enter password\" />\n```\n\n### Clearable and character count\n\n```jsx\n<Input\n label=\"Bio\"\n clearable\n showCount\n maxLength={200}\n placeholder=\"Tell us about yourself\"\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3137
3149
|
"Loader": "# Loader\n\nLoading indicator in three variants: spinner (default), dots, or bar. Configurable size, speed, colors, and optional label text.\n\n## Import\n\n```jsx\nimport { Loader } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` \\| `number` | `\"md\"` | Size: sm=14px, md=20px, lg=36px, or numeric px. |\n| `speed` | `number` | `0.9` | Animation duration in seconds. |\n| `thickness` | `number` | `2.5` | Stroke thickness (spinner). |\n| `color` | `string` | `\"currentColor\"` | Main color (spinner/dots/bar). |\n| `secondaryColor` | `string` | `\"rgba(0,0,0,0.08)\"` | Track/background color. |\n| `variant` | `\"spinner\"` \\| `\"dots\"` \\| `\"bar\"` | `\"spinner\"` | Visual style. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `inline` | `boolean` | `false` | If true, wrapper is inline-flex. |\n| `ariaLabel` | `string` | `\"Loading\"` | Accessibility label. |\n| `text` | `string` | — | Optional label shown next to loader. |\n| `reverse` | `boolean` | `false` | Reverse spinner rotation direction. |\n| `style` | `object` | — | Inline style for wrapper. |\n\n## Examples\n\n```jsx\n<Loader />\n<Loader variant=\"dots\" size=\"sm\" />\n<Loader variant=\"bar\" text=\"Loading...\" />\n<Loader size={32} color=\"#2563eb\" />\n```\n\n[← Component overview](README.md)\n",
|
|
3138
3150
|
"LocationPicker": "# LocationPicker\n\nInput for latitude/longitude. User can type `lat, lng` (e.g. `12.34, 56.78`) or click the icon to use browser geolocation. Value is `{ lat, lng }` or `null`.\n\n## Import\n\n```jsx\nimport { LocationPicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `{ lat: number, lng: number }` \\| `null` | `null` | Current coordinates. |\n| `onChange` | `(coords: { lat, lng } \\| null) => void` | — | Called when value changes (typed or from geolocation). |\n| `inputProps` | `object` | `{}` | Props spread to the underlying input (e.g. `placeholder`). A supplied `inputProps.onChange` is forwarded **in addition to** (not instead of) the component's coord-parsing handler — both fire. `inputProps.className` is merged via `cn()`. |\n| `className` | `string` | — | Classes merged (via `cn()`) onto the root wrapper. |\n| `icon` | `ReactNode` | default pin SVG | Icon for \"use my location\" button. |\n| `iconProps` | `object` | `{}` | Props for the icon button (e.g. `className`, `onClick`). |\n| `iconPosition` | `\"left\"` \\| `\"right\"` | `\"right\"` | Position of the icon button. |\n| `placeholder` | `string` | `\"lat, lng\"` | Input placeholder. |\n\n## Behavior\n\n- Display format is `lat.toFixed(6), lng.toFixed(6)`.\n- Typing a valid \"lat, lng\" string calls `onChange` with `{ lat, lng }` (e.g.\n typing `\"1.5, 2.5\"` calls `onChange({ lat: 1.5, lng: 2.5 })`). A\n consumer-supplied `inputProps.onChange` still fires alongside it.\n- Clearing the input calls `onChange(null)`.\n- Clicking the icon calls `navigator.geolocation.getCurrentPosition` and passes the result to `onChange`. Requires HTTPS in production.\n- Forwards `ref` to the underlying `<input>` and spreads unknown props (`...rest`) onto the root wrapper.\n\n## Example\n\n```jsx\nconst [location, setLocation] = useState(null);\n<LocationPicker\n value={location}\n onChange={setLocation}\n placeholder=\"Enter lat, lng or use location\"\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3139
|
-
"Navbar": "# Navbar\n\nTop navigation bar with logo, nav items (links or buttons), optional search, notifications dropdown, and login/logout. Uses an **emitter** for notification actions (view, markAsRead, markAsUnread, clearAll, delete). Responsive: left icon and hamburger on mobile; desktop nav and search. You can replace the right area with a custom component via `rightMenuContent`.\n\n## Import\n\n```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `emitter` | `object` | **required** | Event emitter for notifications (e.g. `notification:view`, `notification:markAsRead`, etc.). |\n| `logo` | `ReactNode` | — | Logo (e.g. image or link). |\n| `items` | `Array` | `[]` | Nav items: `{ id, label, href?, active?, onClick?(item) }`. If `href` is set, renders `<a>`; else `<button>` with `onClick`. |\n| `user` | `object` \\| `null` | — | If set, shows logout button; if null/undefined, shows login button. |\n| `notifications` | `Array` | `[]` | List of notifications for the dropdown. Each: `{ id, title, message?, read? }`. |\n| `searchable` | `boolean` | `false` | Show search input (desktop). |\n| `onSearch` | `(term: string) => void` | — | Called on search form submit with current search term. |\n| `leftIcon` | `ReactNode` \\| `false` | `<ChevronLeft />` | Icon shown on mobile (e.g. back). Set `false` to hide. |\n| `onLeftIconClick` | `() => void` | — | Called when left icon (mobile) is clicked. |\n| `rightMenuContent` | `(props) => ReactNode` | — | Custom right menu. Receives `{ notifications }` and any Navbar `...props` (e.g. `emitter`, `onFetch`). If not provided, default renders notifications dropdown. |\n| `onLoginClick` | `() => void` | — | Called when login button is clicked. |\n| `onLogoutClick` | `() => void` | — | Called when logout button is clicked. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| ...rest | — | — |
|
|
3151
|
+
"Navbar": "# Navbar\n\nTop navigation bar with logo, nav items (links or buttons), optional search, notifications dropdown, and login/logout. Uses an **emitter** for notification actions (view, markAsRead, markAsUnread, clearAll, delete). Responsive: left icon and hamburger on mobile; desktop nav and search. You can replace the right area with a custom component via `rightMenuContent`.\n\n## Import\n\n```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `emitter` | `object` | **required** | Event emitter for notifications (e.g. `notification:view`, `notification:markAsRead`, etc.). |\n| `logo` | `ReactNode` | — | Logo (e.g. image or link). |\n| `items` | `Array` | `[]` | Nav items: `{ id, label, href?, active?, onClick?(item) }`. If `href` is set, renders `<a>`; else `<button>` with `onClick`. |\n| `user` | `object` \\| `null` | — | If set, shows logout button; if null/undefined, shows login button. |\n| `notifications` | `Array` | `[]` | List of notifications for the dropdown. Each: `{ id, title, message?, read? }`. |\n| `searchable` | `boolean` | `false` | Show search input (desktop). |\n| `onSearch` | `(term: string) => void` | — | Called on search form submit with current search term. |\n| `leftIcon` | `ReactNode` \\| `false` | `<ChevronLeft />` | Icon shown on mobile (e.g. back). Set `false` to hide. |\n| `onLeftIconClick` | `() => void` | — | Called when left icon (mobile) is clicked. |\n| `rightMenuContent` | `(props) => ReactNode` | — | Custom right menu. Receives `{ notifications }` and any Navbar `...props` (e.g. `emitter`, `onFetch`). If not provided, default renders notifications dropdown. |\n| `onLoginClick` | `() => void` | — | Called when login button is clicked. |\n| `onLogoutClick` | `() => void` | — | Called when logout button is clicked. |\n| `onFetch` | `({ setNotifications }) => void` | — | Refresh handler for the default notifications dropdown. Called on mount and when `notifications` changes. Consumed by the right menu — it is **not** forwarded onto `<nav>`. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| ...rest | — | — | Only DOM-valid attributes (e.g. `id`, `aria-*`, `data-*`, event handlers) are forwarded to the root `<nav>`. The component's own control props (`isMobileOpen`, `setIsMobileOpen`, `onFetch`, …) are consumed and never leak to the DOM. |\n\n`Navbar` forwards `ref` to its root `<nav>` element.\n\n## Item shape (items)\n\n- `id`: string or number (key).\n- `label`: string.\n- `href`: optional; if set, item is an `<a href={href}>`.\n- `active`: optional boolean; applies primary styling.\n- `onClick(item)`: optional; used when no `href` (button click).\n\n## Notification shape (notifications)\n\n- `id`: string or number.\n- `title`: string.\n- `message`: optional string.\n- `read`: optional boolean; unread count uses `!n.read`.\n\n## Default notifications dropdown\n\nIf `rightMenuContent` is not provided, the right menu shows a bell icon and dropdown with:\n\n- Unread count badge.\n- \"Clear all\" that clears the list and calls emitter `notification:clearAll`.\n- Per notification: title, message, \"Mark as Read\" / \"Mark as Unread\", \"Delete\" (emitter events).\n- Clicking a notification calls `emitter.emit('notification:view', [n])`.\n\nTo refresh the list from the server, pass `onFetch({ setNotifications })`; the default dropdown uses it on mount and when `notifications` prop changes.\n\n## Example\n\n```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\nimport MyEmitter from './emitter';\n\n<Navbar\n emitter={MyEmitter}\n logo={<a href=\"/\"><img src=\"/logo.svg\" alt=\"Home\" /></a>}\n items={[\n { id: '1', label: 'Home', href: '/', active: pathname === '/' },\n { id: '2', label: 'About', href: '/about' },\n { id: '3', label: 'Settings', onClick: () => openSettings() },\n ]}\n user={user}\n notifications={notifications}\n searchable\n onSearch={(term) => doSearch(term)}\n onLoginClick={() => navigate('/login')}\n onLogoutClick={logout}\n onFetch={async ({ setNotifications }) => {\n const res = await fetch('/api/notifications');\n const data = await res.json();\n setNotifications(data.items);\n }}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3140
3152
|
"Pagination": "# Pagination\n\nPage navigation: first, previous, page numbers, next, last. Renders only when `totalPages > 1`. Optional `theme` for styling (e.g. from Table).\n\n## Import\n\n```jsx\nimport { Pagination } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `currentPage` | `number` | `1` | Current page (1-based). |\n| `totalPages` | `number` | `1` | Total pages. If ≤ 1, component returns null. |\n| `onPageChange` | `(page: number) => void` | — | Called when user selects a page. |\n| `showFirstLast` | `boolean` | `true` | Show first/last page buttons. |\n| `showPrevNext` | `boolean` | `true` | Show previous/next buttons. |\n| `maxVisiblePages` | `number` | `5` | Max page number buttons to show. |\n| `className` | `string` | — | Nav wrapper CSS classes. |\n| ...rest | — | — | Passed to `<nav>`. |\n\n## Example\n\n```jsx\n<Pagination\n currentPage={page}\n totalPages={Math.ceil(total / pageSize)}\n onPageChange={setPage}\n maxVisiblePages={5}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3141
3153
|
"PriceRangePicker": "# PriceRangePicker\n\nDual-thumb range slider for min/max values (e.g. price or any number). Optional number inputs and preset buttons. Controlled via `value` or uncontrolled via `defaultValue`.\n\n## Import\n\n```jsx\nimport { PriceRangePicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `min` | `number` | `0` | Minimum value. |\n| `max` | `number` | `1000` | Maximum value. |\n| `step` | `number` | `1` | Step for thumbs and inputs. |\n| `minGap` | `number` | `5` | Minimum gap between min and max. |\n| `value` | `{ min, max }` \\| `null` | `null` | Controlled value. |\n| `defaultValue` | `{ min, max }` | `{ min: 0, max: 1000 }` | Uncontrolled initial value. |\n| `onChange` | `(value: { min, max }) => void` | `() => {}` | Called on thumb/input change. |\n| `onFinalChange` | `(value: { min, max }) => void` | `() => {}` | Called on mouseup/touchend or Enter in inputs. |\n| `showInputs` | `boolean` | `true` | Show min/max number inputs. |\n| `showTooltips` | `boolean` | `true` | Show tooltips on thumbs. |\n| `disabled` | `boolean` | `false` | Disable the control. |\n| `presets` | `Array<{ id, label, value: { min, max } }>` | `[]` | Preset buttons. |\n| `formatValue` | `(n: number) => string` | `(n) => String(n)` | Format display (e.g. currency). |\n| `className` | `string` | `\"\"` | Container CSS classes. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Thumb and spacing size. |\n| `colorClass` | `string` | `\"bg-pink-500\"` | Tailwind class for active track/thumb. |\n| `ariaLabel` | `string` | `\"Price range\"` | Accessibility label. |\n\n## Example\n\n```jsx\nconst [range, setRange] = useState({ min: 100, max: 500 });\n<PriceRangePicker\n min={0}\n max={1000}\n value={range}\n onChange={setRange}\n formatValue={(n) => `$${n}`}\n presets={[\n { id: '1', label: 'Under $200', value: { min: 0, max: 200 } },\n ]}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3142
3154
|
"ProgressBar": "# ProgressBar\n\nProgress bar showing a value between 0 and max. Supports custom HEX colors, optional label, value text inside the bar, striped and animated styles.\n\n## Import\n\n```jsx\nimport { ProgressBar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `number` | `0` | Current value. |\n| `max` | `number` | `100` | Maximum value. |\n| `size` | `\"xs\"` \\| `\"sm\"` \\| `\"md\"` \\| `\"lg\"` \\| `number` | `\"md\"` | Height: xs/sm/md/lg or px. |\n| `showValue` | `boolean` | `false` | Show percentage text inside the fill. |\n| `rounded` | `boolean` | `true` | Rounded corners. |\n| `color` | `string` (HEX) | `\"#2563eb\"` | Fill color (HEX only). |\n| `bgColor` | `string` (HEX) | `\"#e6eefc\"` | Track background (HEX only). |\n| `valueColor` | `string` (HEX) | auto | Text color inside fill; auto from luminance if omitted. |\n| `striped` | `boolean` | `false` | Striped fill pattern. |\n| `animated` | `boolean` | `false` | Animate stripe movement. |\n| `label` | `string` | `\"\"` | Label above the bar. |\n| `ariaLabel` | `string` | `\"Progress\"` | Accessibility label. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `style` | `object` | `{}` | Wrapper inline style. |\n\n## Example\n\n```jsx\n<ProgressBar value={60} max={100} />\n<ProgressBar value={75} showValue label=\"Upload\" color=\"#16a34a\" />\n<ProgressBar value={40} striped animated size=\"lg\" />\n```\n\n[← Component overview](README.md)\n",
|
|
@@ -3149,7 +3161,7 @@
|
|
|
3149
3161
|
"SpeechToText": "# SpeechToText\n\nVoice-to-text using the Web Speech API. Headless by default — render a custom\ncontrol via `renderButton`, or drive it imperatively through the ref. The\nbuilt-in fallback button is `className`-extensible and forwards arbitrary props.\n\n## Import\n\n```jsx\nimport { SpeechToText } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `lang` | `string` | `\"en-US\"` | Recognition language |\n| `continuous` | `boolean` | `true` | Keep listening until stopped (forced `false` on mobile) |\n| `interimResults` | `boolean` | `true` | Return interim results |\n| `onSpeechComplete` | `function` | — | Final transcript chunk callback `(text) => void` |\n| `onSpeaking` | `function` | — | Interim transcript callback `(text) => void` |\n| `onError` | `function` | — | Fatal error callback `(Error) => void`. Routine events (`no-speech`, `aborted`) are **not** surfaced |\n| `onStart` | `function` | — | Start callback |\n| `onStop` | `function` | — | Stop callback |\n| `renderButton` | `function` | — | Custom control render-prop (see signature below) |\n| `autoStart` | `boolean` | `false` | Start on mount (once, after support is detected) |\n| `disabled` | `boolean` | `false` | Disable |\n| `resetOnStart` | `boolean` | `false` | Clear the accumulated transcript when a new session starts |\n| `className` | `string` | — | Merged (via `cn`) onto the default button |\n| `...rest` | — | — | Forwarded to the default `<button>` |\n\nThe default button is keyboard-accessible (`aria-pressed`, `aria-label`) and\ntoken-driven. When `renderButton` is supplied, `className`/`...rest` are not\napplied (you own the rendered control).\n\n## `renderButton` signature\n\n```js\nrenderButton({ isListening, isSupported, error, start, stop, toggle, disabled })\n```\n\n## Ref methods\n\n`start()`, `stop()`, `toggle()`, `isListening()`, `isSupported()`,\n`getTranscript()`, `clearTranscript()`, `getError()`.\n\n## Example\n\n```jsx\nconst [transcript, setTranscript] = useState('');\n<SpeechToText\n onSpeechComplete={(chunk) => setTranscript((t) => `${t} ${chunk}`.trim())}\n onError={(e) => console.error(e)}\n/>\n<div>Transcript: {transcript}</div>\n```\n\n[← Component overview](README.md)\n",
|
|
3150
3162
|
"Stepper": "# Stepper\n\nHorizontal or vertical step indicator. Each step has circle (with check for completed), optional line, and label. Optional `onStepClick` for clickable steps.\n\n## Import\n\n```jsx\nimport { Stepper } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `steps` | `Array` | `[]` | Each step: `{ id?, label?, description? }`. |\n| `currentStep` | `number` | `0` | Zero-based index of current step. |\n| `orientation` | `\"horizontal\"` \\| `\"vertical\"` | `\"horizontal\"` | Layout. |\n| `variant` | `string` | `\"default\"` | Visual variant. |\n| `onStepClick` | `(step, stepIndex) => void` | — | Called when a step is clicked (e.g. for completed/current). |\n| `className` | `string` | — | Nav wrapper CSS classes. |\n| ...rest | — | — | Passed to `<nav>`. |\n\n## Step status\n\n- **completed**: `stepIndex < currentStep` (check icon, primary color).\n- **current**: `stepIndex === currentStep`.\n- **upcoming**: `stepIndex > currentStep` (gray).\n\n## Example\n\n```jsx\n<Stepper\n steps={[\n { id: '1', label: 'Details' },\n { id: '2', label: 'Payment' },\n { id: '3', label: 'Confirm' },\n ]}\n currentStep={1}\n orientation=\"horizontal\"\n onStepClick={(step, idx) => setStep(idx)}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3151
3163
|
"Switch": "# Switch\n\nToggle switch (on/off). Controlled or uncontrolled.\n\n## Import\n\n```jsx\nimport { Switch } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `checked` | `boolean` | — | Controlled checked |\n| `defaultChecked` | `boolean` | `false` | Uncontrolled default |\n| `onChange` | `(checked: boolean) => void` | — | Receives the new boolean state (not a DOM event) |\n| `disabled` | `boolean` | `false` | Disable |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg` |\n| `name` | `string` | — | Form name |\n| `topLabel` | `string` | — | Label above |\n| `bottomLabel` | `string` | — | Label below |\n| `leftLabel` | `string` | — | Label left |\n| `rightLabel` | `string` | — | Label right |\n\n## Example\n\n```jsx\n<Switch checked={enabled} onChange={checked => setEnabled(checked)} />\n<Switch defaultChecked rightLabel=\"Enable notifications\" />\n```\n\n[← Component overview](README.md)\n",
|
|
3152
|
-
"Table": "# Table\n\nData table with sorting, filtering, pagination, row selection, expandable details, and responsive mobile card view.\n\n## Import\n\n```jsx\nimport { Table } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `data` | `Array` | `[]` | Row data (array of objects) |\n| `columns` | `Array` | `[]` | `[{ key, label, sortable?, isVisible?, render? }]` |\n| `sortable` | `boolean` | `true` | Enable column sort |\n| `filterable` | `boolean` | `false` | Enable column filters |\n| `selectable` | `boolean` | `false` | Row selection checkboxes |\n| `pagination` | `boolean` | `false` | Enable pagination |\n| `pageSize` | `number` | `25` | Rows per page |\n| `onSort` | `function` | — | Sort callback |\n| `onFilter` | `function` | — | Filter callback |\n| `onFetch` | `function` | — | Server-side fetch (setData, setLoading, filters, page, limit, sort) |\n| `onFilterChange` | `function` | — | Filter change callback |\n| `onSelectionChange` | `function` | — | Selected rows callback |\n| `onRowClick` | `function` | — | Row click callback |\n| `hasDetails` | `boolean` | `false` | Expandable row details |\n| `DetailsComponent` | `Component` | — | Component for expanded content |\n| `withAction` | `boolean` | `true` | Show actions column |\n| `onAction` | `function` | — | Action menu callback |\n| `actions` | `Array` | — | Custom actions (edit, delete, etc.) |\n| `showSerial` | `boolean` | `true` | Show row number column |\n| `cellClass` | `string` \\| `function` | — | Cell className |\n| `rowClass` | `string` \\| `function` | — | Row className |\n| `globalSearch` | `boolean` | `false` | Global search box |\n| `limitOptions` | `number[]` | `[10,25,50,100]` | Page size options |\n| `showLimitSelector` | `boolean` | `true` | Show page size selector |\n| `showReloadButton` | `boolean` | `true` | Show reload button |\n| `onReload` | `function` | — | Reload click handler |\n| `stripedRows` | `boolean` | `true` | Striped row background |\n| `theme` | `object` | — | `stripedColors`, `rowHover`, `accentColor` |\n| `serverSide` | `boolean` | `false` | Server-side pagination/sort/filter |\n| `totalRecords` | `number` | `0` | Total count (serverSide) |\n| `pageNumber` | `number` | — | Controlled page |\n| `responsiveBreakpoint` | `number` | `768` | px breakpoint for mobile cards |\n\n## Examples\n\n### Basic table\n\n```jsx\nconst columns = [\n { key: 'name', label: 'Name' },\n { key: 'email', label: 'Email' },\n];\nconst data = [\n { id: 1, name: 'Alice', email: 'alice@example.com' },\n { id: 2, name: 'Bob', email: 'bob@example.com' },\n];\n<Table data={data} columns={columns} />\n```\n\n### With pagination and selection\n\n```jsx\n<Table\n data={data}\n columns={columns}\n pagination\n pageSize={10}\n selectable\n onSelectionChange={(selected) => console.log(selected)}\n/>\n```\n\n### Server-side data\n\n```jsx\n<Table\n data={data}\n columns={columns}\n serverSide\n pagination\n totalRecords={total}\n onFetch={async ({ setData, setLoading, page, limit, sort }) => {\n setLoading(true);\n const res = await fetch(`/api/users?page=${page}&limit=${limit}`);\n const json = await res.json();\n setData(json.rows);\n setLoading(false);\n }}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3164
|
+
"Table": "# Table\n\nData table with sorting, filtering, pagination, row selection, expandable details, and responsive mobile card view.\n\n## Import\n\n```jsx\nimport { Table } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `data` | `Array` | `[]` | Row data (array of objects) |\n| `columns` | `Array` | `[]` | `[{ key, label, sortable?, isVisible?, render? }]` |\n| `sortable` | `boolean` | `true` | Enable column sort |\n| `filterable` | `boolean` | `false` | Enable column filters |\n| `selectable` | `boolean` | `false` | Row selection checkboxes |\n| `pagination` | `boolean` | `false` | Enable pagination |\n| `pageSize` | `number` | `25` | Rows per page |\n| `onSort` | `function` | — | Sort callback |\n| `onFilter` | `function` | — | Filter callback |\n| `onFetch` | `function` | — | Server-side fetch (setData, setLoading, filters, page, limit, sort) |\n| `onFilterChange` | `function` | — | Filter change callback |\n| `onSelectionChange` | `function` | — | Selected rows callback |\n| `onRowClick` | `function` | — | Row click callback |\n| `hasDetails` | `boolean` | `false` | Expandable row details |\n| `DetailsComponent` | `Component` | — | Component for expanded content |\n| `withAction` | `boolean` | `true` | Show actions column |\n| `onAction` | `function` | — | Action menu callback |\n| `actions` | `Array` | — | Custom actions (edit, delete, etc.) |\n| `showSerial` | `boolean` | `true` | Show row number column |\n| `cellClass` | `string` \\| `function` | — | Cell className |\n| `rowClass` | `string` \\| `function` | — | Row className |\n| `globalSearch` | `boolean` | `false` | Global search box |\n| `limitOptions` | `number[]` | `[10,25,50,100]` | Page size options |\n| `showLimitSelector` | `boolean` | `true` | Show page size selector |\n| `showReloadButton` | `boolean` | `true` | Show reload button |\n| `onReload` | `function` | — | Reload click handler |\n| `stripedRows` | `boolean` | `true` | Striped row background |\n| `theme` | `object` | — | `stripedColors`, `rowHover`, `accentColor` |\n| `serverSide` | `boolean` | `false` | Server-side pagination/sort/filter |\n| `totalRecords` | `number` | `0` | Total count (serverSide) |\n| `pageNumber` | `number` | — | Controlled page |\n| `onPageChange` | `(page: number) => void` | — | Called with the new page number when the page changes. Consumed by the table — it is **not** forwarded onto the `<table>`. |\n| `responsiveBreakpoint` | `number` | `768` | px breakpoint for mobile cards |\n\nOnly DOM-valid attributes in `...rest` (e.g. `id`, `aria-*`, `data-*`) are\nforwarded to the root `<table>`; the table's own control props (`onPageChange`,\n`serverSide`, `pagination`, the `on*` callbacks, …) are consumed and never leak\nto the DOM as unknown attributes.\n\n## Examples\n\n### Basic table\n\n```jsx\nconst columns = [\n { key: 'name', label: 'Name' },\n { key: 'email', label: 'Email' },\n];\nconst data = [\n { id: 1, name: 'Alice', email: 'alice@example.com' },\n { id: 2, name: 'Bob', email: 'bob@example.com' },\n];\n<Table data={data} columns={columns} />\n```\n\n### With pagination and selection\n\n```jsx\n<Table\n data={data}\n columns={columns}\n pagination\n pageSize={10}\n selectable\n onSelectionChange={(selected) => console.log(selected)}\n/>\n```\n\n### Server-side data\n\n```jsx\n<Table\n data={data}\n columns={columns}\n serverSide\n pagination\n totalRecords={total}\n onFetch={async ({ setData, setLoading, page, limit, sort }) => {\n setLoading(true);\n const res = await fetch(`/api/users?page=${page}&limit=${limit}`);\n const json = await res.json();\n setData(json.rows);\n setLoading(false);\n }}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3153
3165
|
"Tabs": "# Tabs\n\nTabbed content with list and panels. Use subcomponents: `Tabs.List`, `Tabs.Tab`, `Tabs.Panels`, `Tabs.Panel`. Supports controlled (`index` + `onChange`) or uncontrolled (`defaultIndex`), keyboard navigation, and variants.\n\n## Import\n\n```jsx\nimport { Tabs } from '@dreamtree-org/twreact-ui';\n```\n\n## Props (Tabs root)\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Must include `Tabs.List` and `Tabs.Panels`. |\n| `defaultIndex` | `number` | `0` | Uncontrolled initial active tab index. |\n| `index` | `number` | — | Controlled active index. |\n| `onChange` | `(index: number) => void` | — | Called when tab changes. |\n| `orientation` | `\"horizontal\"` \\| `\"vertical\"` | `\"horizontal\"` | Layout direction. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Tab size. |\n| `variant` | `\"line\"` \\| `\"pills\"` \\| `\"unstyled\"` | `\"line\"` | Tab style. |\n| `animated` | `boolean` | `true` | Fade animation on panel change. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n\n## Usage\n\n```jsx\n<Tabs defaultIndex={0} variant=\"pills\" size=\"md\">\n <Tabs.List>\n <Tabs.Tab>Home</Tabs.Tab>\n <Tabs.Tab>Profile</Tabs.Tab>\n <Tabs.Tab>Settings</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panels>\n <Tabs.Panel>Home content</Tabs.Panel>\n <Tabs.Panel>Profile content</Tabs.Panel>\n <Tabs.Panel>Settings content</Tabs.Panel>\n </Tabs.Panels>\n</Tabs>\n```\n\nControlled:\n\n```jsx\nconst [index, setIndex] = useState(0);\n<Tabs index={index} onChange={setIndex}>\n ...\n</Tabs>\n```\n\n[← Component overview](README.md)\n",
|
|
3154
3166
|
"TextToSpeech": "# TextToSpeech\n\nText-to-speech using the browser’s Speech Synthesis API. Renders a default \"Speak\" / \"Stop\" button or a custom button via `renderButton`. Toggling speak while playing stops playback.\n\n## Import\n\n```jsx\nimport { TextToSpeech } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `text` | `string` | `\"\"` | Text to speak (used as initial input if component manages input). |\n| `rate` | `number` | `1` | Speech rate (0.1–10). |\n| `pitch` | `number` | `0.5` | Pitch (0–2). |\n| `onSpeak` | `(text: string) => void` | `() => {}` | Called when speech starts (with the text spoken). |\n| `renderButton` | `(props: { onClick, isSpeaking }) => ReactNode` | — | Custom button; receives `onClick` and `isSpeaking`. |\n\n## Behavior\n\n- Component keeps internal `inputText` state initialized from `text`; speaking uses that.\n- Clicking the button toggles: if not speaking, starts `SpeechSynthesisUtterance` with `inputText`; if speaking, calls `speechSynthesis.cancel()` and sets speaking to false.\n- `onSpeak` is called when speech starts.\n\n## Example\n\n```jsx\n<TextToSpeech text=\"Hello, world!\" rate={1} onSpeak={(t) => console.log('Speaking:', t)} />\n\n<TextToSpeech\n text={content}\n renderButton={({ onClick, isSpeaking }) => (\n <Button onClick={onClick}>{isSpeaking ? 'Stop' : 'Play'} audio</Button>\n )}\n/>\n```\n\n[← Component overview](README.md)\n",
|
|
3155
3167
|
"ThreeDotPopover": "# ThreeDotPopover\n\nDropdown menu triggered by a three-dot (kebab) button. Use for row actions (Edit, Delete, etc.). Closes on outside click and Escape; optional close on item select.\n\n## Import\n\n```jsx\nimport { ThreeDotPopover } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | Menu items: `{ key, label, icon?, onClick?, disabled?, destructive? }`. `icon` can be component (e.g. `Edit2`). |\n| `trigger` | `ReactNode` | — | Custom trigger; default is three-dot button. |\n| `className` | `string` | `\"\"` | CSS classes for the **default** trigger button (merged via `cn()`). |\n| `wrapperClassName` | `string` | `\"\"` | CSS classes merged (via `cn()`) onto the root container element. |\n| `menuClass` | `string` | `\"\"` | Menu container CSS classes. |\n| `menuItemClass` | `string` | `\"\"` | Each menu item CSS classes. |\n| `closeOnSelect` | `boolean` | `true` | Close menu when an item is selected. |\n| `ariaLabel` | `string` | `\"More options\"` | Trigger button aria-label. |\n\n## Item shape\n\n- `key` (string): Unique key.\n- `label` (string): Display text.\n- `icon` (optional): React component or node.\n- `onClick(item)` (optional): Called when item is clicked.\n- `disabled` (boolean): Disable the item.\n- `destructive` (boolean): Style as destructive (e.g. red for Delete).\n\n## Example\n\n```jsx\nimport { Edit2, Eye, Trash } from 'lucide-react';\n\n<ThreeDotPopover\n items={[\n { key: 'edit', label: 'Edit', icon: Edit2, onClick: () => edit(row) },\n { key: 'view', label: 'View', icon: Eye, onClick: () => view(row) },\n { key: 'delete', label: 'Delete', destructive: true, onClick: () => remove(row) },\n ]}\n closeOnSelect\n/>\n```\n\n## Notes\n\n- Forwards `ref` to the root container element and spreads unknown props\n (`...rest`) onto it.\n\n[← Component overview](README.md)\n",
|