@siyahi/ui 0.1.9-next.33 → 0.1.9-next.35
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/DESIGN.md +21 -7
- package/README.md +5 -5
- package/agents/examples/app-sidebar.tsx +0 -2
- package/agents/examples/chart-panels-three.tsx +51 -0
- package/agents/examples/context-menu.tsx +14 -4
- package/agents/examples/overview-dashboard.tsx +2 -2
- package/agents/examples/{page-hero.tsx → page-header.tsx} +4 -4
- package/agents/examples/select.tsx +2 -1
- package/agents/manifest.json +16 -5
- package/dist/components/registry/charts/area-chart-card.js +1 -0
- package/dist/components/registry/charts/bar-chart-card.js +0 -2
- package/dist/components/registry/heatmap/calendar-heatmap.js +1 -1
- package/dist/components/registry/heatmap/status-heatmap.js +1 -1
- package/dist/components/registry/heatmap/weekday-heatmap.js +1 -1
- package/dist/components/registry/niko-table/core/data-table-error-boundary.js +1 -1
- package/dist/components/registry/niko-table/core/data-table-structure.js +6 -0
- package/dist/components/registry/niko-table/core/data-table.js +1 -1
- package/dist/components/registry/niko-table/filters/table-column-sort.js +2 -2
- package/dist/components/registry/niko-table/filters/table-faceted-filter.js +3 -3
- package/dist/components/registry/niko-table/lib/column-resize-handle.js +1 -1
- package/dist/components/registry/sidebar-07/nav-user.js +16 -19
- package/dist/components/siyahi/{page-hero.d.ts → page-header.d.ts} +3 -3
- package/dist/components/siyahi/{page-hero.js → page-header.js} +4 -4
- package/dist/components/siyahi/panel-grid.d.ts +5 -2
- package/dist/components/siyahi/panel-grid.js +1 -1
- package/dist/components/siyahi/range-position.js +1 -1
- package/dist/components/siyahi/scatter-chart.js +15 -2
- package/dist/components/siyahi/status-badge.js +1 -0
- package/dist/components/siyahi/target-rows.js +2 -2
- package/dist/components/siyahi/treemap.js +0 -3
- package/dist/components/ui/alert-dialog.d.ts +20 -0
- package/dist/components/ui/alert-dialog.js +94 -0
- package/dist/components/ui/aspect-ratio.d.ts +6 -0
- package/dist/components/ui/aspect-ratio.js +13 -0
- package/dist/components/ui/attachment.d.ts +25 -0
- package/dist/components/ui/attachment.js +104 -0
- package/dist/components/ui/bubble.d.ts +18 -0
- package/dist/components/ui/bubble.js +73 -0
- package/dist/components/ui/button-group.d.ts +12 -0
- package/dist/components/ui/button-group.js +41 -0
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/carousel.d.ts +30 -0
- package/dist/components/ui/carousel.js +131 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.js +20 -0
- package/dist/components/ui/combobox.d.ts +26 -0
- package/dist/components/ui/combobox.js +162 -0
- package/dist/components/ui/command.js +1 -1
- package/dist/components/ui/direction.d.ts +2 -0
- package/dist/components/ui/direction.js +1 -0
- package/dist/components/ui/drawer.d.ts +18 -0
- package/dist/components/ui/drawer.js +123 -0
- package/dist/components/ui/empty.d.ts +13 -0
- package/dist/components/ui/empty.js +59 -0
- package/dist/components/ui/field.js +1 -1
- package/dist/components/ui/hover-card.d.ts +7 -0
- package/dist/components/ui/hover-card.js +36 -0
- package/dist/components/ui/input-otp.d.ts +13 -0
- package/dist/components/ui/input-otp.js +46 -0
- package/dist/components/ui/item.d.ts +24 -0
- package/dist/components/ui/item.js +121 -0
- package/dist/components/ui/kbd.d.ts +5 -0
- package/dist/components/ui/kbd.js +19 -0
- package/dist/components/ui/marker.d.ts +12 -0
- package/dist/components/ui/marker.js +43 -0
- package/dist/components/ui/menubar.d.ts +31 -0
- package/dist/components/ui/menubar.js +136 -0
- package/dist/components/ui/message-scroller.d.ts +12 -0
- package/dist/components/ui/message-scroller.js +60 -0
- package/dist/components/ui/message.d.ts +12 -0
- package/dist/components/ui/message.js +49 -0
- package/dist/components/ui/native-select.d.ts +10 -0
- package/dist/components/ui/native-select.js +38 -0
- package/dist/components/ui/navigation-menu.d.ts +13 -0
- package/dist/components/ui/navigation-menu.js +82 -0
- package/dist/components/ui/pagination.d.ts +19 -0
- package/dist/components/ui/pagination.js +80 -0
- package/dist/components/ui/questionnaire.d.ts +21 -0
- package/dist/components/ui/questionnaire.js +170 -0
- package/dist/components/ui/radio-group.d.ts +7 -0
- package/dist/components/ui/radio-group.js +26 -0
- package/dist/components/ui/resizable.d.ts +9 -0
- package/dist/components/ui/resizable.js +28 -0
- package/dist/components/ui/sidebar.js +1 -1
- package/dist/components/ui/spinner.d.ts +4 -0
- package/dist/components/ui/spinner.js +15 -0
- package/dist/components/ui/switch.d.ts +7 -0
- package/dist/components/ui/switch.js +19 -0
- package/dist/components/ui/toast.d.ts +18 -0
- package/dist/components/ui/toast.js +123 -0
- package/dist/components/ui/trace.d.ts +20 -0
- package/dist/components/ui/trace.js +75 -0
- package/dist/index.d.ts +32 -2
- package/dist/index.js +35 -5
- package/dist/lib/chart-frame.d.ts +37 -9
- package/dist/lib/chart-frame.js +60 -30
- package/dist/lib/chart-series.d.ts +3 -2
- package/dist/lib/ticks.d.ts +9 -0
- package/dist/lib/ticks.js +25 -3
- package/dist/lib/use-render-when-fonts-load.d.ts +11 -0
- package/dist/lib/use-render-when-fonts-load.js +49 -0
- package/package.json +5 -3
- package/styles/siyahi.css +224 -26
- package/agents/report-rules.json +0 -7
- package/report.css +0 -145
package/DESIGN.md
CHANGED
|
@@ -24,7 +24,9 @@ a meaning:
|
|
|
24
24
|
inside a 1px border of the same colour all round. Large marks follow the same
|
|
25
25
|
rule: every bar is a tint inside a 1px full-colour edge, not a solid slab.
|
|
26
26
|
A bar is read by its edge, which reaches 3:1 against the card; the tint is a
|
|
27
|
-
fill carried by that edge
|
|
27
|
+
fill carried by that edge: half its colour (`--bar-tint`, 50%), strong
|
|
28
|
+
enough that a thin stacked segment, mostly edge, still shows its colour
|
|
29
|
+
against the next, and a pale slot's bar does not read as the card.
|
|
28
30
|
- **Never a stripe down one side.** Do not mark a notice, card, row or quote
|
|
29
31
|
with a left (or any single-side) coloured border; tint the box or add an
|
|
30
32
|
icon. 1px neutral dividers between columns are separators, not accents, and
|
|
@@ -83,10 +85,16 @@ mono face and the link colour, so the text can point to one.
|
|
|
83
85
|
## Shape
|
|
84
86
|
|
|
85
87
|
- **Square corners everywhere**: panels, cards, buttons, fields, badges,
|
|
86
|
-
toggles, menus,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
toggles, menus, bars and tracks (data bars, progress, a slider's track and
|
|
89
|
+
thumb, a scrollbar's thumb), heatmap cells, treemap tiles and the colour
|
|
90
|
+
chips of charts and legends alike (`--radius` is 0). Only what is round by
|
|
91
|
+
nature stays round: an avatar, a radio, a status dot, a line's end dot, a
|
|
92
|
+
spinner, and a signed calendar heatmap's loss day, whose shape carries its
|
|
93
|
+
sign. The theme squares every other rounding, on any component.
|
|
94
|
+
Never add a `rounded-*` class to a box.
|
|
95
|
+
- **Floating surfaces lie flat.** Nothing casts a drop shadow: a menu, a
|
|
96
|
+
list, a popover, a dialog, a sheet, a hover card and a chart's tooltip take
|
|
97
|
+
the card's hairline for their edge, so they read as a sheet of the page.
|
|
90
98
|
- **Joined toggles.** The items of a `ToggleGroup` sit flush and share their
|
|
91
99
|
borders, one control; the pressed item fills with the foreground.
|
|
92
100
|
- **A code block's copy button sits in a header row** (`CodeBlockHeader`),
|
|
@@ -97,7 +105,7 @@ mono face and the link colour, so the text can point to one.
|
|
|
97
105
|
|
|
98
106
|
## Page header
|
|
99
107
|
|
|
100
|
-
An app page opens on its masthead, `
|
|
108
|
+
An app page opens on its masthead, `PageHeader`: a small mark and eyebrow in the
|
|
101
109
|
mono face and link colour, the title, one muted line saying what the page is,
|
|
102
110
|
the actions at the right, and a hairline under it. One per page; no hero card.
|
|
103
111
|
|
|
@@ -186,7 +194,8 @@ from the catalogue.
|
|
|
186
194
|
|
|
187
195
|
- **Labels are small monospaced capitals**: a stat tile's label and footer
|
|
188
196
|
lines, a `MetricStrip` label, a table's column heads, a sidebar group's
|
|
189
|
-
label,
|
|
197
|
+
label, a group's label in a menu, a select's list or the command palette,
|
|
198
|
+
and a form field's label (muted, above the field). The components and
|
|
190
199
|
the theme set them; never set a label in this style by hand elsewhere, and
|
|
191
200
|
never set a figure or a title in it.
|
|
192
201
|
- **A total row reads as a ledger's**: in `TableFooter`, one rule above it and
|
|
@@ -211,6 +220,11 @@ from the catalogue.
|
|
|
211
220
|
a stack's grey bands read in the legend's order, bottom to top.
|
|
212
221
|
- **No fill under overlapping areas**: from three series on, fills bury each
|
|
213
222
|
other. A stack fills each band with a flat tint, never a gradient.
|
|
223
|
+
- **The value axis just covers the data.** Unless the page fixes it, it ends
|
|
224
|
+
on the round tick just past what is drawn (a 46,800 peak at 50,000, by
|
|
225
|
+
10,000s), a stack's totals for a stack. Bars and stacks reach zero, since
|
|
226
|
+
their length is the value; lines and overlapping areas need not, so a
|
|
227
|
+
revenue line from ₹38L to ₹45L fills the plot rather than its top fifth.
|
|
214
228
|
- **Forecast and today.** `forecastFrom` dashes every line from that point,
|
|
215
229
|
hatches the stretch faintly behind lines on card-coloured halos, labels it
|
|
216
230
|
FORECAST and hollows the end dots (a stack keeps solid edges and no hatching:
|
package/README.md
CHANGED
|
@@ -58,8 +58,8 @@ createRoot(root).render(
|
|
|
58
58
|
|
|
59
59
|
`preloadFonts()` loads Geist and Geist Mono with the scripts. Add `lucide-react`
|
|
60
60
|
only when your own code imports icons. Next.js compiles the stylesheet through
|
|
61
|
-
`@tailwindcss/postcss` instead of the Vite plugin.
|
|
62
|
-
|
|
61
|
+
`@tailwindcss/postcss` instead of the Vite plugin. To host one page as a single
|
|
62
|
+
HTML file, build it with `siyahi-page` from `@siyahi/tools`.
|
|
63
63
|
|
|
64
64
|
If npm is unreachable, both package tarballs are attached to
|
|
65
65
|
[GitHub releases](https://github.com/jatinbansal1998/siyahi/releases).
|
|
@@ -136,8 +136,8 @@ Set `color-scheme` on `<html>` as well so native controls match.
|
|
|
136
136
|
## Tools
|
|
137
137
|
|
|
138
138
|
`@siyahi/tools` provides theme lint rules, font preload, layout screenshots
|
|
139
|
-
(`siyahi-shots`), loading-shift checks (`siyahi-cls`)
|
|
140
|
-
(`siyahi-contrast`). See the
|
|
139
|
+
(`siyahi-shots`), loading-shift checks (`siyahi-cls`), contrast checks
|
|
140
|
+
(`siyahi-contrast`) and a one-file page build (`siyahi-page`). See the
|
|
141
141
|
[tools guide](https://github.com/jatinbansal1998/siyahi/blob/main/packages/tools/README.md)
|
|
142
142
|
for configuration and commands.
|
|
143
143
|
|
|
@@ -146,7 +146,7 @@ for configuration and commands.
|
|
|
146
146
|
```sh
|
|
147
147
|
pnpm install
|
|
148
148
|
pnpm --filter @siyahi/tools exec playwright install chromium
|
|
149
|
-
pnpm check
|
|
149
|
+
pnpm check:static # the full suite runs on each pull request's CI
|
|
150
150
|
pnpm dev
|
|
151
151
|
```
|
|
152
152
|
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
BlocksIcon,
|
|
4
4
|
ChartAreaIcon,
|
|
5
5
|
CodeIcon,
|
|
6
|
-
FileTextIcon,
|
|
7
6
|
HouseIcon,
|
|
8
7
|
LayersIcon,
|
|
9
8
|
PaletteIcon,
|
|
@@ -18,7 +17,6 @@ const views = [
|
|
|
18
17
|
{ title: "Inputs and overlays", url: "#/inputs", icon: <SlidersHorizontalIcon /> },
|
|
19
18
|
{ title: "Data", url: "#/data", icon: <ChartAreaIcon /> },
|
|
20
19
|
{ title: "Blocks", url: "#/blocks", icon: <BlocksIcon />, isActive: true },
|
|
21
|
-
{ title: "Reports", url: "#/reports", icon: <FileTextIcon /> },
|
|
22
20
|
// linkProps go onto the anchor: here a new tab, in an app often onMouseEnter to prefetch the view's data.
|
|
23
21
|
{
|
|
24
22
|
title: "Source",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { AreaChartCard, BarChartCard, LineChartCard, PanelGrid, useFormat } from "@siyahi/ui";
|
|
2
|
+
|
|
3
|
+
// One fund over six months: its month-end growth, its value and what was added each month.
|
|
4
|
+
const months = [
|
|
5
|
+
{ month: "May", growth: 0, value: 410000, added: 20000 },
|
|
6
|
+
{ month: "Jun", growth: 0.025, value: 432000, added: 15000 },
|
|
7
|
+
{ month: "Jul", growth: 0.061, value: 455000, added: 10000 },
|
|
8
|
+
{ month: "Aug", growth: 0.047, value: 461000, added: 25000 },
|
|
9
|
+
{ month: "Sep", growth: 0.11, value: 498000, added: 15000 },
|
|
10
|
+
{ month: "Oct", growth: 0.156, value: 527000, added: 20000 },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
// Three short panels in a reading column about as wide as an article (max-w-4xl, 56rem): three across from 42rem.
|
|
14
|
+
export default function ChartPanelsThreeExample() {
|
|
15
|
+
const { pct, money, moneyCompact } = useFormat();
|
|
16
|
+
return (
|
|
17
|
+
<div className="max-w-4xl">
|
|
18
|
+
<PanelGrid columns={3}>
|
|
19
|
+
<LineChartCard
|
|
20
|
+
title="Growth"
|
|
21
|
+
description="Since May, month-end"
|
|
22
|
+
data={months}
|
|
23
|
+
xKey="month"
|
|
24
|
+
series={[{ key: "growth", label: "Growth", color: "var(--chart-1)" }]}
|
|
25
|
+
valueFormatter={pct}
|
|
26
|
+
height={160}
|
|
27
|
+
/>
|
|
28
|
+
<AreaChartCard
|
|
29
|
+
title="Value"
|
|
30
|
+
description="Month-end, ₹"
|
|
31
|
+
data={months}
|
|
32
|
+
xKey="month"
|
|
33
|
+
series={[{ key: "value", label: "Value", color: "var(--chart-1)" }]}
|
|
34
|
+
valueFormatter={money}
|
|
35
|
+
yTickFormatter={moneyCompact}
|
|
36
|
+
height={160}
|
|
37
|
+
/>
|
|
38
|
+
<BarChartCard
|
|
39
|
+
title="Added"
|
|
40
|
+
description="Each month, ₹"
|
|
41
|
+
data={months}
|
|
42
|
+
xKey="month"
|
|
43
|
+
series={[{ key: "added", label: "Added", color: "var(--chart-1)" }]}
|
|
44
|
+
valueFormatter={money}
|
|
45
|
+
yTickFormatter={moneyCompact}
|
|
46
|
+
height={160}
|
|
47
|
+
/>
|
|
48
|
+
</PanelGrid>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ContextMenu,
|
|
3
|
+
ContextMenuContent,
|
|
4
|
+
ContextMenuGroup,
|
|
5
|
+
ContextMenuItem,
|
|
6
|
+
ContextMenuLabel,
|
|
7
|
+
ContextMenuTrigger,
|
|
8
|
+
} from "@siyahi/ui";
|
|
2
9
|
|
|
3
10
|
export default function ContextMenuExample() {
|
|
4
11
|
return (
|
|
5
12
|
<ContextMenu>
|
|
6
13
|
<ContextMenuTrigger className="w-full">
|
|
7
|
-
<div className="flex h-24 items-center justify-center
|
|
14
|
+
<div className="flex h-24 items-center justify-center border text-muted-foreground">
|
|
8
15
|
Right-click or long-press here
|
|
9
16
|
</div>
|
|
10
17
|
</ContextMenuTrigger>
|
|
11
18
|
<ContextMenuContent>
|
|
12
|
-
<
|
|
13
|
-
|
|
19
|
+
<ContextMenuGroup>
|
|
20
|
+
<ContextMenuLabel>Order</ContextMenuLabel>
|
|
21
|
+
<ContextMenuItem>Copy order number</ContextMenuItem>
|
|
22
|
+
<ContextMenuItem>Open order</ContextMenuItem>
|
|
23
|
+
</ContextMenuGroup>
|
|
14
24
|
</ContextMenuContent>
|
|
15
25
|
</ContextMenu>
|
|
16
26
|
);
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
CardTitle,
|
|
10
10
|
Delta,
|
|
11
11
|
Input,
|
|
12
|
-
|
|
12
|
+
PageHeader,
|
|
13
13
|
PanelGrid,
|
|
14
14
|
StatusBadge,
|
|
15
15
|
Table,
|
|
@@ -126,7 +126,7 @@ export default function OverviewDashboard() {
|
|
|
126
126
|
const shown = holdings.filter((row) => row.name.toLowerCase().includes(query.trim().toLowerCase()));
|
|
127
127
|
return (
|
|
128
128
|
<div className="flex flex-col gap-6">
|
|
129
|
-
<
|
|
129
|
+
<PageHeader
|
|
130
130
|
mark={<InkDrop />}
|
|
131
131
|
eyebrow="The Book"
|
|
132
132
|
title="Holdings"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Button,
|
|
1
|
+
import { Button, PageHeader } from "@siyahi/ui";
|
|
2
2
|
import { ArrowRightIcon } from "lucide-react";
|
|
3
3
|
|
|
4
|
-
// The catalogue's own ink drop, painted with currentColor so the
|
|
4
|
+
// The catalogue's own ink drop, painted with currentColor so the header tints it.
|
|
5
5
|
function InkDrop() {
|
|
6
6
|
return (
|
|
7
7
|
<svg viewBox="0 0 16 16">
|
|
@@ -14,9 +14,9 @@ function InkDrop() {
|
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export default function
|
|
17
|
+
export default function PageHeaderExample() {
|
|
18
18
|
return (
|
|
19
|
-
<
|
|
19
|
+
<PageHeader
|
|
20
20
|
eyebrow="@siyahi/ui"
|
|
21
21
|
title="Siyahi"
|
|
22
22
|
lead="Ink for numbers. A design system for pages people read figures from: dashboards, ledgers, reports."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@siyahi/ui";
|
|
1
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@siyahi/ui";
|
|
2
2
|
|
|
3
3
|
const stores = [
|
|
4
4
|
{ label: "All stores", value: "all" },
|
|
@@ -15,6 +15,7 @@ export default function SelectExample() {
|
|
|
15
15
|
</SelectTrigger>
|
|
16
16
|
<SelectContent>
|
|
17
17
|
<SelectGroup>
|
|
18
|
+
<SelectLabel>Sales channel</SelectLabel>
|
|
18
19
|
{stores.map((store) => (
|
|
19
20
|
<SelectItem key={store.value} value={store.value}>
|
|
20
21
|
{store.label}
|
package/agents/manifest.json
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
"props": "dist/index.d.ts",
|
|
5
5
|
"setup": "README.md#install",
|
|
6
6
|
"layout": "README.md#surfaces",
|
|
7
|
-
"report": "report.css",
|
|
8
|
-
"reportRules": "agents/report-rules.json",
|
|
9
7
|
"recipes": {
|
|
10
8
|
"dashboard": "agents/examples/surfaces.tsx",
|
|
11
9
|
"table": "agents/examples/data-table.tsx",
|
|
@@ -671,6 +669,16 @@
|
|
|
671
669
|
"useFormat"
|
|
672
670
|
]
|
|
673
671
|
},
|
|
672
|
+
{
|
|
673
|
+
"file": "agents/examples/chart-panels-three.tsx",
|
|
674
|
+
"components": [
|
|
675
|
+
"AreaChartCard",
|
|
676
|
+
"BarChartCard",
|
|
677
|
+
"LineChartCard",
|
|
678
|
+
"PanelGrid",
|
|
679
|
+
"useFormat"
|
|
680
|
+
]
|
|
681
|
+
},
|
|
674
682
|
{
|
|
675
683
|
"file": "agents/examples/chart-panels.tsx",
|
|
676
684
|
"components": [
|
|
@@ -717,7 +725,9 @@
|
|
|
717
725
|
"components": [
|
|
718
726
|
"ContextMenu",
|
|
719
727
|
"ContextMenuContent",
|
|
728
|
+
"ContextMenuGroup",
|
|
720
729
|
"ContextMenuItem",
|
|
730
|
+
"ContextMenuLabel",
|
|
721
731
|
"ContextMenuTrigger"
|
|
722
732
|
]
|
|
723
733
|
},
|
|
@@ -1038,7 +1048,7 @@
|
|
|
1038
1048
|
"CardTitle",
|
|
1039
1049
|
"Delta",
|
|
1040
1050
|
"Input",
|
|
1041
|
-
"
|
|
1051
|
+
"PageHeader",
|
|
1042
1052
|
"PanelGrid",
|
|
1043
1053
|
"StatusBadge",
|
|
1044
1054
|
"Table",
|
|
@@ -1054,10 +1064,10 @@
|
|
|
1054
1064
|
]
|
|
1055
1065
|
},
|
|
1056
1066
|
{
|
|
1057
|
-
"file": "agents/examples/page-
|
|
1067
|
+
"file": "agents/examples/page-header.tsx",
|
|
1058
1068
|
"components": [
|
|
1059
1069
|
"Button",
|
|
1060
|
-
"
|
|
1070
|
+
"PageHeader"
|
|
1061
1071
|
]
|
|
1062
1072
|
},
|
|
1063
1073
|
{
|
|
@@ -1208,6 +1218,7 @@
|
|
|
1208
1218
|
"SelectContent",
|
|
1209
1219
|
"SelectGroup",
|
|
1210
1220
|
"SelectItem",
|
|
1221
|
+
"SelectLabel",
|
|
1211
1222
|
"SelectTrigger",
|
|
1212
1223
|
"SelectValue"
|
|
1213
1224
|
]
|
|
@@ -18,6 +18,7 @@ function AreaChartCard({ stacked = false, curve = "monotone", ...props }) {
|
|
|
18
18
|
return /* @__PURE__ */ jsxs(ChartFrame, {
|
|
19
19
|
chart: AreaChart,
|
|
20
20
|
logBlocked: stacked ? "Log cannot show stacked areas" : void 0,
|
|
21
|
+
stackOffset: stacked ? "none" : void 0,
|
|
21
22
|
endLabels: !stacked,
|
|
22
23
|
forecastHatch: !stacked,
|
|
23
24
|
curve,
|
|
@@ -3,13 +3,11 @@ import { ChartFrame, barFill, seriesFill } from "../../../lib/chart-frame.js";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { Bar, BarChart, Cell } from "recharts";
|
|
5
5
|
//#region src/components/registry/charts/bar-chart-card.tsx
|
|
6
|
-
const DOWN_FROM_ZERO = ["auto", 0];
|
|
7
6
|
/** Values over an ordered axis as bars: one series, or several grouped or stacked. */
|
|
8
7
|
function BarChartCard({ stacked = false, selected = null, onSelect, ...props }) {
|
|
9
8
|
return /* @__PURE__ */ jsx(ChartFrame, {
|
|
10
9
|
chart: BarChart,
|
|
11
10
|
...props,
|
|
12
|
-
yDomain: props.yDomain ?? (props.data.some((row) => props.series.some(({ key }) => Number(row[key]) > 0)) ? void 0 : DOWN_FROM_ZERO),
|
|
13
11
|
stackOffset: stacked ? "sign" : void 0,
|
|
14
12
|
onClick: onSelect ? ({ activeTooltipIndex, isTooltipActive }) => {
|
|
15
13
|
if (!isTooltipActive || activeTooltipIndex == null) return;
|
|
@@ -226,7 +226,7 @@ const getMonthLabels = (weeks, monthNames = generateMonthLabels(), yearTicks = f
|
|
|
226
226
|
* @param levels - Total number of legend cells (including empty when not normalized). Default: 5
|
|
227
227
|
* @param isNormalized - When true, uses min-max normalization across the dataset (suitable for signed values). When false (default), treats 0 as empty and scales from 0 to max.
|
|
228
228
|
*/
|
|
229
|
-
const CalendarHeatmap = ({ data, weekStart = 0, continuousMonths = true, hasEmptyColumn = false, blockSize: blockSizeProp, blockMargin = 4, blockRadius =
|
|
229
|
+
const CalendarHeatmap = ({ data, weekStart = 0, continuousMonths = true, hasEmptyColumn = false, blockSize: blockSizeProp, blockMargin = 4, blockRadius = 0, blockAspectRatio = 1, levels: levelsProp = 5, isNormalized = false, signed = false, range, colors, locale, labels: labelsProp, fontSize = 14, emptyState, totalCount: totalCountProp, style = EMPTY_STYLE, className, children, ...props }) => {
|
|
230
230
|
const levels = Math.max(1, levelsProp);
|
|
231
231
|
const [rootRef, rootWidth] = useElementWidth();
|
|
232
232
|
const dataWithLevels = useMemo(() => {
|
|
@@ -109,7 +109,7 @@ const useStatusHeatmap = () => {
|
|
|
109
109
|
* @param blockAspectRatio - Width/height ratio of blocks. Default: bars share the full width
|
|
110
110
|
* @param colors - Custom colors for critical, degraded, and healthy states
|
|
111
111
|
*/
|
|
112
|
-
const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin = 2, blockRadius =
|
|
112
|
+
const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin = 2, blockRadius = 0, blockAspectRatio: blockAspectRatioProp, colors, locale, labels: labelsProp, fontSize = 14, emptyState, statusValues = [
|
|
113
113
|
0,
|
|
114
114
|
1,
|
|
115
115
|
2,
|
|
@@ -89,7 +89,7 @@ const useWeekdayHeatmap = () => {
|
|
|
89
89
|
* @param extraRow - Appends an aggregated row below the grid. `compute` receives all activities and must return 24 values (one per hour). Rendered through `renderExtraRow` on the body, or falls back to `children`.
|
|
90
90
|
* @param extraColumn - Appends an aggregated column to the right of the grid. `compute` receives all activities and must return 7 values indexed by weekday 0–6. Rendered through `renderExtraColumn` on the body, or falls back to `children`.
|
|
91
91
|
*/
|
|
92
|
-
const WeekdayHeatmap = ({ data, weekStart = 0, hours = HOURS, weekdays: displayedWeekdays, use12Hour = false, blockSize: blockSizeProp, blockMargin = 4, blockRadius =
|
|
92
|
+
const WeekdayHeatmap = ({ data, weekStart = 0, hours = HOURS, weekdays: displayedWeekdays, use12Hour = false, blockSize: blockSizeProp, blockMargin = 4, blockRadius = 0, blockAspectRatio = 1, levels: levelsProp = 5, isNormalized = false, colors, locale, labels: labelsProp, fontSize = 14, emptyState, totalCount: totalCountProp, extraRow, extraColumn, style = EMPTY_STYLE, className, children, ...props }) => {
|
|
93
93
|
const levels = Math.max(1, levelsProp);
|
|
94
94
|
const [rootRef, rootWidth] = useElementWidth();
|
|
95
95
|
const weekdays = useMemo(() => displayedWeekdays ?? Array.from({ length: 7 }, (_, i) => (weekStart + i) % 7), [displayedWeekdays, weekStart]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { Alert, AlertDescription, AlertTitle } from "../../../ui/alert.js";
|
|
3
2
|
import { Button } from "../../../ui/button.js";
|
|
3
|
+
import { Alert, AlertDescription, AlertTitle } from "../../../ui/alert.js";
|
|
4
4
|
import { AlertCircle } from "lucide-react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import React from "react";
|
|
@@ -19,6 +19,10 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
19
19
|
import React from "react";
|
|
20
20
|
import { flexRender } from "@tanstack/react-table";
|
|
21
21
|
//#region src/components/registry/niko-table/core/data-table-structure.tsx
|
|
22
|
+
const ARIA_SORT = {
|
|
23
|
+
asc: "ascending",
|
|
24
|
+
desc: "descending"
|
|
25
|
+
};
|
|
22
26
|
const DataTableHeader = React.memo(function DataTableHeader({ className, sticky = true }) {
|
|
23
27
|
const { table, headerMinWidths, setColumnResizePreview, isCompact } = useDataTable();
|
|
24
28
|
const resizing = table?.options.enableColumnResizing ?? false;
|
|
@@ -39,8 +43,10 @@ const DataTableHeader = React.memo(function DataTableHeader({ className, sticky
|
|
|
39
43
|
}),
|
|
40
44
|
...getCommonPinningStyles(header.column, true, !isCompact)
|
|
41
45
|
};
|
|
46
|
+
const sorted = !header.isPlaceholder && header.column.getSortIndex() === 0 && header.column.getIsSorted();
|
|
42
47
|
return /* @__PURE__ */ jsxs(TableHead, {
|
|
43
48
|
"data-col-id": header.column.id,
|
|
49
|
+
"aria-sort": sorted ? ARIA_SORT[sorted] : void 0,
|
|
44
50
|
"data-numeric": header.column.columnDef.meta?.variant === "number" || void 0,
|
|
45
51
|
style: headerStyle,
|
|
46
52
|
className: cn(!isCompact && header.column.getIsPinned() && "bg-background", resizing && "relative overflow-hidden"),
|
|
@@ -117,7 +117,7 @@ function DataTable({ children, className, height, maxHeight, "aria-label": label
|
|
|
117
117
|
"aria-label": labelledBy ? void 0 : label,
|
|
118
118
|
"aria-labelledby": labelledBy,
|
|
119
119
|
tabIndex: 0,
|
|
120
|
-
className: cn("relative isolate w-full overflow-auto rounded-lg border", "[&::-webkit-scrollbar]:h-2.5 [&::-webkit-scrollbar]:w-2.5", "[&::-webkit-scrollbar-track]:bg-transparent", "[&::-webkit-scrollbar-thumb]:
|
|
120
|
+
className: cn("relative isolate w-full overflow-auto rounded-lg border", "[&::-webkit-scrollbar]:h-2.5 [&::-webkit-scrollbar]:w-2.5", "[&::-webkit-scrollbar-track]:bg-transparent", "[&::-webkit-scrollbar-thumb]:bg-border/40", "hover:[&::-webkit-scrollbar-thumb]:bg-border", "[&::-webkit-scrollbar-thumb:hover]:bg-border/80!", "scrollbar-thin scrollbar-thumb-border/40 scrollbar-track-transparent", "hover:scrollbar-thumb-border", parsed.safeClassName),
|
|
121
121
|
style: {
|
|
122
122
|
height: finalHeight,
|
|
123
123
|
maxHeight: finalMaxHeight
|
|
@@ -82,7 +82,7 @@ function TableColumnSortOptions({ column, table: propTable, variant: propVariant
|
|
|
82
82
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
83
83
|
className: "flex items-center gap-2",
|
|
84
84
|
children: [/* @__PURE__ */ jsx("span", { children: "Column Sort" }), showSortBadge && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
85
|
-
render: /* @__PURE__ */ jsx("span", { className: "flex size-4 cursor-help items-center justify-center
|
|
85
|
+
render: /* @__PURE__ */ jsx("span", { className: "flex size-4 cursor-help items-center justify-center bg-primary text-[10px] font-medium text-primary-foreground" }),
|
|
86
86
|
children: sortIndex + 1
|
|
87
87
|
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
88
88
|
side: "right",
|
|
@@ -159,7 +159,7 @@ function TableColumnSortMenu({ column, table: propTable, variant: propVariant, c
|
|
|
159
159
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
160
160
|
className: "relative flex items-center justify-center",
|
|
161
161
|
children: [/* @__PURE__ */ jsx(SortIcon, { className: "size-4" }), showSortBadge && /* @__PURE__ */ jsx("span", {
|
|
162
|
-
className: "absolute -top-1 -right-2 flex size-3 items-center justify-center
|
|
162
|
+
className: "absolute -top-1 -right-2 flex size-3 items-center justify-center bg-primary text-[9px] text-primary-foreground",
|
|
163
163
|
children: sortIndex + 1
|
|
164
164
|
})]
|
|
165
165
|
}), /* @__PURE__ */ jsx("span", {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { Badge } from "../../../ui/badge.js";
|
|
3
2
|
import { Button } from "../../../ui/button.js";
|
|
4
|
-
import {
|
|
3
|
+
import { Badge } from "../../../ui/badge.js";
|
|
5
4
|
import { Separator } from "../../../ui/separator.js";
|
|
5
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "../../../ui/command.js";
|
|
6
6
|
import { Popover, PopoverContent, PopoverTrigger } from "../../../ui/popover.js";
|
|
7
7
|
import { cn } from "../../../../lib/utils.js";
|
|
8
8
|
import { FILTER_OPERATORS, FILTER_VARIANTS, JOIN_OPERATORS } from "../lib/constants.js";
|
|
@@ -107,7 +107,7 @@ function TableFacetedFilter({ column, title, options = [], multiple, onValueChan
|
|
|
107
107
|
children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: trigger || /* @__PURE__ */ jsxs(Button, {
|
|
108
108
|
variant: "outline",
|
|
109
109
|
size: "sm",
|
|
110
|
-
className: "h-8
|
|
110
|
+
className: "h-8",
|
|
111
111
|
children: [
|
|
112
112
|
selectedValues?.size > 0 ? /* @__PURE__ */ jsx("div", {
|
|
113
113
|
role: "button",
|
|
@@ -168,7 +168,7 @@ function DataTableColumnResizeHandle({ header, isFlex = false, setResizePreview
|
|
|
168
168
|
}
|
|
169
169
|
},
|
|
170
170
|
className: "group/resize absolute top-0 right-0 z-10 flex h-full w-2 cursor-col-resize touch-none justify-end outline-none select-none",
|
|
171
|
-
children: /* @__PURE__ */ jsx("div", { className: cn("my-1.5 w-px
|
|
171
|
+
children: /* @__PURE__ */ jsx("div", { className: cn("my-1.5 w-px bg-border opacity-0 transition-all", "group-hover/resize:my-0 group-hover/resize:w-0.5 group-hover/resize:bg-primary group-hover/resize:opacity-100", "group-focus-visible/resize:my-0 group-focus-visible/resize:w-0.5 group-focus-visible/resize:bg-primary group-focus-visible/resize:opacity-100", isResizing && "my-0 w-0.5 bg-primary opacity-100") })
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Avatar, AvatarFallback, AvatarImage } from "../../ui/avatar.js";
|
|
2
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem,
|
|
2
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../../ui/dropdown-menu.js";
|
|
3
3
|
import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from "../../ui/sidebar.js";
|
|
4
4
|
import { BadgeCheckIcon, BellIcon, ChevronsUpDownIcon, CreditCardIcon, LogOutIcon, SparklesIcon } from "lucide-react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -34,25 +34,22 @@ function NavUser({ user }) {
|
|
|
34
34
|
align: "end",
|
|
35
35
|
sideOffset: 4,
|
|
36
36
|
children: [
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
-
className: "
|
|
39
|
-
children: /* @__PURE__ */ jsxs(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
className: "
|
|
46
|
-
children:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
className: "truncate text-xs",
|
|
51
|
-
children: user.email
|
|
52
|
-
})]
|
|
37
|
+
/* @__PURE__ */ jsxs("div", {
|
|
38
|
+
className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm",
|
|
39
|
+
children: [/* @__PURE__ */ jsxs(Avatar, { children: [/* @__PURE__ */ jsx(AvatarImage, {
|
|
40
|
+
src: user.avatar,
|
|
41
|
+
alt: user.name
|
|
42
|
+
}), /* @__PURE__ */ jsx(AvatarFallback, { children: "CN" })] }), /* @__PURE__ */ jsxs("div", {
|
|
43
|
+
className: "grid flex-1 text-left text-sm leading-tight",
|
|
44
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
45
|
+
className: "truncate font-medium",
|
|
46
|
+
children: user.name
|
|
47
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
48
|
+
className: "truncate text-xs",
|
|
49
|
+
children: user.email
|
|
53
50
|
})]
|
|
54
|
-
})
|
|
55
|
-
})
|
|
51
|
+
})]
|
|
52
|
+
}),
|
|
56
53
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
57
54
|
/* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [/* @__PURE__ */ jsx(SparklesIcon, {}), "Upgrade to Pro"] }) }),
|
|
58
55
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
//#region src/components/siyahi/page-
|
|
3
|
-
export interface
|
|
2
|
+
//#region src/components/siyahi/page-header.d.ts
|
|
3
|
+
export interface PageHeaderProps {
|
|
4
4
|
/** A short line above the title in the mono face and the link colour, such as the app or a section name. */
|
|
5
5
|
eyebrow?: ReactNode;
|
|
6
6
|
/** The page's h1. */
|
|
@@ -19,5 +19,5 @@ export interface PageHeroProps {
|
|
|
19
19
|
* the actions at the right, and a hairline under it all. One per page, above everything else; a section uses
|
|
20
20
|
* PageSection.
|
|
21
21
|
*/
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function PageHeader({ eyebrow, title, lead, detail, actions, mark }: PageHeaderProps): import("react").JSX.Element;
|
|
23
23
|
//#endregion
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
//#region src/components/siyahi/page-
|
|
2
|
+
//#region src/components/siyahi/page-header.tsx
|
|
3
3
|
/**
|
|
4
4
|
* The masthead at the top of a page: a small mark and eyebrow, the title, one muted line saying what the page is,
|
|
5
5
|
* the actions at the right, and a hairline under it all. One per page, above everything else; a section uses
|
|
6
6
|
* PageSection.
|
|
7
7
|
*/
|
|
8
|
-
function
|
|
8
|
+
function PageHeader({ eyebrow, title, lead, detail, actions, mark }) {
|
|
9
9
|
return /* @__PURE__ */ jsxs("header", {
|
|
10
|
-
"data-slot": "page-
|
|
10
|
+
"data-slot": "page-header",
|
|
11
11
|
className: "flex flex-wrap items-end justify-between gap-x-6 gap-y-3 border-b pb-4",
|
|
12
12
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
13
13
|
className: "flex min-w-0 flex-col gap-1",
|
|
@@ -40,4 +40,4 @@ function PageHero({ eyebrow, title, lead, detail, actions, mark }) {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
//#endregion
|
|
43
|
-
export {
|
|
43
|
+
export { PageHeader };
|
|
@@ -3,11 +3,14 @@ import { ReactNode } from "react";
|
|
|
3
3
|
declare const COLUMNS: {
|
|
4
4
|
readonly 1: "";
|
|
5
5
|
readonly 2: "@2xl/panels:grid-cols-2";
|
|
6
|
-
readonly 3: "@2xl/panels:grid-cols-
|
|
6
|
+
readonly 3: "@2xl/panels:grid-cols-3";
|
|
7
7
|
readonly 4: "@2xl/panels:grid-cols-2 @5xl/panels:grid-cols-4";
|
|
8
8
|
};
|
|
9
9
|
export interface PanelGridProps {
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Blocks across from a 42rem grid, so three short ones fit a reading column (an article's 55rem); 4 goes two across
|
|
12
|
+
* there and four from 64rem. Below 42rem they sit one under another.
|
|
13
|
+
*/
|
|
11
14
|
columns?: keyof typeof COLUMNS | undefined;
|
|
12
15
|
children: ReactNode;
|
|
13
16
|
className?: string | undefined;
|
|
@@ -26,7 +26,7 @@ function RangePosition({ low, high, value, lowLabel = "Low", highLabel = "High",
|
|
|
26
26
|
style: { width: at }
|
|
27
27
|
}), /* @__PURE__ */ jsx("div", {
|
|
28
28
|
"data-slot": "range-thumb",
|
|
29
|
-
className: cn("absolute top-1/2 -translate-1/2
|
|
29
|
+
className: cn("absolute top-1/2 -translate-1/2 border-2 border-foreground bg-card", variant === "full" ? "size-3.5" : "size-2.5"),
|
|
30
30
|
style: { left: at }
|
|
31
31
|
})]
|
|
32
32
|
});
|