@siyahi/ui 0.1.1-next.4 → 0.1.2-next.1
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/registry/dashboardcn/bar-list.d.ts +2 -0
- package/dist/components/registry/dashboardcn/bar-list.js +30 -22
- package/dist/components/registry/niko-table/core/data-table-structure.js +2 -2
- package/dist/components/registry/niko-table/filters/table-column-actions.js +4 -4
- package/dist/components/registry/niko-table/filters/table-column-sort.js +3 -4
- package/dist/components/registry/niko-table/lib/styles.js +1 -1
- package/dist/components/siyahi/treemap.d.ts +16 -7
- package/dist/components/siyahi/treemap.js +34 -21
- package/dist/index.d.ts +2 -2
- package/dist/lib/treemap.d.ts +23 -0
- package/dist/lib/treemap.js +40 -0
- package/package.json +1 -1
|
@@ -6,6 +6,8 @@ export interface BarListItem {
|
|
|
6
6
|
/** Renders the label as a link. */
|
|
7
7
|
href?: string;
|
|
8
8
|
icon?: React$1.ReactNode;
|
|
9
|
+
/** Secondary figure after the label, such as a `Delta`. */
|
|
10
|
+
detail?: React$1.ReactNode;
|
|
9
11
|
/** Stable key when names can repeat. */
|
|
10
12
|
key?: string;
|
|
11
13
|
}
|
|
@@ -31,28 +31,36 @@ function BarList({ data, valueFormatter, sortOrder = "descending", color = "var(
|
|
|
31
31
|
className: "flex items-center gap-3 text-sm",
|
|
32
32
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
33
33
|
className: "relative flex h-8 min-w-0 flex-1 items-center",
|
|
34
|
-
children: [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
className: "
|
|
50
|
-
children: item.icon
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx("div", {
|
|
36
|
+
"aria-hidden": "true",
|
|
37
|
+
className: "absolute inset-y-0 left-0 rounded-md transition-[width] duration-300",
|
|
38
|
+
style: {
|
|
39
|
+
width: `${width}%`,
|
|
40
|
+
backgroundColor: `color-mix(in oklab, ${color} 20%, transparent)`
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ jsxs(Label, {
|
|
44
|
+
...item.href ? { href: item.href } : {},
|
|
45
|
+
...onItemClick && !item.href ? {
|
|
46
|
+
type: "button",
|
|
47
|
+
onClick: () => onItemClick(item)
|
|
48
|
+
} : {},
|
|
49
|
+
className: cn("relative flex min-w-0 items-center gap-2 px-2 text-left", interactive && "hover:underline"),
|
|
50
|
+
children: [item.icon ? /* @__PURE__ */ jsx("span", {
|
|
51
|
+
className: "text-muted-foreground shrink-0 [&>svg]:size-4",
|
|
52
|
+
children: item.icon
|
|
53
|
+
}) : null, /* @__PURE__ */ jsx("span", {
|
|
54
|
+
className: "truncate",
|
|
55
|
+
children: item.name
|
|
56
|
+
})]
|
|
57
|
+
}),
|
|
58
|
+
item.detail ? /* @__PURE__ */ jsx("span", {
|
|
59
|
+
"data-slot": "bar-list-detail",
|
|
60
|
+
className: "text-muted-foreground relative shrink-0 pr-2 text-xs tabular-nums",
|
|
61
|
+
children: item.detail
|
|
62
|
+
}) : null
|
|
63
|
+
]
|
|
56
64
|
}), /* @__PURE__ */ jsxs("div", {
|
|
57
65
|
className: "flex shrink-0 items-center gap-2 tabular-nums",
|
|
58
66
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -27,7 +27,7 @@ const DataTableHeader = React.memo(function DataTableHeader({ className, sticky
|
|
|
27
27
|
const flexColumnIds = resolveFlexColumnIds(table);
|
|
28
28
|
const columnSizing = table.state.columnSizing;
|
|
29
29
|
return /* @__PURE__ */ jsx(TableHeader, {
|
|
30
|
-
className: cn(sticky && "sticky top-0 z-30 bg-
|
|
30
|
+
className: cn(sticky && "sticky top-0 z-30 bg-card", sticky && "after:absolute after:right-0 after:bottom-0 after:left-0 after:h-px after:bg-border", className),
|
|
31
31
|
children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
|
|
32
32
|
const isFlex = flexColumnIds.has(header.column.id);
|
|
33
33
|
const headerStyle = {
|
|
@@ -83,7 +83,7 @@ const BodyRow = React.memo(function BodyRow({ row, displayIndex, expandColumnId,
|
|
|
83
83
|
"data-flash": flashing ? "true" : void 0,
|
|
84
84
|
"data-col-id": cell.column.id,
|
|
85
85
|
style: cellStyle,
|
|
86
|
-
className: cn(!cell.getIsGrouped() && "truncate", cell.column.getIsPinned() && "bg-
|
|
86
|
+
className: cn(!cell.getIsGrouped() && "truncate", cell.column.getIsPinned() && "bg-linear-to-r group-hover:from-muted/50 group-hover:to-muted/50 group-data-[context-menu-open]:from-muted/50 group-data-[context-menu-open]:to-muted/50 group-data-[state=selected]:from-muted group-data-[state=selected]:to-muted"),
|
|
87
87
|
children: renderCellContent(cell)
|
|
88
88
|
}, cell.id);
|
|
89
89
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button } from "../../../ui/button.js";
|
|
2
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuTrigger } from "../../../ui/dropdown-menu.js";
|
|
2
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuTrigger } from "../../../ui/dropdown-menu.js";
|
|
3
3
|
import { cn } from "../../../../lib/utils.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -34,13 +34,13 @@ function TableColumnActions({ children, className, label = "Column Actions", isA
|
|
|
34
34
|
className: "sr-only",
|
|
35
35
|
children: label
|
|
36
36
|
})]
|
|
37
|
-
}) }), /* @__PURE__ */
|
|
37
|
+
}) }), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
38
38
|
align,
|
|
39
39
|
className: "w-48",
|
|
40
|
-
children: [/* @__PURE__ */ jsx(DropdownMenuLabel, {
|
|
40
|
+
children: /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, {
|
|
41
41
|
className: "text-xs font-normal text-muted-foreground",
|
|
42
42
|
children: label
|
|
43
|
-
}), children]
|
|
43
|
+
}), children] })
|
|
44
44
|
})] });
|
|
45
45
|
}
|
|
46
46
|
TableColumnActions.displayName = "TableColumnActions";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Button } from "../../../ui/button.js";
|
|
3
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "../../../ui/dropdown-menu.js";
|
|
3
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "../../../ui/dropdown-menu.js";
|
|
4
4
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../../../ui/tooltip.js";
|
|
5
5
|
import { cn } from "../../../../lib/utils.js";
|
|
6
6
|
import { FILTER_VARIANTS } from "../lib/constants.js";
|
|
@@ -76,8 +76,7 @@ function TableColumnSortOptions({ column, table: propTable, variant: propVariant
|
|
|
76
76
|
column.toggleSorting(isDesc, canMultiSort ? isMulti : false);
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
80
|
-
withSeparator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
79
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [withSeparator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
|
|
81
80
|
/* @__PURE__ */ jsxs(DropdownMenuLabel, {
|
|
82
81
|
className: "flex items-center justify-between text-xs font-normal text-muted-foreground",
|
|
83
82
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -122,7 +121,7 @@ function TableColumnSortOptions({ column, table: propTable, variant: propVariant
|
|
|
122
121
|
onClick: () => column.clearSorting(),
|
|
123
122
|
children: [/* @__PURE__ */ jsx(icons.unsorted, { className: "mr-2 size-4 text-muted-foreground/70" }), "Clear Sort"]
|
|
124
123
|
})
|
|
125
|
-
] });
|
|
124
|
+
] })] });
|
|
126
125
|
}
|
|
127
126
|
/**
|
|
128
127
|
* Standalone dropdown menu for sorting.
|
|
@@ -16,7 +16,7 @@ const getCommonPinningStyles = (column, isHeader = false) => {
|
|
|
16
16
|
maxWidth: columnSize,
|
|
17
17
|
flexShrink: 0,
|
|
18
18
|
zIndex: isHeader ? 20 : 10,
|
|
19
|
-
backgroundColor: "var(--
|
|
19
|
+
backgroundColor: "var(--card)",
|
|
20
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
21
|
};
|
|
22
22
|
};
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
//#region src/components/siyahi/treemap.d.ts
|
|
2
2
|
export interface TreemapItem {
|
|
3
3
|
name: string;
|
|
4
|
-
/** Tile area, such as the holding's value. */
|
|
4
|
+
/** Tile area, such as the holding's value. Zero, negative and non-finite weights draw no tile. */
|
|
5
5
|
weight: number;
|
|
6
|
-
/** Signed change as a fraction; sets the heat. */
|
|
7
|
-
change: number;
|
|
6
|
+
/** Signed change as a fraction; sets the heat. `null` when unknown: a muted tile marked "—". */
|
|
7
|
+
change: number | null;
|
|
8
|
+
/** Unique key when names repeat, such as one symbol held at two brokers. Defaults to `name`. */
|
|
9
|
+
key?: string;
|
|
10
|
+
/** Tiles of one group, such as a sector, sit together under the group's name, even a group of one. */
|
|
11
|
+
group?: string;
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
items: TreemapItem[];
|
|
13
|
+
export interface TreemapProps<T extends TreemapItem> {
|
|
14
|
+
items: T[];
|
|
12
15
|
height: number;
|
|
13
|
-
|
|
16
|
+
/** ±range: the change, as a fraction, that takes the deepest heat step. Default 0.05 (±5%); a range that is not a positive number uses the default. */
|
|
17
|
+
range?: number;
|
|
18
|
+
/** Gets the item under the pointer, and null when the pointer moves onto a group's name or leaves the map. */
|
|
19
|
+
onHover?: (item: T | null) => void;
|
|
20
|
+
}
|
|
21
|
+
/** Holdings heat map: area by weight, colour by signed change, optionally grouped; hand-drawn SVG. */
|
|
22
|
+
export declare function Treemap<T extends TreemapItem>({ items, height, range, onHover }: TreemapProps<T>): import("react").JSX.Element;
|
|
14
23
|
//#endregion
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { useFormat } from "../../lib/format.js";
|
|
2
|
+
import { heat, layout } from "../../lib/treemap.js";
|
|
2
3
|
import { useLayoutEffect, useRef, useState } from "react";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { hierarchy, treemap, treemapSquarify } from "d3-hierarchy";
|
|
5
5
|
//#region src/components/siyahi/treemap.tsx
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const mix = Math.min(5, Math.ceil(Math.abs(change) * 100)) * 12;
|
|
9
|
-
return `color-mix(in oklab, var(${change > 0 ? "--positive" : "--negative"}) ${mix}%, var(--card))`;
|
|
10
|
-
}
|
|
11
|
-
/** Holdings heat map: area by weight, colour by signed change, hand-drawn SVG. */
|
|
12
|
-
function Treemap({ items, height }) {
|
|
6
|
+
/** Holdings heat map: area by weight, colour by signed change, optionally grouped; hand-drawn SVG. */
|
|
7
|
+
function Treemap({ items, height, range, onHover }) {
|
|
13
8
|
const ref = useRef(null);
|
|
14
9
|
const [width, setWidth] = useState(0);
|
|
15
10
|
const { pct } = useFormat();
|
|
@@ -18,39 +13,57 @@ function Treemap({ items, height }) {
|
|
|
18
13
|
if (ref.current) observer.observe(ref.current);
|
|
19
14
|
return () => observer.disconnect();
|
|
20
15
|
}, []);
|
|
21
|
-
const
|
|
22
|
-
const
|
|
16
|
+
const { groups, tiles } = layout(items, width, height);
|
|
17
|
+
const change = (value) => value === null ? "—" : `${value > 0 ? "▲ " : value < 0 ? "▼ " : ""}${pct(Math.abs(value))}`;
|
|
23
18
|
return /* @__PURE__ */ jsx("div", {
|
|
24
19
|
ref,
|
|
25
20
|
"data-slot": "treemap",
|
|
26
21
|
style: { height },
|
|
27
|
-
children: /* @__PURE__ */
|
|
22
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
28
23
|
width,
|
|
29
24
|
height,
|
|
30
25
|
role: "img",
|
|
31
26
|
"aria-label": "Treemap of holdings by weight and change",
|
|
32
27
|
className: "text-xs",
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
onPointerLeave: () => onHover?.(null),
|
|
29
|
+
children: [groups.map(({ group, ...box }) => /* @__PURE__ */ jsxs("svg", {
|
|
30
|
+
...box,
|
|
31
|
+
"data-slot": "treemap-group",
|
|
32
|
+
onPointerEnter: () => onHover?.(null),
|
|
33
|
+
children: [/* @__PURE__ */ jsx("rect", {
|
|
34
|
+
width: "100%",
|
|
35
|
+
height: "100%",
|
|
36
|
+
fill: "none",
|
|
37
|
+
pointerEvents: "all"
|
|
38
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
39
|
+
x: 2,
|
|
40
|
+
y: 12,
|
|
41
|
+
className: "fill-muted-foreground font-medium",
|
|
42
|
+
children: group
|
|
43
|
+
})]
|
|
44
|
+
}, group)), tiles.map(({ item, ...box }) => /* @__PURE__ */ jsxs("svg", {
|
|
45
|
+
...box,
|
|
46
|
+
"data-slot": "treemap-tile",
|
|
47
|
+
onPointerEnter: () => onHover?.(item),
|
|
35
48
|
children: [/* @__PURE__ */ jsx("rect", {
|
|
36
|
-
width:
|
|
37
|
-
height:
|
|
49
|
+
width: "100%",
|
|
50
|
+
height: "100%",
|
|
38
51
|
rx: 4,
|
|
39
|
-
style: { fill: heat(
|
|
40
|
-
}),
|
|
52
|
+
style: { fill: heat(item.change, range) }
|
|
53
|
+
}), box.width > 56 && box.height > 36 && /* @__PURE__ */ jsxs("text", {
|
|
41
54
|
x: 8,
|
|
42
55
|
y: 18,
|
|
43
56
|
className: "fill-foreground",
|
|
44
57
|
children: [/* @__PURE__ */ jsx("tspan", {
|
|
45
58
|
className: "font-medium",
|
|
46
|
-
children:
|
|
47
|
-
}), /* @__PURE__ */
|
|
59
|
+
children: item.name
|
|
60
|
+
}), /* @__PURE__ */ jsx("tspan", {
|
|
48
61
|
x: 8,
|
|
49
62
|
dy: 16,
|
|
50
|
-
children:
|
|
63
|
+
children: change(item.change)
|
|
51
64
|
})]
|
|
52
65
|
})]
|
|
53
|
-
},
|
|
66
|
+
}, item.key ?? item.name))]
|
|
54
67
|
})
|
|
55
68
|
});
|
|
56
69
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ import { LocalTime, LocalTimeProps } from "./components/siyahi/local-time.js";
|
|
|
43
43
|
import { PriceChart, PriceChartProps } from "./components/siyahi/price-chart.js";
|
|
44
44
|
import { SiyahiLocale, defaultLocale } from "./lib/locale.js";
|
|
45
45
|
import { SiyahiProvider, SiyahiProviderProps, useLocale } from "./components/siyahi/siyahi-provider.js";
|
|
46
|
-
import { Treemap, TreemapItem } from "./components/siyahi/treemap.js";
|
|
46
|
+
import { Treemap, TreemapItem, TreemapProps } from "./components/siyahi/treemap.js";
|
|
47
47
|
import { Alert, AlertAction, AlertDescription, AlertTitle } from "./components/ui/alert.js";
|
|
48
48
|
import { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from "./components/ui/avatar.js";
|
|
49
49
|
import { Badge, badgeVariants } from "./components/ui/badge.js";
|
|
@@ -70,4 +70,4 @@ import { Toggle, toggleVariants } from "./components/ui/toggle.js";
|
|
|
70
70
|
import { ToggleGroup, ToggleGroupItem } from "./components/ui/toggle-group.js";
|
|
71
71
|
import { Formatters, TimeOptions, money, moneyCompact, pct, time, useFormat } from "./lib/format.js";
|
|
72
72
|
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Line, LineChart, ReferenceLine, XAxis, YAxis } from "./lib/recharts.js";
|
|
73
|
-
export { ActiveCell, ActiveSelection, Activity, Alert, AlertAction, AlertDescription, AlertTitle, AppSidebar, AppSidebarProps, Area, AreaChart, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Bar, BarChart, BarList, BarListItem, BarListProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, CalendarDayButton, CalendarHeatmap, CalendarHeatmapBlock, CalendarHeatmapBlockProps, CalendarHeatmapBody, CalendarHeatmapBodyProps, CalendarHeatmapFooter, CalendarHeatmapFooterProps, CalendarHeatmapLegend, CalendarHeatmapLegendProps, CalendarHeatmapProps, CalendarHeatmapStat, CalendarHeatmapStatProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CartesianGrid, ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorConfig, ColumnResizeInfo, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DataTableActions, DataTableBody, DataTableBodyProps, type DataTableCell, type DataTableColumn, DataTableColumnActions, type DataTableColumnDef, DataTableColumnFilter, DataTableColumnHeader, DataTableColumnHeaderProps, DataTableColumnHeaderRoot, DataTableColumnSortMenu, DataTableColumnSortOptions, DataTableColumnTitle, type DataTableColumns, DataTableConfig, DataTableContainerProps, DataTableContext, DataTableContextState, DataTableEmptyActions, DataTableEmptyActionsProps, DataTableEmptyBody, DataTableEmptyBodyProps, DataTableEmptyDescription, DataTableEmptyDescriptionProps, DataTableEmptyFilteredMessage, DataTableEmptyFilteredMessageProps, DataTableEmptyIcon, DataTableEmptyIconProps, DataTableEmptyMessage, DataTableEmptyMessageProps, DataTableEmptyState, DataTableEmptyStateProps, DataTableEmptyTitle, DataTableEmptyTitleProps, DataTableErrorBoundary, DataTableErrorBoundaryProps, DataTableFacetedFilter, DataTableFacetedFilterContent, DataTableGroupRowContextValue, DataTableGroupRowProvider, DataTableGroupedRowCells, DataTableGroupedRows, DataTableGroupedRowsProps, DataTableHeader, type DataTableHeader$1 as DataTableHeaderCell, DataTableHeaderProps, type DataTableInstance, DataTableLoading, DataTableLoadingMore, DataTableLoadingMoreProps, DataTableLoadingProps, DataTableProvider, DataTableRoot, type DataTableRow, DataTableRowContextMenu, DataTableRowContextMenuProps, DataTableRowContextMenuSlot, DataTableRowContextMenuSlotProps, DataTableRowMenuScope, DataTableSkeleton, DataTableSkeletonProps, DataTableToolbarSection, DataTableToolbarSectionProps, Delta, DeltaProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type ExtendedColumnFilter, type ExtendedColumnSort, type FilterOperator, type FilterOperatorValues, type FilterVariant, type FilterVariantValues, FlashCellRef, FlashCells, FlashRows, FlashRowsOptions, Formatters, type GlobalFilter, GroupedBodyRow, GroupedBodyRowProps, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, type JoinOperator, type JoinOperatorValues, Labels, Line, LineChart, LocalTime, LocalTimeProps, NavMain, NavProjects, NavUser, type Option, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, PriceChart, PriceChartProps, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, type QueryKeys, ReferenceLine, RowMenuGroup, RowMenuItem, RowMenuLabel, RowMenuSeparator, RowMenuSub, RowMenuSubContent, RowMenuSubTrigger, ScrollAlign, ScrollArea, ScrollBar, type ScrollEvent, ScrollRowIntoView, SectionCard, SectionCards, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiyahiLocale, SiyahiProvider, SiyahiProviderProps, Skeleton, Slider, StatusActivity, StatusColorConfig, StatusHeatmap, StatusHeatmapBlock, StatusHeatmapBlockProps, StatusHeatmapBody, StatusHeatmapBodyProps, StatusHeatmapFooter, StatusHeatmapFooterProps, StatusHeatmapLabels, StatusHeatmapLegend, StatusHeatmapLegendProps, StatusHeatmapProps, StatusHeatmapStat, StatusHeatmapStatProps, StatusValue, Table, TableBody, TableCaption, TableCell, TableColumnActions, TableColumnActionsProps, TableColumnSortMenu, TableColumnSortOptions, TableColumnTitle, TableFacetedFilter, TableFacetedFilterContent, TableFacetedFilterProps, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TeamSwitcher, Textarea, TimeOptions, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Treemap, TreemapItem, type ValueOf, type ColorConfig$1 as WeekdayColorConfig, type WeekdayExtraColumnSpec, type WeekdayExtraRowSpec, WeekdayHeatmap, WeekdayHeatmapBlock, type WeekdayHeatmapBlockProps, WeekdayHeatmapBody, type WeekdayHeatmapBodyProps, WeekdayHeatmapFooter, type WeekdayHeatmapFooterProps, type WeekdayHeatmapLabels, WeekdayHeatmapLegend, type WeekdayHeatmapLegendProps, type WeekdayHeatmapProps, WeekdayHeatmapStat, type WeekdayHeatmapStatProps, type WeekdayHour, type WeekdayHourlyActivity, type WeekdayIndex, XAxis, YAxis, badgeVariants, buttonVariants, defaultLocale, flashCellKey, money, moneyCompact, pct, resolveGroupedRowsSlot, resolveRowContextMenuRenderer, tabsListVariants, time, toggleVariants, useColumnHeaderContext, useColumnResizeInfo, useDataTable, useDataTableActiveCell, useDataTableActiveCellSetter, useDataTableGroupRow, useDataTableRow, useFormat, useLocale, useResolvedRowContextMenuRenderer, useSidebar, useTableFacetedFilter };
|
|
73
|
+
export { ActiveCell, ActiveSelection, Activity, Alert, AlertAction, AlertDescription, AlertTitle, AppSidebar, AppSidebarProps, Area, AreaChart, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Bar, BarChart, BarList, BarListItem, BarListProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, CalendarDayButton, CalendarHeatmap, CalendarHeatmapBlock, CalendarHeatmapBlockProps, CalendarHeatmapBody, CalendarHeatmapBodyProps, CalendarHeatmapFooter, CalendarHeatmapFooterProps, CalendarHeatmapLegend, CalendarHeatmapLegendProps, CalendarHeatmapProps, CalendarHeatmapStat, CalendarHeatmapStatProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CartesianGrid, ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorConfig, ColumnResizeInfo, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DataTableActions, DataTableBody, DataTableBodyProps, type DataTableCell, type DataTableColumn, DataTableColumnActions, type DataTableColumnDef, DataTableColumnFilter, DataTableColumnHeader, DataTableColumnHeaderProps, DataTableColumnHeaderRoot, DataTableColumnSortMenu, DataTableColumnSortOptions, DataTableColumnTitle, type DataTableColumns, DataTableConfig, DataTableContainerProps, DataTableContext, DataTableContextState, DataTableEmptyActions, DataTableEmptyActionsProps, DataTableEmptyBody, DataTableEmptyBodyProps, DataTableEmptyDescription, DataTableEmptyDescriptionProps, DataTableEmptyFilteredMessage, DataTableEmptyFilteredMessageProps, DataTableEmptyIcon, DataTableEmptyIconProps, DataTableEmptyMessage, DataTableEmptyMessageProps, DataTableEmptyState, DataTableEmptyStateProps, DataTableEmptyTitle, DataTableEmptyTitleProps, DataTableErrorBoundary, DataTableErrorBoundaryProps, DataTableFacetedFilter, DataTableFacetedFilterContent, DataTableGroupRowContextValue, DataTableGroupRowProvider, DataTableGroupedRowCells, DataTableGroupedRows, DataTableGroupedRowsProps, DataTableHeader, type DataTableHeader$1 as DataTableHeaderCell, DataTableHeaderProps, type DataTableInstance, DataTableLoading, DataTableLoadingMore, DataTableLoadingMoreProps, DataTableLoadingProps, DataTableProvider, DataTableRoot, type DataTableRow, DataTableRowContextMenu, DataTableRowContextMenuProps, DataTableRowContextMenuSlot, DataTableRowContextMenuSlotProps, DataTableRowMenuScope, DataTableSkeleton, DataTableSkeletonProps, DataTableToolbarSection, DataTableToolbarSectionProps, Delta, DeltaProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type ExtendedColumnFilter, type ExtendedColumnSort, type FilterOperator, type FilterOperatorValues, type FilterVariant, type FilterVariantValues, FlashCellRef, FlashCells, FlashRows, FlashRowsOptions, Formatters, type GlobalFilter, GroupedBodyRow, GroupedBodyRowProps, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, type JoinOperator, type JoinOperatorValues, Labels, Line, LineChart, LocalTime, LocalTimeProps, NavMain, NavProjects, NavUser, type Option, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, PriceChart, PriceChartProps, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, type QueryKeys, ReferenceLine, RowMenuGroup, RowMenuItem, RowMenuLabel, RowMenuSeparator, RowMenuSub, RowMenuSubContent, RowMenuSubTrigger, ScrollAlign, ScrollArea, ScrollBar, type ScrollEvent, ScrollRowIntoView, SectionCard, SectionCards, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiyahiLocale, SiyahiProvider, SiyahiProviderProps, Skeleton, Slider, StatusActivity, StatusColorConfig, StatusHeatmap, StatusHeatmapBlock, StatusHeatmapBlockProps, StatusHeatmapBody, StatusHeatmapBodyProps, StatusHeatmapFooter, StatusHeatmapFooterProps, StatusHeatmapLabels, StatusHeatmapLegend, StatusHeatmapLegendProps, StatusHeatmapProps, StatusHeatmapStat, StatusHeatmapStatProps, StatusValue, Table, TableBody, TableCaption, TableCell, TableColumnActions, TableColumnActionsProps, TableColumnSortMenu, TableColumnSortOptions, TableColumnTitle, TableFacetedFilter, TableFacetedFilterContent, TableFacetedFilterProps, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TeamSwitcher, Textarea, TimeOptions, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Treemap, TreemapItem, TreemapProps, type ValueOf, type ColorConfig$1 as WeekdayColorConfig, type WeekdayExtraColumnSpec, type WeekdayExtraRowSpec, WeekdayHeatmap, WeekdayHeatmapBlock, type WeekdayHeatmapBlockProps, WeekdayHeatmapBody, type WeekdayHeatmapBodyProps, WeekdayHeatmapFooter, type WeekdayHeatmapFooterProps, type WeekdayHeatmapLabels, WeekdayHeatmapLegend, type WeekdayHeatmapLegendProps, type WeekdayHeatmapProps, WeekdayHeatmapStat, type WeekdayHeatmapStatProps, type WeekdayHour, type WeekdayHourlyActivity, type WeekdayIndex, XAxis, YAxis, badgeVariants, buttonVariants, defaultLocale, flashCellKey, money, moneyCompact, pct, resolveGroupedRowsSlot, resolveRowContextMenuRenderer, tabsListVariants, time, toggleVariants, useColumnHeaderContext, useColumnResizeInfo, useDataTable, useDataTableActiveCell, useDataTableActiveCellSetter, useDataTableGroupRow, useDataTableRow, useFormat, useLocale, useResolvedRowContextMenuRenderer, useSidebar, useTableFacetedFilter };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/lib/treemap.d.ts
|
|
2
|
+
interface Box {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
export interface Layout<T> {
|
|
9
|
+
groups: (Box & {
|
|
10
|
+
group: string;
|
|
11
|
+
})[];
|
|
12
|
+
tiles: (Box & {
|
|
13
|
+
item: T;
|
|
14
|
+
})[];
|
|
15
|
+
}
|
|
16
|
+
/** Squarified layout: items without a group are tiles of their own, the rest sit together under their group's label. */
|
|
17
|
+
export declare function layout<T extends {
|
|
18
|
+
weight: number;
|
|
19
|
+
group?: string;
|
|
20
|
+
}>(items: T[], width: number, height: number): Layout<T>;
|
|
21
|
+
export declare function heat(change: number | null, range?: number): string;
|
|
22
|
+
//#endregion
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { hierarchy, treemap, treemapSquarify } from "d3-hierarchy";
|
|
2
|
+
//#region src/lib/treemap.ts
|
|
3
|
+
/** Height of a group's label row, above its tiles. */
|
|
4
|
+
const GROUP_LABEL = 18;
|
|
5
|
+
const box = ({ x0, y0, x1, y1 }) => ({
|
|
6
|
+
x: x0,
|
|
7
|
+
y: y0,
|
|
8
|
+
width: x1 - x0,
|
|
9
|
+
height: y1 - y0
|
|
10
|
+
});
|
|
11
|
+
const area = (weight) => weight !== void 0 && Number.isFinite(weight) && weight > 0 ? weight : 0;
|
|
12
|
+
/** Squarified layout: items without a group are tiles of their own, the rest sit together under their group's label. */
|
|
13
|
+
function layout(items, width, height) {
|
|
14
|
+
const nested = { children: [...Map.groupBy(items, (item) => item.group)].flatMap(([group, members]) => {
|
|
15
|
+
const tiles = members.map((item) => ({ item }));
|
|
16
|
+
return group === void 0 ? tiles : [{
|
|
17
|
+
group,
|
|
18
|
+
children: tiles
|
|
19
|
+
}];
|
|
20
|
+
}) };
|
|
21
|
+
const root = treemap().size([width, height]).paddingInner(2).paddingTop(({ data }) => data.group === void 0 ? 0 : GROUP_LABEL).tile(treemapSquarify)(hierarchy(nested).sum(({ item }) => area(item?.weight)));
|
|
22
|
+
return {
|
|
23
|
+
groups: (root.children ?? []).flatMap((node) => node.data.group === void 0 || !node.value ? [] : [{
|
|
24
|
+
...box(node),
|
|
25
|
+
height: GROUP_LABEL,
|
|
26
|
+
group: node.data.group
|
|
27
|
+
}]),
|
|
28
|
+
tiles: root.leaves().flatMap((node) => node.data.item === void 0 || !node.value ? [] : [{
|
|
29
|
+
...box(node),
|
|
30
|
+
item: node.data.item
|
|
31
|
+
}])
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function heat(change, range = .05) {
|
|
35
|
+
if (!change) return "var(--muted)";
|
|
36
|
+
const mix = Math.min(5, Math.ceil(Math.abs(change) / (Number.isFinite(range) && range > 0 ? range : .05) * 5)) * 12;
|
|
37
|
+
return `color-mix(in oklab, var(${change > 0 ? "--positive" : "--negative"}) ${mix}%, var(--card))`;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { heat, layout };
|