@siyahi/ui 0.0.0-stage → 0.1.0-next.3
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/LICENSE +21 -0
- package/README.md +174 -2
- package/THIRD_PARTY_NOTICES.md +51 -0
- package/dist/components/registry/dashboard-01/section-cards.d.ts +17 -0
- package/dist/components/registry/dashboard-01/section-cards.js +39 -0
- package/dist/components/registry/dashboardcn/bar-list.d.ts +24 -0
- package/dist/components/registry/dashboardcn/bar-list.js +71 -0
- package/dist/components/registry/heatmap/calendar-heatmap.d.ts +134 -0
- package/dist/components/registry/heatmap/calendar-heatmap.js +497 -0
- package/dist/components/registry/heatmap/status-heatmap.d.ts +120 -0
- package/dist/components/registry/heatmap/status-heatmap.js +330 -0
- package/dist/components/registry/heatmap/weekday-heatmap.d.ts +145 -0
- package/dist/components/registry/heatmap/weekday-heatmap.js +489 -0
- package/dist/components/registry/niko-table/components/data-table-column-actions.d.ts +26 -0
- package/dist/components/registry/niko-table/components/data-table-column-actions.js +32 -0
- package/dist/components/registry/niko-table/components/data-table-column-filter.d.ts +13 -0
- package/dist/components/registry/niko-table/components/data-table-column-filter.js +17 -0
- package/dist/components/registry/niko-table/components/data-table-column-header.d.ts +30 -0
- package/dist/components/registry/niko-table/components/data-table-column-header.js +35 -0
- package/dist/components/registry/niko-table/components/data-table-column-sort.d.ts +21 -0
- package/dist/components/registry/niko-table/components/data-table-column-sort.js +36 -0
- package/dist/components/registry/niko-table/components/data-table-column-title.d.ts +12 -0
- package/dist/components/registry/niko-table/components/data-table-column-title.js +18 -0
- package/dist/components/registry/niko-table/components/data-table-empty-state.d.ts +108 -0
- package/dist/components/registry/niko-table/components/data-table-empty-state.js +148 -0
- package/dist/components/registry/niko-table/components/data-table-faceted-filter.d.ts +46 -0
- package/dist/components/registry/niko-table/components/data-table-faceted-filter.js +133 -0
- package/dist/components/registry/niko-table/components/data-table-grouped-rows.d.ts +111 -0
- package/dist/components/registry/niko-table/components/data-table-grouped-rows.js +77 -0
- package/dist/components/registry/niko-table/components/data-table-row-context-menu-slot.d.ts +65 -0
- package/dist/components/registry/niko-table/components/data-table-row-context-menu-slot.js +65 -0
- package/dist/components/registry/niko-table/components/data-table-row-context-menu.d.ts +50 -0
- package/dist/components/registry/niko-table/components/data-table-row-context-menu.js +42 -0
- package/dist/components/registry/niko-table/components/data-table-row-menu.d.ts +51 -0
- package/dist/components/registry/niko-table/components/data-table-row-menu.js +65 -0
- package/dist/components/registry/niko-table/components/data-table-toolbar-section.d.ts +7 -0
- package/dist/components/registry/niko-table/components/data-table-toolbar-section.js +63 -0
- package/dist/components/registry/niko-table/config/data-table.d.ts +156 -0
- package/dist/components/registry/niko-table/config/data-table.js +279 -0
- package/dist/components/registry/niko-table/config/feature-detection.d.ts +39 -0
- package/dist/components/registry/niko-table/config/feature-detection.js +174 -0
- package/dist/components/registry/niko-table/core/data-table-context.d.ts +157 -0
- package/dist/components/registry/niko-table/core/data-table-context.js +326 -0
- package/dist/components/registry/niko-table/core/data-table-error-boundary.d.ts +85 -0
- package/dist/components/registry/niko-table/core/data-table-error-boundary.js +116 -0
- package/dist/components/registry/niko-table/core/data-table-grouped-row.d.ts +49 -0
- package/dist/components/registry/niko-table/core/data-table-grouped-row.js +112 -0
- package/dist/components/registry/niko-table/core/data-table-root.d.ts +62 -0
- package/dist/components/registry/niko-table/core/data-table-root.js +406 -0
- package/dist/components/registry/niko-table/core/data-table-structure.d.ts +153 -0
- package/dist/components/registry/niko-table/core/data-table-structure.js +370 -0
- package/dist/components/registry/niko-table/core/data-table.d.ts +30 -0
- package/dist/components/registry/niko-table/core/data-table.js +126 -0
- package/dist/components/registry/niko-table/filters/table-column-actions.d.ts +49 -0
- package/dist/components/registry/niko-table/filters/table-column-actions.js +48 -0
- package/dist/components/registry/niko-table/filters/table-column-sort.d.ts +51 -0
- package/dist/components/registry/niko-table/filters/table-column-sort.js +184 -0
- package/dist/components/registry/niko-table/filters/table-column-title.d.ts +17 -0
- package/dist/components/registry/niko-table/filters/table-column-title.js +20 -0
- package/dist/components/registry/niko-table/filters/table-faceted-filter.d.ts +40 -0
- package/dist/components/registry/niko-table/filters/table-faceted-filter.js +210 -0
- package/dist/components/registry/niko-table/hooks/use-derived-column-title.d.ts +29 -0
- package/dist/components/registry/niko-table/hooks/use-derived-column-title.js +40 -0
- package/dist/components/registry/niko-table/hooks/use-generated-options.d.ts +49 -0
- package/dist/components/registry/niko-table/hooks/use-generated-options.js +144 -0
- package/dist/components/registry/niko-table/lib/build-faceted-options.d.ts +59 -0
- package/dist/components/registry/niko-table/lib/build-faceted-options.js +82 -0
- package/dist/components/registry/niko-table/lib/column-resize-handle.d.ts +33 -0
- package/dist/components/registry/niko-table/lib/column-resize-handle.js +175 -0
- package/dist/components/registry/niko-table/lib/constants.d.ts +128 -0
- package/dist/components/registry/niko-table/lib/constants.js +123 -0
- package/dist/components/registry/niko-table/lib/create-scroll-handler.d.ts +35 -0
- package/dist/components/registry/niko-table/lib/create-scroll-handler.js +63 -0
- package/dist/components/registry/niko-table/lib/data-table-features.d.ts +218 -0
- package/dist/components/registry/niko-table/lib/data-table-features.js +127 -0
- package/dist/components/registry/niko-table/lib/filter-functions.d.ts +47 -0
- package/dist/components/registry/niko-table/lib/filter-functions.js +309 -0
- package/dist/components/registry/niko-table/lib/filter-rows.d.ts +14 -0
- package/dist/components/registry/niko-table/lib/filter-rows.js +28 -0
- package/dist/components/registry/niko-table/lib/flex-columns.d.ts +48 -0
- package/dist/components/registry/niko-table/lib/flex-columns.js +65 -0
- package/dist/components/registry/niko-table/lib/format.d.ts +33 -0
- package/dist/components/registry/niko-table/lib/format.js +99 -0
- package/dist/components/registry/niko-table/lib/render-cell-content.d.ts +17 -0
- package/dist/components/registry/niko-table/lib/render-cell-content.js +65 -0
- package/dist/components/registry/niko-table/lib/row-click.d.ts +67 -0
- package/dist/components/registry/niko-table/lib/row-click.js +28 -0
- package/dist/components/registry/niko-table/lib/styles.d.ts +6 -0
- package/dist/components/registry/niko-table/lib/styles.js +24 -0
- package/dist/components/registry/niko-table/lib/use-header-min-widths.d.ts +17 -0
- package/dist/components/registry/niko-table/lib/use-header-min-widths.js +82 -0
- package/dist/components/registry/niko-table/types/index.d.ts +141 -0
- package/dist/components/registry/niko-table/types/index.js +2 -0
- package/dist/components/registry/niko-table/ui/table.d.ts +13 -0
- package/dist/components/registry/niko-table/ui/table.js +74 -0
- package/dist/components/registry/sidebar-07/app-sidebar.d.ts +18 -0
- package/dist/components/registry/sidebar-07/app-sidebar.js +26 -0
- package/dist/components/registry/sidebar-07/nav-main.d.ts +15 -0
- package/dist/components/registry/sidebar-07/nav-main.js +25 -0
- package/dist/components/registry/sidebar-07/nav-projects.d.ts +9 -0
- package/dist/components/registry/sidebar-07/nav-projects.js +43 -0
- package/dist/components/registry/sidebar-07/nav-user.d.ts +9 -0
- package/dist/components/registry/sidebar-07/nav-user.js +70 -0
- package/dist/components/registry/sidebar-07/team-switcher.d.ts +10 -0
- package/dist/components/registry/sidebar-07/team-switcher.js +70 -0
- package/dist/components/siyahi/delta.d.ts +10 -0
- package/dist/components/siyahi/delta.js +27 -0
- package/dist/components/siyahi/local-time.d.ts +7 -0
- package/dist/components/siyahi/local-time.js +22 -0
- package/dist/components/siyahi/price-chart.d.ts +12 -0
- package/dist/components/siyahi/price-chart.js +80 -0
- package/dist/components/siyahi/siyahi-provider.d.ts +12 -0
- package/dist/components/siyahi/siyahi-provider.js +31 -0
- package/dist/components/siyahi/treemap.d.ts +14 -0
- package/dist/components/siyahi/treemap.js +58 -0
- package/dist/components/ui/alert.d.ts +12 -0
- package/dist/components/ui/alert.js +43 -0
- package/dist/components/ui/avatar.d.ts +13 -0
- package/dist/components/ui/avatar.js +50 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/badge.js +29 -0
- package/dist/components/ui/breadcrumb.d.ts +12 -0
- package/dist/components/ui/breadcrumb.js +72 -0
- package/dist/components/ui/button.d.ts +10 -0
- package/dist/components/ui/button.js +44 -0
- package/dist/components/ui/calendar.d.ts +12 -0
- package/dist/components/ui/calendar.js +107 -0
- package/dist/components/ui/card.d.ts +13 -0
- package/dist/components/ui/card.js +56 -0
- package/dist/components/ui/chart.d.ts +46 -0
- package/dist/components/ui/chart.js +149 -0
- package/dist/components/ui/collapsible.d.ts +7 -0
- package/dist/components/ui/collapsible.js +24 -0
- package/dist/components/ui/command.d.ts +21 -0
- package/dist/components/ui/command.js +88 -0
- package/dist/components/ui/context-menu.d.ts +31 -0
- package/dist/components/ui/context-menu.js +132 -0
- package/dist/components/ui/dialog.d.ts +19 -0
- package/dist/components/ui/dialog.js +91 -0
- package/dist/components/ui/dropdown-menu.d.ts +31 -0
- package/dist/components/ui/dropdown-menu.js +136 -0
- package/dist/components/ui/input-group.d.ts +20 -0
- package/dist/components/ui/input-group.js +79 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +15 -0
- package/dist/components/ui/popover.d.ts +11 -0
- package/dist/components/ui/popover.js +55 -0
- package/dist/components/ui/progress.d.ts +9 -0
- package/dist/components/ui/progress.js +43 -0
- package/dist/components/ui/scroll-area.d.ts +7 -0
- package/dist/components/ui/scroll-area.js +36 -0
- package/dist/components/ui/select.d.ts +17 -0
- package/dist/components/ui/select.js +97 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.js +15 -0
- package/dist/components/ui/sheet.d.ts +16 -0
- package/dist/components/ui/sheet.js +89 -0
- package/dist/components/ui/sidebar.d.ts +65 -0
- package/dist/components/ui/sidebar.js +385 -0
- package/dist/components/ui/skeleton.d.ts +4 -0
- package/dist/components/ui/skeleton.js +12 -0
- package/dist/components/ui/slider.d.ts +5 -0
- package/dist/components/ui/slider.js +33 -0
- package/dist/components/ui/table.d.ts +12 -0
- package/dist/components/ui/table.js +66 -0
- package/dist/components/ui/tabs.d.ts +12 -0
- package/dist/components/ui/tabs.js +45 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/textarea.js +13 -0
- package/dist/components/ui/toggle-group.d.ts +13 -0
- package/dist/components/ui/toggle-group.js +52 -0
- package/dist/components/ui/toggle.d.ts +10 -0
- package/dist/components/ui/toggle.js +36 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.js +41 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +18 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +71 -0
- package/dist/lib/format.d.ts +24 -0
- package/dist/lib/format.js +58 -0
- package/dist/lib/locale.d.ts +12 -0
- package/dist/lib/locale.js +8 -0
- package/dist/lib/recharts.d.ts +2 -0
- package/dist/lib/recharts.js +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +1 -0
- package/package.json +78 -3
- package/registry.lock.json +413 -0
- package/report.css +129 -0
- package/styles/shadcn.css +643 -0
- package/styles/siyahi.css +189 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Button } from "../../../ui/button.js";
|
|
2
|
+
import { cn } from "../../../../lib/utils.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
5
|
+
import { flexRender } from "@tanstack/react-table";
|
|
6
|
+
//#region src/components/registry/niko-table/lib/render-cell-content.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Renders a body cell with TanStack grouping / aggregation awareness.
|
|
9
|
+
*
|
|
10
|
+
* - Grouped column cell: expand/collapse control + value + leaf count
|
|
11
|
+
* - Aggregated cell: `aggregatedCell` (falls back to `cell`)
|
|
12
|
+
* - Placeholder cell: empty (grouped columns leave gaps on leaf rows)
|
|
13
|
+
* - Otherwise: normal `cell` render
|
|
14
|
+
*
|
|
15
|
+
* Used by every body structure so grouping works the same for regular,
|
|
16
|
+
* virtualized, and DnD tables.
|
|
17
|
+
*/
|
|
18
|
+
function renderCellContent(cell) {
|
|
19
|
+
const context = cell.getContext();
|
|
20
|
+
if ((context.table.atoms.grouping?.get() ?? []).length === 0) return flexRender(cell.column.columnDef.cell, context);
|
|
21
|
+
if (cell.getIsPlaceholder()) return null;
|
|
22
|
+
if (cell.getIsAggregated()) return flexRender(cell.column.columnDef.aggregatedCell ?? cell.column.columnDef.cell, context);
|
|
23
|
+
if (cell.getIsGrouped()) {
|
|
24
|
+
const row = cell.row;
|
|
25
|
+
const canExpand = row.getCanExpand();
|
|
26
|
+
const isExpanded = row.getIsExpanded();
|
|
27
|
+
const leafCount = row.subRows.length;
|
|
28
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
29
|
+
className: "flex min-w-0 items-center gap-1",
|
|
30
|
+
children: [
|
|
31
|
+
canExpand ? /* @__PURE__ */ jsx(Button, {
|
|
32
|
+
type: "button",
|
|
33
|
+
variant: "ghost",
|
|
34
|
+
size: "icon",
|
|
35
|
+
className: cn("size-7 shrink-0", "dark:text-muted-foreground"),
|
|
36
|
+
"aria-expanded": isExpanded,
|
|
37
|
+
"aria-label": isExpanded ? "Collapse group" : "Expand group",
|
|
38
|
+
onClick: row.getToggleExpandedHandler(),
|
|
39
|
+
children: isExpanded ? /* @__PURE__ */ jsx(ChevronDown, {
|
|
40
|
+
className: "size-4",
|
|
41
|
+
"aria-hidden": true
|
|
42
|
+
}) : /* @__PURE__ */ jsx(ChevronRight, {
|
|
43
|
+
className: "size-4",
|
|
44
|
+
"aria-hidden": true
|
|
45
|
+
})
|
|
46
|
+
}) : null,
|
|
47
|
+
/* @__PURE__ */ jsx("span", {
|
|
48
|
+
className: "truncate",
|
|
49
|
+
children: flexRender(cell.column.columnDef.cell, context)
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ jsxs("span", {
|
|
52
|
+
className: "shrink-0 text-muted-foreground tabular-nums",
|
|
53
|
+
children: [
|
|
54
|
+
"(",
|
|
55
|
+
leafCount,
|
|
56
|
+
")"
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return flexRender(cell.column.columnDef.cell, context);
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { renderCellContent };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DataTableInstance } from "../types/index.js";
|
|
2
|
+
import { RowData } from "@tanstack/react-table";
|
|
3
|
+
//#region src/components/registry/niko-table/lib/row-click.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns `true` when the click landed on (or inside) an interactive
|
|
6
|
+
* element that should suppress `onRowClick`.
|
|
7
|
+
*
|
|
8
|
+
* Also suppresses when the user has an active text selection — accidental
|
|
9
|
+
* row clicks while drag-selecting cell text are a common annoyance,
|
|
10
|
+
* especially on rows that navigate to a detail view on click.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isInteractiveClickTarget(target: HTMLElement): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* For delegated `<tbody>` handlers. Returns the matched row, or `null`
|
|
15
|
+
* if the click should be ignored (interactive target or no row found).
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveRowFromClick<TData extends RowData>(target: HTMLElement, table: DataTableInstance<TData>): import("@tanstack/react-table").Row<{
|
|
18
|
+
columnOrderingFeature: import("@tanstack/react-table").TableFeature;
|
|
19
|
+
columnPinningFeature: import("@tanstack/react-table").TableFeature;
|
|
20
|
+
columnResizingFeature: import("@tanstack/react-table").TableFeature;
|
|
21
|
+
columnSizingFeature: import("@tanstack/react-table").TableFeature;
|
|
22
|
+
columnVisibilityFeature: import("@tanstack/react-table").TableFeature;
|
|
23
|
+
columnFacetingFeature: import("@tanstack/react-table").TableFeature;
|
|
24
|
+
columnFilteringFeature: import("@tanstack/react-table").TableFeature;
|
|
25
|
+
globalFilteringFeature: import("@tanstack/react-table").TableFeature;
|
|
26
|
+
facetedRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>, columnId: string) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, any>;
|
|
27
|
+
facetedUniqueValues: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>, columnId: string) => () => Map<any, number>;
|
|
28
|
+
facetedMinMaxValues: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>, columnId: string) => () => undefined | [number, number];
|
|
29
|
+
filteredRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, any>;
|
|
30
|
+
filterFns: {
|
|
31
|
+
readonly extended: import("@tanstack/react-table").FilterFn<import("@tanstack/react-table").TableFeatures, RowData>;
|
|
32
|
+
readonly numberRange: import("@tanstack/react-table").FilterFn<import("@tanstack/react-table").TableFeatures, RowData>;
|
|
33
|
+
readonly dateRange: import("@tanstack/react-table").FilterFn<import("@tanstack/react-table").TableFeatures, RowData>;
|
|
34
|
+
};
|
|
35
|
+
rowSortingFeature: import("@tanstack/react-table").TableFeature;
|
|
36
|
+
sortedRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, RowData>) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, RowData>;
|
|
37
|
+
sortFns: {
|
|
38
|
+
readonly alphanumeric: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
39
|
+
readonly alphanumericCaseSensitive: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
40
|
+
readonly basic: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
41
|
+
readonly datetime: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
42
|
+
readonly text: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
43
|
+
readonly textCaseSensitive: import("@tanstack/react-table").CreatedSortFn<any, any>;
|
|
44
|
+
};
|
|
45
|
+
rowExpandingFeature: import("@tanstack/react-table").TableFeature;
|
|
46
|
+
expandedRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, any>;
|
|
47
|
+
columnGroupingFeature: import("@tanstack/react-table").TableFeature;
|
|
48
|
+
rowAggregationFeature: import("@tanstack/react-table").TableFeature;
|
|
49
|
+
groupedRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, any>;
|
|
50
|
+
aggregationFns: {
|
|
51
|
+
readonly count: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, number>;
|
|
52
|
+
readonly extent: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, [(number | Date) | undefined, (number | Date) | undefined]>;
|
|
53
|
+
readonly first: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, unknown>;
|
|
54
|
+
readonly last: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, unknown>;
|
|
55
|
+
readonly max: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
|
|
56
|
+
readonly mean: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, number | undefined>;
|
|
57
|
+
readonly median: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, number | undefined>;
|
|
58
|
+
readonly min: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, (number | Date) | undefined>;
|
|
59
|
+
readonly sum: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, number>;
|
|
60
|
+
readonly unique: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, unknown[]>;
|
|
61
|
+
readonly uniqueCount: import("@tanstack/react-table").AggregationFnDef<any, any, unknown, number>;
|
|
62
|
+
};
|
|
63
|
+
rowPaginationFeature: import("@tanstack/react-table").TableFeature;
|
|
64
|
+
paginatedRowModel: (table: import("@tanstack/react-table").Table<import("@tanstack/react-table").TableFeatures, any>) => () => import("@tanstack/react-table").RowModel<import("@tanstack/react-table").TableFeatures, any>;
|
|
65
|
+
rowSelectionFeature: import("@tanstack/react-table").TableFeature;
|
|
66
|
+
}, TData> | null;
|
|
67
|
+
//#endregion
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/components/registry/niko-table/lib/row-click.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns `true` when the click landed on (or inside) an interactive
|
|
4
|
+
* element that should suppress `onRowClick`.
|
|
5
|
+
*
|
|
6
|
+
* Also suppresses when the user has an active text selection — accidental
|
|
7
|
+
* row clicks while drag-selecting cell text are a common annoyance,
|
|
8
|
+
* especially on rows that navigate to a detail view on click.
|
|
9
|
+
*/
|
|
10
|
+
function isInteractiveClickTarget(target) {
|
|
11
|
+
const selection = typeof window !== "undefined" ? window.getSelection?.() : null;
|
|
12
|
+
if (selection && !selection.isCollapsed && selection.toString().length > 0) return true;
|
|
13
|
+
return Boolean(target.closest("button") || target.closest("input") || target.closest("textarea") || target.closest("select") || target.closest("a") || target.closest("label") || target.closest("[contenteditable]") || target.closest("[role=\"button\"]") || target.closest("[role=\"checkbox\"]") || target.closest("[role=\"combobox\"]") || target.closest("[role=\"menuitem\"]") || target.closest("[role=\"textbox\"]") || target.closest("[data-radix-collection-item]") || target.closest("[data-slot=\"checkbox\"]") || target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT" || target.tagName === "BUTTON" || target.tagName === "A");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* For delegated `<tbody>` handlers. Returns the matched row, or `null`
|
|
17
|
+
* if the click should be ignored (interactive target or no row found).
|
|
18
|
+
*/
|
|
19
|
+
function resolveRowFromClick(target, table) {
|
|
20
|
+
if (isInteractiveClickTarget(target)) return null;
|
|
21
|
+
const rowEl = target.closest("tr[data-row-id]");
|
|
22
|
+
if (!rowEl) return null;
|
|
23
|
+
const rowId = rowEl.getAttribute("data-row-id");
|
|
24
|
+
if (rowId === null) return null;
|
|
25
|
+
return table.getRow(rowId) ?? null;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { isInteractiveClickTarget, resolveRowFromClick };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DataTableFeatures } from "./data-table-features.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Column, RowData } from "@tanstack/react-table";
|
|
4
|
+
//#region src/components/registry/niko-table/lib/styles.d.ts
|
|
5
|
+
export declare const getCommonPinningStyles: <TData extends RowData>(column: Column<DataTableFeatures, TData>, isHeader?: boolean) => React.CSSProperties;
|
|
6
|
+
//#endregion
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "@tanstack/react-table";
|
|
2
|
+
//#region src/components/registry/niko-table/lib/styles.ts
|
|
3
|
+
const getCommonPinningStyles = (column, isHeader = false) => {
|
|
4
|
+
const isPinned = column.getIsPinned();
|
|
5
|
+
if (!isPinned) return {};
|
|
6
|
+
const isLeft = isPinned === "start";
|
|
7
|
+
const columnSize = column.getSize();
|
|
8
|
+
return {
|
|
9
|
+
position: "sticky",
|
|
10
|
+
top: isHeader ? 0 : void 0,
|
|
11
|
+
left: isLeft ? `${column.getStart("start")}px` : void 0,
|
|
12
|
+
right: !isLeft ? `${column.getAfter("end")}px` : void 0,
|
|
13
|
+
opacity: 1,
|
|
14
|
+
width: columnSize,
|
|
15
|
+
minWidth: columnSize,
|
|
16
|
+
maxWidth: columnSize,
|
|
17
|
+
flexShrink: 0,
|
|
18
|
+
zIndex: isHeader ? 20 : 10,
|
|
19
|
+
backgroundColor: "var(--background)",
|
|
20
|
+
...isLeft ? { boxShadow: "inset -2px 0 0 0 color-mix(in oklab, var(--foreground) 40%, transparent), 4px 0 8px -2px color-mix(in oklab, var(--foreground) 14%, transparent)" } : { boxShadow: "inset 2px 0 0 0 color-mix(in oklab, var(--foreground) 40%, transparent), -4px 0 8px -2px color-mix(in oklab, var(--foreground) 14%, transparent)" }
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { getCommonPinningStyles };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DataTableInstance } from "../types/index.js";
|
|
2
|
+
import { RowData } from "@tanstack/react-table";
|
|
3
|
+
//#region src/components/registry/niko-table/lib/use-header-min-widths.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Measure the natural width each column's header needs so a column is never
|
|
6
|
+
* rendered so narrow that its label truncates on load (header-fit).
|
|
7
|
+
*
|
|
8
|
+
* Returns `columnId -> minimum width in px` (label width + header chrome). The
|
|
9
|
+
* caller floors each un-resized column at this width; a column the user has
|
|
10
|
+
* explicitly resized is left alone. Pure measurement — nothing is written to
|
|
11
|
+
* `columnSizing`, so it never persists or goes stale.
|
|
12
|
+
*
|
|
13
|
+
* Recomputes only when the visible columns, their labels, or the header font
|
|
14
|
+
* change — measurement itself is O(columns) with zero reflow.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useHeaderMinWidths<TData extends RowData>(table: DataTableInstance<TData>, scrollElement: HTMLElement | null, enabled: boolean): ReadonlyMap<string, number>;
|
|
17
|
+
//#endregion
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { formatLabel } from "./format.js";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
//#region src/components/registry/niko-table/lib/use-header-min-widths.ts
|
|
4
|
+
const BASE_HEADER_CHROME_PX = 28;
|
|
5
|
+
const SORT_AFFORDANCE_PX = 24;
|
|
6
|
+
const EMPTY_MIN_WIDTHS = /* @__PURE__ */ new Map();
|
|
7
|
+
let measureCanvas = null;
|
|
8
|
+
function getMeasureContext() {
|
|
9
|
+
if (typeof document === "undefined") return null;
|
|
10
|
+
if (!measureCanvas) measureCanvas = document.createElement("canvas");
|
|
11
|
+
return measureCanvas.getContext("2d");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The label text a column renders in its header. Mirrors the composable
|
|
15
|
+
* title's precedence (`useDerivedColumnTitle`): `meta.label`, else a plain
|
|
16
|
+
* string `header`, else the formatted column id — the same fallback
|
|
17
|
+
* `DataTableColumnTitle` renders when nothing else is set. One gap this can't
|
|
18
|
+
* see: a JSX `<DataTableColumnTitle title="..." />` override lives in rendered
|
|
19
|
+
* output, not the column def — mirror such overrides into `meta.label` so
|
|
20
|
+
* header-fit measures the right string.
|
|
21
|
+
*/
|
|
22
|
+
function headerLabel(column) {
|
|
23
|
+
const columnDef = column.columnDef;
|
|
24
|
+
if (columnDef.meta?.label) return columnDef.meta.label;
|
|
25
|
+
if (typeof columnDef.header === "string") return columnDef.header;
|
|
26
|
+
return formatLabel(column.id);
|
|
27
|
+
}
|
|
28
|
+
/** Content equality so a re-measure with identical results keeps identity. */
|
|
29
|
+
function minWidthsEqual(a, b) {
|
|
30
|
+
if (a.size !== b.size) return false;
|
|
31
|
+
for (const [id, width] of b) if (a.get(id) !== width) return false;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Measure the natural width each column's header needs so a column is never
|
|
36
|
+
* rendered so narrow that its label truncates on load (header-fit).
|
|
37
|
+
*
|
|
38
|
+
* Returns `columnId -> minimum width in px` (label width + header chrome). The
|
|
39
|
+
* caller floors each un-resized column at this width; a column the user has
|
|
40
|
+
* explicitly resized is left alone. Pure measurement — nothing is written to
|
|
41
|
+
* `columnSizing`, so it never persists or goes stale.
|
|
42
|
+
*
|
|
43
|
+
* Recomputes only when the visible columns, their labels, or the header font
|
|
44
|
+
* change — measurement itself is O(columns) with zero reflow.
|
|
45
|
+
*/
|
|
46
|
+
function useHeaderMinWidths(table, scrollElement, enabled) {
|
|
47
|
+
const [minWidths, setMinWidths] = React$1.useState(EMPTY_MIN_WIDTHS);
|
|
48
|
+
const leafColumns = table.getVisibleLeafColumns();
|
|
49
|
+
const signature = leafColumns.map((c) => `${c.id}:${headerLabel(c) ?? ""}:${c.getCanSort() ? 1 : 0}`).join("|");
|
|
50
|
+
React$1.useLayoutEffect(() => {
|
|
51
|
+
const store = (next) => setMinWidths((prev) => minWidthsEqual(prev, next) ? prev : next);
|
|
52
|
+
if (!enabled || !scrollElement) {
|
|
53
|
+
store(EMPTY_MIN_WIDTHS);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const ctx = getMeasureContext();
|
|
57
|
+
const fontEl = scrollElement.querySelector("thead [data-slot=\"column-title\"]") ?? scrollElement.querySelector("thead th[data-col-id]");
|
|
58
|
+
if (!ctx || !fontEl) {
|
|
59
|
+
store(EMPTY_MIN_WIDTHS);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const cs = getComputedStyle(fontEl);
|
|
63
|
+
ctx.font = `${cs.fontStyle} ${cs.fontWeight} ${cs.fontSize} ${cs.fontFamily}`;
|
|
64
|
+
const next = /* @__PURE__ */ new Map();
|
|
65
|
+
for (const column of leafColumns) {
|
|
66
|
+
if (!column.getCanResize()) continue;
|
|
67
|
+
const label = headerLabel(column);
|
|
68
|
+
if (!label) continue;
|
|
69
|
+
const textWidth = ctx.measureText(label).width;
|
|
70
|
+
const chrome = BASE_HEADER_CHROME_PX + (column.getCanSort() ? SORT_AFFORDANCE_PX : 0);
|
|
71
|
+
next.set(column.id, Math.ceil(textWidth) + chrome);
|
|
72
|
+
}
|
|
73
|
+
store(next);
|
|
74
|
+
}, [
|
|
75
|
+
enabled,
|
|
76
|
+
scrollElement,
|
|
77
|
+
signature
|
|
78
|
+
]);
|
|
79
|
+
return minWidths;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { useHeaderMinWidths };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { FILTER_OPERATORS, FILTER_VARIANTS, FilterOperator as FilterOperator$1, FilterVariant as FilterVariant$1, JOIN_OPERATORS, JoinOperator as JoinOperator$1 } from "../lib/constants.js";
|
|
2
|
+
import { DataTableFeatures } from "../lib/data-table-features.js";
|
|
3
|
+
import * as React$1 from "react";
|
|
4
|
+
import { Cell, Column, ColumnDef, Header, ReactTable, Row, RowData, TableFeatures } from "@tanstack/react-table";
|
|
5
|
+
//#region src/components/registry/niko-table/types/index.d.ts
|
|
6
|
+
declare module "@tanstack/react-table" {
|
|
7
|
+
interface ColumnMeta<TFeatures extends TableFeatures, TData extends RowData, TValue> {
|
|
8
|
+
label?: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Which column absorbs the leftover row width when column resizing is on
|
|
12
|
+
* (needs `<DataTableColumnResize />`). Filling is ON BY DEFAULT — the first
|
|
13
|
+
* non-pinned data column flexes automatically — so you rarely set this.
|
|
14
|
+
*
|
|
15
|
+
* - `true` overrides the default to flex THIS column instead (use when the
|
|
16
|
+
* first column isn't the one that should grow).
|
|
17
|
+
* - `false` opts this column out of being auto-picked.
|
|
18
|
+
*
|
|
19
|
+
* The flex column renders with no width and absorbs the surplus, so every
|
|
20
|
+
* other column keeps its `size` and a trailing actions/menu column pins to
|
|
21
|
+
* the right edge. Pure layout — never touches `columnSizing`, so no
|
|
22
|
+
* persistence side effects. Turn filling off for a whole table with
|
|
23
|
+
* `TableMeta.disableFlexFill`.
|
|
24
|
+
*/
|
|
25
|
+
flex?: boolean;
|
|
26
|
+
variant?: FilterVariant;
|
|
27
|
+
options?: Option[];
|
|
28
|
+
range?: [number, number];
|
|
29
|
+
/**
|
|
30
|
+
* Automatically generate options for select/multiSelect columns if not provided.
|
|
31
|
+
* When true and no static `options` exist, generation logic (wrappers / hooks) may supply them.
|
|
32
|
+
*/
|
|
33
|
+
autoOptions?: boolean;
|
|
34
|
+
/** Whether to automatically rename option labels using formatLabel. When false, uses raw value as label. */
|
|
35
|
+
autoOptionsFormat?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Per-column label formatter applied when options are auto-derived from
|
|
38
|
+
* row data. Receives the stringified row value and returns the display
|
|
39
|
+
* label. Wins over `autoOptionsFormat` when present. Ignored when the
|
|
40
|
+
* caller passes explicit `options`.
|
|
41
|
+
*/
|
|
42
|
+
formatOptionLabel?: (value: string) => string;
|
|
43
|
+
/** Per-column override for showing counts (falls back to wrapper prop). */
|
|
44
|
+
showCounts?: boolean;
|
|
45
|
+
/** Per-column override for using filtered rows for counts (falls back to wrapper prop). */
|
|
46
|
+
dynamicCounts?: boolean;
|
|
47
|
+
/** Merge strategy override: preserve | augment | replace (falls back to wrapper prop). */
|
|
48
|
+
mergeStrategy?: "preserve" | "augment" | "replace";
|
|
49
|
+
unit?: string;
|
|
50
|
+
icon?: React$1.ComponentType<{
|
|
51
|
+
className?: string;
|
|
52
|
+
}>;
|
|
53
|
+
expandedContent?: (row: TData) => React$1.ReactNode;
|
|
54
|
+
}
|
|
55
|
+
interface TableMeta<TFeatures extends TableFeatures, TData extends RowData> {
|
|
56
|
+
joinOperator?: JoinOperator;
|
|
57
|
+
hasIndividualJoinOperators?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Turn off default flex fill for the whole table, so columns size to their
|
|
60
|
+
* own widths and the table scrolls horizontally instead of stretching to
|
|
61
|
+
* fill. Use for wide, many-column tables meant to scroll.
|
|
62
|
+
*
|
|
63
|
+
* Set it statically via `<DataTableRoot meta={{ disableFlexFill: true }}>`
|
|
64
|
+
* — it's read when table options are built, so toggling it at runtime
|
|
65
|
+
* alone won't re-apply until another table state change rebuilds them.
|
|
66
|
+
*/
|
|
67
|
+
disableFlexFill?: boolean;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export interface Option {
|
|
71
|
+
label: string;
|
|
72
|
+
value: string;
|
|
73
|
+
count?: number;
|
|
74
|
+
icon?: React$1.ComponentType<{
|
|
75
|
+
className?: string;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
78
|
+
export type FilterVariant = FilterVariant$1;
|
|
79
|
+
export type FilterOperator = FilterOperator$1;
|
|
80
|
+
export type JoinOperator = JoinOperator$1;
|
|
81
|
+
/**
|
|
82
|
+
* Extended column filter with additional metadata
|
|
83
|
+
*/
|
|
84
|
+
export interface ExtendedColumnFilter<TData> {
|
|
85
|
+
id: Extract<keyof TData, string>;
|
|
86
|
+
value: string | string[];
|
|
87
|
+
variant: FilterVariant;
|
|
88
|
+
operator: FilterOperator;
|
|
89
|
+
filterId: string;
|
|
90
|
+
joinOperator?: JoinOperator;
|
|
91
|
+
}
|
|
92
|
+
/** Global filter type */
|
|
93
|
+
export type GlobalFilter = string | Record<string, unknown>;
|
|
94
|
+
/**
|
|
95
|
+
* Extended column sort (for URL state management)
|
|
96
|
+
*/
|
|
97
|
+
export interface ExtendedColumnSort<TData> {
|
|
98
|
+
id: Extract<keyof TData, string>;
|
|
99
|
+
desc: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Query keys for URL state management
|
|
103
|
+
*/
|
|
104
|
+
export interface QueryKeys {
|
|
105
|
+
page?: string;
|
|
106
|
+
perPage?: string;
|
|
107
|
+
sort?: string;
|
|
108
|
+
filters?: string;
|
|
109
|
+
joinOperator?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Extended column definition for data table
|
|
113
|
+
* Inherits all TanStack Table ColumnDef properties
|
|
114
|
+
*/
|
|
115
|
+
export type DataTableColumnDef<TData extends RowData, TValue = unknown> = ColumnDef<DataTableFeatures, TData, TValue> & {};
|
|
116
|
+
/**
|
|
117
|
+
* Mixed column arrays (plain objects and `createDataTableColumnHelper` results).
|
|
118
|
+
* Per-column `TValue` varies, so the array uses `any` the same way TanStack's
|
|
119
|
+
* `columns` option does.
|
|
120
|
+
*/
|
|
121
|
+
export type DataTableColumns<TData extends RowData> = DataTableColumnDef<TData, any>[];
|
|
122
|
+
/**
|
|
123
|
+
* Data table row type
|
|
124
|
+
* Alias for TanStack Table Row
|
|
125
|
+
*/
|
|
126
|
+
export type DataTableRow<TData extends RowData> = Row<DataTableFeatures, TData> & {};
|
|
127
|
+
export type DataTableColumn<TData extends RowData, TValue = unknown> = Column<DataTableFeatures, TData, TValue>;
|
|
128
|
+
export type DataTableHeader<TData extends RowData, TValue = unknown> = Header<DataTableFeatures, TData, TValue>;
|
|
129
|
+
export type DataTableCell<TData extends RowData, TValue = unknown> = Cell<DataTableFeatures, TData, TValue>;
|
|
130
|
+
export type DataTableInstance<TData extends RowData> = ReactTable<DataTableFeatures, TData> & {};
|
|
131
|
+
/**
|
|
132
|
+
* Convenience type for accessing constant values with better type safety
|
|
133
|
+
*/
|
|
134
|
+
export type JoinOperatorValues = typeof JOIN_OPERATORS;
|
|
135
|
+
export type FilterOperatorValues = typeof FILTER_OPERATORS;
|
|
136
|
+
export type FilterVariantValues = typeof FILTER_VARIANTS;
|
|
137
|
+
/**
|
|
138
|
+
* Utility type to get the literal values from constant objects
|
|
139
|
+
*/
|
|
140
|
+
export type ValueOf<T> = T[keyof T];
|
|
141
|
+
//#endregion
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
//#region src/components/registry/niko-table/ui/table.d.ts
|
|
3
|
+
declare function TableComponent({ className, ...props }: React$1.ComponentProps<"table">): React$1.JSX.Element;
|
|
4
|
+
declare function Table({ className, ...props }: React$1.ComponentProps<"table">): React$1.JSX.Element;
|
|
5
|
+
declare function TableHeader({ className, ...props }: React$1.ComponentProps<"thead">): React$1.JSX.Element;
|
|
6
|
+
declare function TableBody({ className, ...props }: React$1.ComponentProps<"tbody">): React$1.JSX.Element;
|
|
7
|
+
declare function TableFooter({ className, ...props }: React$1.ComponentProps<"tfoot">): React$1.JSX.Element;
|
|
8
|
+
declare function TableRow({ className, ...props }: React$1.ComponentProps<"tr">): React$1.JSX.Element;
|
|
9
|
+
declare function TableHead({ className, ...props }: React$1.ComponentProps<"th">): React$1.JSX.Element;
|
|
10
|
+
declare function TableCell({ className, ...props }: React$1.ComponentProps<"td">): React$1.JSX.Element;
|
|
11
|
+
declare function TableCaption({ className, ...props }: React$1.ComponentProps<"caption">): React$1.JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Table, TableBody, TableCaption, TableCell, TableComponent, TableFooter, TableHead, TableHeader, TableRow };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/registry/niko-table/ui/table.tsx
|
|
6
|
+
function TableComponent({ className, ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx("table", {
|
|
8
|
+
"data-slot": "table",
|
|
9
|
+
className: cn("w-full caption-bottom text-sm", className),
|
|
10
|
+
...props
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function Table({ className, ...props }) {
|
|
14
|
+
return /* @__PURE__ */ jsx("div", {
|
|
15
|
+
"data-slot": "table-container",
|
|
16
|
+
tabIndex: 0,
|
|
17
|
+
className: "relative w-full overflow-x-auto",
|
|
18
|
+
children: /* @__PURE__ */ jsx(TableComponent, {
|
|
19
|
+
className,
|
|
20
|
+
...props
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function TableHeader({ className, ...props }) {
|
|
25
|
+
return /* @__PURE__ */ jsx("thead", {
|
|
26
|
+
"data-slot": "table-header",
|
|
27
|
+
className: cn("[&_tr]:border-b", className),
|
|
28
|
+
...props
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function TableBody({ className, ...props }) {
|
|
32
|
+
return /* @__PURE__ */ jsx("tbody", {
|
|
33
|
+
"data-slot": "table-body",
|
|
34
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
35
|
+
...props
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function TableFooter({ className, ...props }) {
|
|
39
|
+
return /* @__PURE__ */ jsx("tfoot", {
|
|
40
|
+
"data-slot": "table-footer",
|
|
41
|
+
className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
|
|
42
|
+
...props
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function TableRow({ className, ...props }) {
|
|
46
|
+
return /* @__PURE__ */ jsx("tr", {
|
|
47
|
+
"data-slot": "table-row",
|
|
48
|
+
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
49
|
+
...props
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function TableHead({ className, ...props }) {
|
|
53
|
+
return /* @__PURE__ */ jsx("th", {
|
|
54
|
+
"data-slot": "table-head",
|
|
55
|
+
className: cn("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-[2px]", className),
|
|
56
|
+
...props
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function TableCell({ className, ...props }) {
|
|
60
|
+
return /* @__PURE__ */ jsx("td", {
|
|
61
|
+
"data-slot": "table-cell",
|
|
62
|
+
className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-[2px]", className),
|
|
63
|
+
...props
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function TableCaption({ className, ...props }) {
|
|
67
|
+
return /* @__PURE__ */ jsx("caption", {
|
|
68
|
+
"data-slot": "table-caption",
|
|
69
|
+
className: cn("mt-4 text-sm text-muted-foreground", className),
|
|
70
|
+
...props
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { Table, TableBody, TableCaption, TableCell, TableComponent, TableFooter, TableHead, TableHeader, TableRow };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NavMain } from "./nav-main.js";
|
|
2
|
+
import { NavProjects } from "./nav-projects.js";
|
|
3
|
+
import { NavUser } from "./nav-user.js";
|
|
4
|
+
import { TeamSwitcher } from "./team-switcher.js";
|
|
5
|
+
import { Sidebar } from "../../ui/sidebar.js";
|
|
6
|
+
import * as React$1 from "react";
|
|
7
|
+
//#region src/components/registry/sidebar-07/app-sidebar.d.ts
|
|
8
|
+
export interface AppSidebarProps extends React$1.ComponentProps<typeof Sidebar> {
|
|
9
|
+
navMain: React$1.ComponentProps<typeof NavMain>["items"];
|
|
10
|
+
navLabel?: string;
|
|
11
|
+
/** Shown at the top instead of the team switcher. */
|
|
12
|
+
header?: React$1.ReactNode;
|
|
13
|
+
teams?: React$1.ComponentProps<typeof TeamSwitcher>["teams"];
|
|
14
|
+
projects?: React$1.ComponentProps<typeof NavProjects>["projects"];
|
|
15
|
+
user?: React$1.ComponentProps<typeof NavUser>["user"];
|
|
16
|
+
}
|
|
17
|
+
export declare function AppSidebar({ navMain, navLabel, header, teams, projects, user, ...props }: AppSidebarProps): React$1.JSX.Element;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "../../ui/sidebar.js";
|
|
3
|
+
import { NavMain } from "./nav-main.js";
|
|
4
|
+
import { NavProjects } from "./nav-projects.js";
|
|
5
|
+
import { NavUser } from "./nav-user.js";
|
|
6
|
+
import { TeamSwitcher } from "./team-switcher.js";
|
|
7
|
+
import "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/registry/sidebar-07/app-sidebar.tsx
|
|
10
|
+
function AppSidebar({ navMain, navLabel, header, teams, projects, user, ...props }) {
|
|
11
|
+
return /* @__PURE__ */ jsxs(Sidebar, {
|
|
12
|
+
collapsible: "icon",
|
|
13
|
+
...props,
|
|
14
|
+
children: [
|
|
15
|
+
(header || teams) && /* @__PURE__ */ jsx(SidebarHeader, { children: header ?? (teams && /* @__PURE__ */ jsx(TeamSwitcher, { teams })) }),
|
|
16
|
+
/* @__PURE__ */ jsxs(SidebarContent, { children: [/* @__PURE__ */ jsx(NavMain, {
|
|
17
|
+
items: navMain,
|
|
18
|
+
label: navLabel
|
|
19
|
+
}), projects && /* @__PURE__ */ jsx(NavProjects, { projects })] }),
|
|
20
|
+
user && /* @__PURE__ */ jsx(SidebarFooter, { children: /* @__PURE__ */ jsx(NavUser, { user }) }),
|
|
21
|
+
/* @__PURE__ */ jsx(SidebarRail, {})
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { AppSidebar };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/components/registry/sidebar-07/nav-main.d.ts
|
|
2
|
+
export declare function NavMain({ items, label }: {
|
|
3
|
+
label?: string | undefined;
|
|
4
|
+
items: {
|
|
5
|
+
title: string;
|
|
6
|
+
url: string;
|
|
7
|
+
icon?: React.ReactNode;
|
|
8
|
+
isActive?: boolean;
|
|
9
|
+
items?: {
|
|
10
|
+
title: string;
|
|
11
|
+
url: string;
|
|
12
|
+
}[];
|
|
13
|
+
}[];
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
//#endregion
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../ui/collapsible.js";
|
|
2
|
+
import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem } from "../../ui/sidebar.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { ChevronRightIcon } from "lucide-react";
|
|
5
|
+
//#region src/components/registry/sidebar-07/nav-main.tsx
|
|
6
|
+
function NavMain({ items, label = "Navigation" }) {
|
|
7
|
+
return /* @__PURE__ */ jsxs(SidebarGroup, { children: [/* @__PURE__ */ jsx(SidebarGroupLabel, { children: label }), /* @__PURE__ */ jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsxs(Collapsible, {
|
|
8
|
+
defaultOpen: item.isActive,
|
|
9
|
+
className: "group/collapsible",
|
|
10
|
+
render: /* @__PURE__ */ jsx(SidebarMenuItem, {}),
|
|
11
|
+
children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
|
|
12
|
+
render: /* @__PURE__ */ jsx(SidebarMenuButton, { tooltip: item.title }),
|
|
13
|
+
children: [
|
|
14
|
+
item.icon,
|
|
15
|
+
/* @__PURE__ */ jsx("span", { children: item.title }),
|
|
16
|
+
/* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto transition-transform duration-200 group-data-open/collapsible:rotate-90" })
|
|
17
|
+
]
|
|
18
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsx(SidebarMenuSubButton, {
|
|
19
|
+
render: /* @__PURE__ */ jsx("a", { href: subItem.url }),
|
|
20
|
+
children: /* @__PURE__ */ jsx("span", { children: subItem.title })
|
|
21
|
+
}) }, subItem.title)) }) })]
|
|
22
|
+
}, item.title)) })] });
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { NavMain };
|