@olwiba/ui 0.2.24 → 0.2.25
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/index.d.ts +51 -3
- package/dist/index.js +40 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Chart.tsx +38 -7
- package/src/components/DataTable.tsx +56 -8
- package/src/components/Notify.tsx +32 -1
- package/src/marketing/Footer.tsx +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -1217,8 +1217,14 @@ interface FooterProps {
|
|
|
1217
1217
|
icon: ReactNode;
|
|
1218
1218
|
}>;
|
|
1219
1219
|
legal?: string;
|
|
1220
|
+
/**
|
|
1221
|
+
* Live status pill. `label` is a ReactNode, not a string: a real status
|
|
1222
|
+
* pill often carries per-service detail in a tooltip, and typing it as
|
|
1223
|
+
* string forced consumers to smuggle that through `as unknown as string`.
|
|
1224
|
+
* A plain string still works and is the common case.
|
|
1225
|
+
*/
|
|
1220
1226
|
status?: {
|
|
1221
|
-
label:
|
|
1227
|
+
label: ReactNode;
|
|
1222
1228
|
operational?: boolean;
|
|
1223
1229
|
};
|
|
1224
1230
|
renderLink?: AppShellRenderLink;
|
|
@@ -1513,6 +1519,23 @@ interface DataTableProps<TData> {
|
|
|
1513
1519
|
onSelectionChange?: (rows: TData[]) => void;
|
|
1514
1520
|
/** Rows per page. Set to `0` to disable pagination entirely. @default 10 */
|
|
1515
1521
|
pageSize?: number;
|
|
1522
|
+
/**
|
|
1523
|
+
* Hands pagination to the caller, for data the client does not hold all of.
|
|
1524
|
+
*
|
|
1525
|
+
* With this set, `data` is treated as the current page rather than the whole
|
|
1526
|
+
* set: the table stops slicing, and the footer reports and drives the
|
|
1527
|
+
* caller's page instead of its own. Without it nothing changes — a table
|
|
1528
|
+
* given every row keeps paginating locally, which is right for the common
|
|
1529
|
+
* case and avoids making every consumer implement paging to get a table.
|
|
1530
|
+
*/
|
|
1531
|
+
pagination?: {
|
|
1532
|
+
pageIndex: number;
|
|
1533
|
+
/** Total pages. Omit when unknown — the footer then relies on `hasNext`. */
|
|
1534
|
+
pageCount?: number;
|
|
1535
|
+
hasNext?: boolean;
|
|
1536
|
+
hasPrevious?: boolean;
|
|
1537
|
+
onPageChange: (pageIndex: number) => void;
|
|
1538
|
+
};
|
|
1516
1539
|
/** Slot rendered top-right of the toolbar — e.g. an "Add" button. */
|
|
1517
1540
|
toolbar?: React.ReactNode;
|
|
1518
1541
|
onRowClick?: (row: TData) => void;
|
|
@@ -1524,7 +1547,7 @@ interface DataTableProps<TData> {
|
|
|
1524
1547
|
* toggle `searchKey`/`selectable`/`pageSize` rather than reaching for a
|
|
1525
1548
|
* different table component per use case.
|
|
1526
1549
|
*/
|
|
1527
|
-
declare function DataTable<TData>({ columns, data, searchKey, searchPlaceholder, selectable, onSelectionChange, pageSize, toolbar, onRowClick, emptyMessage, className, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
|
|
1550
|
+
declare function DataTable<TData>({ columns, data, searchKey, searchPlaceholder, selectable, onSelectionChange, pageSize, pagination, toolbar, onRowClick, emptyMessage, className, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
|
|
1528
1551
|
|
|
1529
1552
|
interface LoadMoreProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
1530
1553
|
hasNextPage: boolean;
|
|
@@ -1635,6 +1658,27 @@ interface ChartProps {
|
|
|
1635
1658
|
grid?: boolean;
|
|
1636
1659
|
/** Legend. @default true for multiple series or donut, false for one series */
|
|
1637
1660
|
legend?: boolean;
|
|
1661
|
+
/**
|
|
1662
|
+
* Stack series instead of overlaying them. Area and bar only — a stacked
|
|
1663
|
+
* line is a shape people misread as absolute values.
|
|
1664
|
+
*
|
|
1665
|
+
* Off by default: stacking answers "what does the total split into", and
|
|
1666
|
+
* silently switching a two-series comparison to it would change what an
|
|
1667
|
+
* existing chart claims.
|
|
1668
|
+
*/
|
|
1669
|
+
stacked?: boolean;
|
|
1670
|
+
/**
|
|
1671
|
+
* Formats x-axis ticks. Separate from `valueFormatter`, which formats the
|
|
1672
|
+
* measured value — an axis of ISO dates wants shortening without changing
|
|
1673
|
+
* what the tooltip reports.
|
|
1674
|
+
*/
|
|
1675
|
+
xTickFormatter?: (value: string) => string;
|
|
1676
|
+
/**
|
|
1677
|
+
* Fixes the y-axis range. Without it recharts scales to the data, which for
|
|
1678
|
+
* a percentage series makes a 98-100%% band fill the plot and read as
|
|
1679
|
+
* volatility.
|
|
1680
|
+
*/
|
|
1681
|
+
yDomain?: [number, number];
|
|
1638
1682
|
/** Formats values in tooltips and the y-axis, e.g. `(v) => \`$${v}\``. */
|
|
1639
1683
|
valueFormatter?: (value: number) => string;
|
|
1640
1684
|
className?: string;
|
|
@@ -1646,7 +1690,7 @@ interface ChartProps {
|
|
|
1646
1690
|
* comparison, donut for part-of-whole identity. More than 5 donut slices:
|
|
1647
1691
|
* fold the tail into an "Other" slice in your data instead of adding hues.
|
|
1648
1692
|
*/
|
|
1649
|
-
declare function Chart({ type, data, xKey, series, height, grid, legend, valueFormatter, className, }: ChartProps): react_jsx_runtime.JSX.Element;
|
|
1693
|
+
declare function Chart({ type, data, xKey, series, height, grid, legend, stacked, xTickFormatter, yDomain, valueFormatter, className, }: ChartProps): react_jsx_runtime.JSX.Element;
|
|
1650
1694
|
|
|
1651
1695
|
interface FileUploadEntry {
|
|
1652
1696
|
id: string;
|
|
@@ -1706,6 +1750,10 @@ interface NotificationToastProps {
|
|
|
1706
1750
|
*/
|
|
1707
1751
|
declare function NotificationToast({ variant, title, description, avatar, action, secondaryAction, onDismiss, }: NotificationToastProps): react_jsx_runtime.JSX.Element;
|
|
1708
1752
|
interface NotifyOptions extends Omit<NotificationToastProps, 'onDismiss'> {
|
|
1753
|
+
/**
|
|
1754
|
+
* Overrides the per-variant default below. Explicit always wins — a caller
|
|
1755
|
+
* that has thought about the timing knows more than this heuristic does.
|
|
1756
|
+
*/
|
|
1709
1757
|
duration?: number;
|
|
1710
1758
|
}
|
|
1711
1759
|
/** Fires a `NotificationToast` through sonner. Requires `<Toaster />` from `@olwiba/cn` mounted once in your app. */
|
package/dist/index.js
CHANGED
|
@@ -962,6 +962,7 @@ function DataTable({
|
|
|
962
962
|
selectable = false,
|
|
963
963
|
onSelectionChange,
|
|
964
964
|
pageSize = 10,
|
|
965
|
+
pagination,
|
|
965
966
|
toolbar,
|
|
966
967
|
onRowClick,
|
|
967
968
|
emptyMessage = "No results.",
|
|
@@ -988,8 +989,11 @@ function DataTable({
|
|
|
988
989
|
},
|
|
989
990
|
getCoreRowModel: getCoreRowModel(),
|
|
990
991
|
getSortedRowModel: getSortedRowModel(),
|
|
991
|
-
|
|
992
|
-
|
|
992
|
+
// Server-paginated tables must not slice: `data` is already the page, and
|
|
993
|
+
// running the client model over it would paginate a single page again.
|
|
994
|
+
...pageSize > 0 && !pagination ? { getPaginationRowModel: getPaginationRowModel() } : {},
|
|
995
|
+
...pagination ? { manualPagination: true } : {},
|
|
996
|
+
initialState: pageSize > 0 && !pagination ? { pagination: { pageSize } } : void 0,
|
|
993
997
|
enableRowSelection: selectable
|
|
994
998
|
});
|
|
995
999
|
React21.useEffect(() => {
|
|
@@ -997,6 +1001,12 @@ function DataTable({
|
|
|
997
1001
|
onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
|
|
998
1002
|
}, [rowSelection]);
|
|
999
1003
|
const rows = table.getRowModel().rows;
|
|
1004
|
+
const canPrevious = pagination ? pagination.hasPrevious ?? pagination.pageIndex > 0 : table.getCanPreviousPage();
|
|
1005
|
+
const canNext = pagination ? pagination.hasNext ?? (pagination.pageCount !== void 0 && pagination.pageIndex < pagination.pageCount - 1) : table.getCanNextPage();
|
|
1006
|
+
const goPrevious = () => pagination ? pagination.onPageChange(pagination.pageIndex - 1) : table.previousPage();
|
|
1007
|
+
const goNext = () => pagination ? pagination.onPageChange(pagination.pageIndex + 1) : table.nextPage();
|
|
1008
|
+
const showPager = pagination ? canPrevious || canNext : pageSize > 0 && table.getPageCount() > 1;
|
|
1009
|
+
const pageLabel = pagination ? pagination.pageCount !== void 0 ? `Page ${pagination.pageIndex + 1} of ${pagination.pageCount}` : `Page ${pagination.pageIndex + 1}` : `Page ${table.getState().pagination.pageIndex + 1} of ${table.getPageCount()}`;
|
|
1000
1010
|
return /* @__PURE__ */ jsxs("div", { className: cn$1("space-y-4", className), children: [
|
|
1001
1011
|
(searchKey || toolbar) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
1002
1012
|
searchKey ? /* @__PURE__ */ jsxs("div", { className: "relative max-w-sm flex-1", children: [
|
|
@@ -1052,18 +1062,18 @@ function DataTable({
|
|
|
1052
1062
|
row.id
|
|
1053
1063
|
)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: allColumns.length, className: "h-24 text-center text-muted-foreground", children: emptyMessage }) }) })
|
|
1054
1064
|
] }) }),
|
|
1055
|
-
(selectable ||
|
|
1065
|
+
(selectable || showPager) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1056
1066
|
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1057
1067
|
selectable && `${table.getFilteredSelectedRowModel().rows.length} of ${table.getFilteredRowModel().rows.length} selected`,
|
|
1058
|
-
selectable &&
|
|
1059
|
-
|
|
1068
|
+
selectable && showPager && " \xB7 ",
|
|
1069
|
+
showPager && pageLabel
|
|
1060
1070
|
] }),
|
|
1061
|
-
|
|
1062
|
-
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick:
|
|
1071
|
+
showPager && /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1072
|
+
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: goPrevious, disabled: !canPrevious, children: [
|
|
1063
1073
|
/* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" }),
|
|
1064
1074
|
" Previous"
|
|
1065
1075
|
] }),
|
|
1066
|
-
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick:
|
|
1076
|
+
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: goNext, disabled: !canNext, children: [
|
|
1067
1077
|
"Next ",
|
|
1068
1078
|
/* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
1069
1079
|
] })
|
|
@@ -4328,6 +4338,9 @@ function Chart({
|
|
|
4328
4338
|
height = 300,
|
|
4329
4339
|
grid = true,
|
|
4330
4340
|
legend,
|
|
4341
|
+
stacked = false,
|
|
4342
|
+
xTickFormatter,
|
|
4343
|
+
yDomain,
|
|
4331
4344
|
valueFormatter = (v) => String(v),
|
|
4332
4345
|
className
|
|
4333
4346
|
}) {
|
|
@@ -4370,12 +4383,13 @@ function Chart({
|
|
|
4370
4383
|
if (type === "bar") {
|
|
4371
4384
|
chart = /* @__PURE__ */ jsxs(BarChart, { data, barCategoryGap: "25%", children: [
|
|
4372
4385
|
gridEl,
|
|
4373
|
-
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
|
|
4374
|
-
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
|
|
4386
|
+
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps, tickFormatter: xTickFormatter }),
|
|
4387
|
+
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, domain: yDomain, tickFormatter: valueFormatter }),
|
|
4375
4388
|
tooltip,
|
|
4376
4389
|
series.map((s, i) => /* @__PURE__ */ jsx(
|
|
4377
4390
|
Bar,
|
|
4378
4391
|
{
|
|
4392
|
+
stackId: stacked ? "stack" : void 0,
|
|
4379
4393
|
dataKey: s.key,
|
|
4380
4394
|
name: s.label ?? s.key,
|
|
4381
4395
|
fill: seriesColor(s, i),
|
|
@@ -4388,8 +4402,8 @@ function Chart({
|
|
|
4388
4402
|
} else if (type === "area") {
|
|
4389
4403
|
chart = /* @__PURE__ */ jsxs(AreaChart, { data, children: [
|
|
4390
4404
|
gridEl,
|
|
4391
|
-
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
|
|
4392
|
-
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
|
|
4405
|
+
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps, tickFormatter: xTickFormatter }),
|
|
4406
|
+
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, domain: yDomain, tickFormatter: valueFormatter }),
|
|
4393
4407
|
tooltip,
|
|
4394
4408
|
series.map((s, i) => /* @__PURE__ */ jsx(
|
|
4395
4409
|
Area,
|
|
@@ -4397,10 +4411,11 @@ function Chart({
|
|
|
4397
4411
|
type: "monotone",
|
|
4398
4412
|
dataKey: s.key,
|
|
4399
4413
|
name: s.label ?? s.key,
|
|
4414
|
+
stackId: stacked ? "stack" : void 0,
|
|
4400
4415
|
stroke: seriesColor(s, i),
|
|
4401
4416
|
strokeWidth: 2,
|
|
4402
4417
|
fill: seriesColor(s, i),
|
|
4403
|
-
fillOpacity: 0.12,
|
|
4418
|
+
fillOpacity: stacked ? 0.35 : 0.12,
|
|
4404
4419
|
dot: false,
|
|
4405
4420
|
activeDot: { r: 4 }
|
|
4406
4421
|
},
|
|
@@ -4410,8 +4425,8 @@ function Chart({
|
|
|
4410
4425
|
} else {
|
|
4411
4426
|
chart = /* @__PURE__ */ jsxs(LineChart, { data, children: [
|
|
4412
4427
|
gridEl,
|
|
4413
|
-
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
|
|
4414
|
-
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
|
|
4428
|
+
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps, tickFormatter: xTickFormatter }),
|
|
4429
|
+
/* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, domain: yDomain, tickFormatter: valueFormatter }),
|
|
4415
4430
|
tooltip,
|
|
4416
4431
|
series.map((s, i) => /* @__PURE__ */ jsx(
|
|
4417
4432
|
Line,
|
|
@@ -4638,9 +4653,18 @@ function NotificationToast({
|
|
|
4638
4653
|
] })
|
|
4639
4654
|
] }) });
|
|
4640
4655
|
}
|
|
4656
|
+
function defaultDuration(variant, hasAction) {
|
|
4657
|
+
if (variant === "error") return 1e4;
|
|
4658
|
+
if (variant === "warning") return 8e3;
|
|
4659
|
+
if (hasAction) return 8e3;
|
|
4660
|
+
return void 0;
|
|
4661
|
+
}
|
|
4641
4662
|
function notify(options) {
|
|
4642
4663
|
const { duration, ...toastProps } = options;
|
|
4643
|
-
|
|
4664
|
+
const resolved = duration ?? defaultDuration(toastProps.variant, Boolean(toastProps.action || toastProps.secondaryAction));
|
|
4665
|
+
return toast.custom((id) => /* @__PURE__ */ jsx(NotificationToast, { ...toastProps, onDismiss: () => toast.dismiss(id) }), {
|
|
4666
|
+
duration: resolved
|
|
4667
|
+
});
|
|
4644
4668
|
}
|
|
4645
4669
|
function NotificationsPopover({
|
|
4646
4670
|
notifications,
|