@siyahi/ui 0.1.9-next.2 → 0.1.9-next.21

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.
Files changed (196) hide show
  1. package/DESIGN.md +30 -0
  2. package/README.md +82 -176
  3. package/THIRD_PARTY_NOTICES.md +11 -11
  4. package/agents/examples/accordion.tsx +39 -0
  5. package/agents/examples/alert.tsx +23 -0
  6. package/agents/examples/app-sidebar.tsx +38 -0
  7. package/agents/examples/avatar.tsx +14 -0
  8. package/agents/examples/badge.tsx +18 -0
  9. package/agents/examples/bar-list-labels.tsx +22 -0
  10. package/agents/examples/bar-list-sides.tsx +38 -0
  11. package/agents/examples/bar-list.tsx +24 -0
  12. package/agents/examples/breadcrumb.tsx +28 -0
  13. package/agents/examples/button-states.tsx +23 -0
  14. package/agents/examples/button.tsx +21 -0
  15. package/agents/examples/calendar.tsx +15 -0
  16. package/agents/examples/callout.tsx +33 -0
  17. package/agents/examples/card.tsx +34 -0
  18. package/agents/examples/change-bar.tsx +104 -0
  19. package/agents/examples/chart-area.tsx +39 -0
  20. package/agents/examples/chart-bar-flows.tsx +32 -0
  21. package/agents/examples/chart-bar-hourly.tsx +28 -0
  22. package/agents/examples/chart-bar-losses.tsx +29 -0
  23. package/agents/examples/chart-bar-sectors.tsx +72 -0
  24. package/agents/examples/chart-bar-years.tsx +40 -0
  25. package/agents/examples/chart-bar.tsx +56 -0
  26. package/agents/examples/chart-category-ticks.tsx +50 -0
  27. package/agents/examples/chart-line-events.tsx +47 -0
  28. package/agents/examples/chart-line-timeline.tsx +41 -0
  29. package/agents/examples/chart-line.tsx +57 -0
  30. package/agents/examples/code-block.tsx +38 -0
  31. package/agents/examples/collapsible.tsx +16 -0
  32. package/agents/examples/command.tsx +27 -0
  33. package/agents/examples/context-menu.tsx +15 -0
  34. package/agents/examples/copy-button.tsx +8 -0
  35. package/agents/examples/data-bar.tsx +121 -0
  36. package/agents/examples/data-table-compact.tsx +95 -0
  37. package/agents/examples/data-table-filters.tsx +103 -0
  38. package/agents/examples/data-table.tsx +98 -0
  39. package/agents/examples/delta.tsx +13 -0
  40. package/agents/examples/dialog.tsx +28 -0
  41. package/agents/examples/distribution-bar-budget.tsx +30 -0
  42. package/agents/examples/distribution-bar-tug.tsx +72 -0
  43. package/agents/examples/dropdown-menu.tsx +31 -0
  44. package/agents/examples/formatters.tsx +42 -0
  45. package/agents/examples/heatmap-calendar.tsx +60 -0
  46. package/agents/examples/heatmap-status.tsx +57 -0
  47. package/agents/examples/heatmap-weekday.tsx +75 -0
  48. package/agents/examples/input-states.tsx +33 -0
  49. package/agents/examples/input.tsx +17 -0
  50. package/agents/examples/local-time.tsx +14 -0
  51. package/agents/examples/metric-strip.tsx +46 -0
  52. package/agents/examples/overview-dashboard.tsx +18 -0
  53. package/agents/examples/page-hero.tsx +38 -0
  54. package/agents/examples/page-section.tsx +52 -0
  55. package/agents/examples/popover.tsx +23 -0
  56. package/agents/examples/price-chart.tsx +32 -0
  57. package/agents/examples/progress-tone.tsx +28 -0
  58. package/agents/examples/progress.tsx +10 -0
  59. package/agents/examples/range-position-table.tsx +101 -0
  60. package/agents/examples/range-position.tsx +53 -0
  61. package/agents/examples/scroll-area.tsx +20 -0
  62. package/agents/examples/section-cards-select.tsx +30 -0
  63. package/agents/examples/section-cards-trend.tsx +30 -0
  64. package/agents/examples/section-cards.tsx +48 -0
  65. package/agents/examples/select.tsx +27 -0
  66. package/agents/examples/separator.tsx +13 -0
  67. package/agents/examples/sheet.tsx +15 -0
  68. package/agents/examples/skeleton.tsx +11 -0
  69. package/agents/examples/slider.tsx +5 -0
  70. package/agents/examples/surfaces.tsx +116 -0
  71. package/agents/examples/table.tsx +50 -0
  72. package/agents/examples/tabs.tsx +16 -0
  73. package/agents/examples/target-rows.tsx +70 -0
  74. package/agents/examples/toggle-group.tsx +12 -0
  75. package/agents/examples/toggle.tsx +11 -0
  76. package/agents/examples/tooltip.tsx +13 -0
  77. package/agents/examples/treemap.tsx +88 -0
  78. package/agents/manifest.json +1081 -0
  79. package/agents/report-rules.json +7 -0
  80. package/dist/components/registry/charts/area-chart-card.js +25 -7
  81. package/dist/components/registry/charts/bar-chart-card.d.ts +0 -1
  82. package/dist/components/registry/charts/bar-chart-card.js +40 -26
  83. package/dist/components/registry/charts/line-chart-card.js +2 -2
  84. package/dist/components/registry/dashboard-01/section-cards.d.ts +2 -0
  85. package/dist/components/registry/dashboard-01/section-cards.js +42 -35
  86. package/dist/components/registry/dashboardcn/bar-list.js +18 -11
  87. package/dist/components/registry/dashboardcn/distribution-bar.js +1 -1
  88. package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +29 -0
  89. package/dist/components/registry/dashboardcn/kpi-row-card.js +81 -0
  90. package/dist/components/registry/dashboardcn/sparkline.d.ts +22 -0
  91. package/dist/components/registry/dashboardcn/sparkline.js +117 -0
  92. package/dist/components/registry/heatmap/calendar-heatmap.d.ts +4 -2
  93. package/dist/components/registry/heatmap/calendar-heatmap.js +74 -33
  94. package/dist/components/registry/heatmap/status-heatmap.d.ts +5 -3
  95. package/dist/components/registry/heatmap/status-heatmap.js +37 -15
  96. package/dist/components/registry/heatmap/weekday-heatmap.d.ts +9 -3
  97. package/dist/components/registry/heatmap/weekday-heatmap.js +82 -47
  98. package/dist/components/registry/niko-table/core/data-table-context.d.ts +18 -1
  99. package/dist/components/registry/niko-table/core/data-table-context.js +7 -1
  100. package/dist/components/registry/niko-table/core/data-table-grouped-row.js +3 -1
  101. package/dist/components/registry/niko-table/core/data-table-root.js +39 -4
  102. package/dist/components/registry/niko-table/core/data-table-structure.js +17 -12
  103. package/dist/components/registry/niko-table/core/data-table.d.ts +2 -2
  104. package/dist/components/registry/niko-table/core/data-table.js +5 -1
  105. package/dist/components/registry/niko-table/filters/table-faceted-filter.js +4 -4
  106. package/dist/components/registry/niko-table/filters/table-search-filter.js +1 -1
  107. package/dist/components/registry/niko-table/lib/flex-columns.d.ts +1 -1
  108. package/dist/components/registry/niko-table/lib/flex-columns.js +3 -3
  109. package/dist/components/registry/niko-table/lib/styles.d.ts +1 -1
  110. package/dist/components/registry/niko-table/lib/styles.js +3 -3
  111. package/dist/components/registry/niko-table/types/index.d.ts +9 -0
  112. package/dist/components/registry/niko-table/ui/table.js +2 -2
  113. package/dist/components/registry/sidebar-07/app-sidebar.d.ts +1 -1
  114. package/dist/components/registry/sidebar-07/app-sidebar.js +3 -1
  115. package/dist/components/registry/sidebar-07/nav-main.d.ts +2 -1
  116. package/dist/components/registry/sidebar-07/nav-main.js +16 -3
  117. package/dist/components/siyahi/callout.d.ts +24 -0
  118. package/dist/components/siyahi/callout.js +40 -0
  119. package/dist/components/siyahi/change-bar.d.ts +21 -0
  120. package/dist/components/siyahi/change-bar.js +35 -0
  121. package/dist/components/siyahi/data-bar.d.ts +19 -0
  122. package/dist/components/siyahi/data-bar.js +29 -0
  123. package/dist/components/siyahi/data-table-compact-columns-toggle.d.ts +4 -0
  124. package/dist/components/siyahi/data-table-compact-columns-toggle.js +19 -0
  125. package/dist/components/siyahi/data-table-footnote.d.ts +12 -0
  126. package/dist/components/siyahi/data-table-footnote.js +35 -0
  127. package/dist/components/siyahi/default-sidebar-open.d.ts +8 -0
  128. package/dist/components/siyahi/default-sidebar-open.js +13 -0
  129. package/dist/components/siyahi/page-hero.d.ts +25 -0
  130. package/dist/components/siyahi/page-hero.js +41 -0
  131. package/dist/components/siyahi/page-section.d.ts +4 -1
  132. package/dist/components/siyahi/page-section.js +6 -3
  133. package/dist/components/siyahi/page-toc.d.ts +20 -0
  134. package/dist/components/siyahi/page-toc.js +76 -0
  135. package/dist/components/siyahi/panel-grid.d.ts +22 -0
  136. package/dist/components/siyahi/panel-grid.js +34 -0
  137. package/dist/components/siyahi/quote.d.ts +12 -0
  138. package/dist/components/siyahi/quote.js +23 -0
  139. package/dist/components/siyahi/range-position.d.ts +24 -0
  140. package/dist/components/siyahi/range-position.js +105 -0
  141. package/dist/components/siyahi/siyahi-provider.d.ts +13 -2
  142. package/dist/components/siyahi/siyahi-provider.js +17 -4
  143. package/dist/components/siyahi/target-rows.d.ts +34 -0
  144. package/dist/components/siyahi/target-rows.js +97 -0
  145. package/dist/components/siyahi/treemap.d.ts +4 -1
  146. package/dist/components/siyahi/treemap.js +78 -28
  147. package/dist/components/siyahi/warning-alert.d.ts +10 -0
  148. package/dist/components/siyahi/warning-alert.js +20 -0
  149. package/dist/components/ui/accordion.js +5 -5
  150. package/dist/components/ui/alert.js +2 -2
  151. package/dist/components/ui/badge.js +1 -1
  152. package/dist/components/ui/breadcrumb.js +2 -2
  153. package/dist/components/ui/button.js +10 -10
  154. package/dist/components/ui/calendar.js +1 -1
  155. package/dist/components/ui/card.js +4 -4
  156. package/dist/components/ui/chart.js +1 -1
  157. package/dist/components/ui/code-block.js +13 -12
  158. package/dist/components/ui/command.js +7 -6
  159. package/dist/components/ui/context-menu.js +7 -7
  160. package/dist/components/ui/dialog.js +5 -5
  161. package/dist/components/ui/dropdown-menu.js +8 -8
  162. package/dist/components/ui/input-group.js +11 -11
  163. package/dist/components/ui/input.js +1 -1
  164. package/dist/components/ui/popover.js +3 -3
  165. package/dist/components/ui/progress.js +1 -1
  166. package/dist/components/ui/select.js +6 -6
  167. package/dist/components/ui/sheet.js +5 -5
  168. package/dist/components/ui/sidebar.js +17 -18
  169. package/dist/components/ui/skeleton.js +1 -1
  170. package/dist/components/ui/slider.js +2 -2
  171. package/dist/components/ui/table.js +2 -2
  172. package/dist/components/ui/tabs.js +2 -2
  173. package/dist/components/ui/textarea.js +1 -1
  174. package/dist/components/ui/toggle-group.js +2 -2
  175. package/dist/components/ui/toggle.js +4 -4
  176. package/dist/components/ui/tooltip.js +2 -2
  177. package/dist/index.d.ts +21 -7
  178. package/dist/index.js +18 -4
  179. package/dist/lib/chart-frame.d.ts +25 -7
  180. package/dist/lib/chart-frame.js +251 -127
  181. package/dist/lib/chart-series.d.ts +12 -6
  182. package/dist/lib/compact-columns.d.ts +19 -0
  183. package/dist/lib/compact-columns.js +55 -0
  184. package/dist/lib/format.d.ts +7 -2
  185. package/dist/lib/format.js +54 -16
  186. package/dist/lib/heatmap-navigation.d.ts +8 -0
  187. package/dist/lib/heatmap-navigation.js +49 -0
  188. package/dist/lib/treemap.js +6 -1
  189. package/dist/lib/use-element-width.d.ts +5 -0
  190. package/dist/lib/use-element-width.js +15 -0
  191. package/package.json +4 -1
  192. package/registry.lock.json +16 -0
  193. package/report.css +33 -32
  194. package/styles/siyahi.css +221 -39
  195. package/dist/lib/recharts.d.ts +0 -2
  196. package/dist/lib/recharts.js +0 -1
@@ -0,0 +1,41 @@
1
+ import { LineChartCard, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // A sar sample every 10 minutes from 15:00; the numbers are made up for the catalogue.
4
+ const data = [
5
+ { minute: 0, used: 4.1, anon: 2.9 },
6
+ { minute: 10, used: 4.3, anon: 3.1 },
7
+ { minute: 20, used: 4.6, anon: 3.4 },
8
+ { minute: 30, used: 5.2, anon: 4.2 },
9
+ { minute: 40, used: 7.8, anon: 7.1 },
10
+ { minute: 50, used: 8.1, anon: 7.6 },
11
+ { minute: 60, used: 6.2, anon: 5.3 },
12
+ { minute: 70, used: 4.4, anon: 3.2 },
13
+ ];
14
+
15
+ const series: ChartSeries<(typeof data)[number]> = [
16
+ { key: "used", label: "Used", color: "var(--chart-1)" },
17
+ { key: "anon", label: "Anon", color: "var(--chart-2)" },
18
+ ];
19
+
20
+ const clock = (minute: number) => `${Math.floor(15 + minute / 60)}:${String(minute % 60).padStart(2, "0")}`;
21
+
22
+ export default function ChartLineTimelineExample() {
23
+ return (
24
+ <LineChartCard
25
+ title="Memory in use, GiB"
26
+ description="sar -r. Used excludes cache; anon is program memory."
27
+ data={data}
28
+ xKey="minute"
29
+ // Ticks on both ends of the domain: the first sits at the plot's left edge.
30
+ xDomain={[0, 70]}
31
+ xTicks={[0, 10, 20, 30, 40, 50, 60, 70]}
32
+ xFormatter={clock}
33
+ xTooltipFormatter={(minute) => `${clock(minute)} IST, 10-min average`}
34
+ series={series}
35
+ valueFormatter={(v) => v.toFixed(1)}
36
+ yTickFormatter={(v) => v.toFixed(0)}
37
+ curve="linear"
38
+ height={192}
39
+ />
40
+ );
41
+ }
@@ -0,0 +1,57 @@
1
+ import { useState } from "react";
2
+ import { LineChartCard, ToggleGroup, ToggleGroupItem, useFormat, type ChartSeries } from "@siyahi/ui";
3
+
4
+ const cumulative = [
5
+ { month: "May", portfolio: 0.012, index: 0.008 },
6
+ { month: "Jun", portfolio: 0.021, index: 0.015 },
7
+ { month: "Jul", portfolio: 0.034, index: 0.029 },
8
+ { month: "Aug", portfolio: -0.006, index: 0.004 },
9
+ { month: "Sep", portfolio: 0.041, index: 0.031 },
10
+ { month: "Oct", portfolio: 0.052, index: 0.036 },
11
+ ];
12
+
13
+ const monthly = [
14
+ { month: "May", portfolio: 0.012, index: 0.008 },
15
+ { month: "Jun", portfolio: 0.009, index: 0.007 },
16
+ { month: "Jul", portfolio: 0.013, index: 0.014 },
17
+ { month: "Aug", portfolio: -0.039, index: -0.024 },
18
+ { month: "Sep", portfolio: 0.047, index: 0.027 },
19
+ { month: "Oct", portfolio: 0.011, index: 0.005 },
20
+ ];
21
+
22
+ const series: ChartSeries<(typeof cumulative)[number]> = [
23
+ { key: "portfolio", label: "Portfolio", color: "var(--chart-1)" },
24
+ { key: "index", label: "Nifty 50", color: "var(--chart-2)" },
25
+ ];
26
+
27
+ export default function ChartLineExample() {
28
+ const { pct } = useFormat();
29
+ const [mode, setMode] = useState("cumulative");
30
+ return (
31
+ <LineChartCard
32
+ title="Return against the index"
33
+ description={mode === "cumulative" ? "Cumulative, from the start of May" : "Each month on its own"}
34
+ action={
35
+ <ToggleGroup
36
+ value={[mode]}
37
+ onValueChange={([next]) => {
38
+ // Pressing the selected mode again would leave none selected; keep it.
39
+ if (next) setMode(next);
40
+ }}
41
+ variant="outline"
42
+ size="sm"
43
+ aria-label="Mode"
44
+ >
45
+ <ToggleGroupItem value="cumulative">Cumulative return</ToggleGroupItem>
46
+ <ToggleGroupItem value="monthly">Monthly return</ToggleGroupItem>
47
+ </ToggleGroup>
48
+ }
49
+ data={mode === "cumulative" ? cumulative : monthly}
50
+ xKey="month"
51
+ series={series}
52
+ // A formatter goes in as it is: the card calls it with the value alone.
53
+ valueFormatter={pct}
54
+ height={256}
55
+ />
56
+ );
57
+ }
@@ -0,0 +1,38 @@
1
+ import {
2
+ CodeBlock,
3
+ CodeBlockActions,
4
+ CodeBlockContent,
5
+ CodeBlockCopyButton,
6
+ CodeBlockHeader,
7
+ CodeBlockTitle,
8
+ } from "@siyahi/ui";
9
+
10
+ const CHECK = "openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null";
11
+
12
+ const LOG = Array.from(
13
+ { length: 24 },
14
+ (_, i) =>
15
+ `19:${String(33 + Math.floor(i / 4)).padStart(2, "0")}:${String((i * 15) % 60).padStart(2, "0")} memory.pressure some avg10=${(12 + i * 3.1).toFixed(2)}`,
16
+ ).join("\n");
17
+
18
+ export default function CodeBlockExample() {
19
+ return (
20
+ <div className="flex flex-col gap-4">
21
+ <CodeBlock>
22
+ <CodeBlockHeader>
23
+ <CodeBlockTitle>Show the chain a server sends</CodeBlockTitle>
24
+ <CodeBlockActions>
25
+ <CodeBlockCopyButton value={CHECK} />
26
+ </CodeBlockActions>
27
+ </CodeBlockHeader>
28
+ <CodeBlockContent wrap>{CHECK}</CodeBlockContent>
29
+ </CodeBlock>
30
+ <CodeBlock size="sm">
31
+ <CodeBlockActions>
32
+ <CodeBlockCopyButton value={LOG} />
33
+ </CodeBlockActions>
34
+ <CodeBlockContent className="max-h-48">{LOG}</CodeBlockContent>
35
+ </CodeBlock>
36
+ </div>
37
+ );
38
+ }
@@ -0,0 +1,16 @@
1
+ import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from "@siyahi/ui";
2
+ import { ChevronsUpDownIcon } from "lucide-react";
3
+
4
+ export default function CollapsibleExample() {
5
+ return (
6
+ <Collapsible className="flex max-w-sm flex-col gap-2">
7
+ <CollapsibleTrigger render={<Button variant="outline" className="w-fit" />}>
8
+ <ChevronsUpDownIcon />
9
+ How lots are matched
10
+ </CollapsibleTrigger>
11
+ <CollapsibleContent className="text-muted-foreground">
12
+ Sells are matched to the oldest buy first, as the tax rules require.
13
+ </CollapsibleContent>
14
+ </Collapsible>
15
+ );
16
+ }
@@ -0,0 +1,27 @@
1
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@siyahi/ui";
2
+ import { ChartLineIcon, LandmarkIcon, WalletIcon } from "lucide-react";
3
+
4
+ export default function CommandExample() {
5
+ return (
6
+ <Command className="rounded-lg border">
7
+ <CommandInput placeholder="Jump to a page" />
8
+ <CommandList>
9
+ <CommandEmpty>No page matches.</CommandEmpty>
10
+ <CommandGroup heading="Pages">
11
+ <CommandItem>
12
+ <WalletIcon />
13
+ Holdings
14
+ </CommandItem>
15
+ <CommandItem>
16
+ <ChartLineIcon />
17
+ Realized
18
+ </CommandItem>
19
+ <CommandItem>
20
+ <LandmarkIcon />
21
+ Cash flow
22
+ </CommandItem>
23
+ </CommandGroup>
24
+ </CommandList>
25
+ </Command>
26
+ );
27
+ }
@@ -0,0 +1,15 @@
1
+ import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "@siyahi/ui";
2
+
3
+ export default function ContextMenuExample() {
4
+ return (
5
+ <ContextMenu>
6
+ <ContextMenuTrigger className="flex h-24 w-full items-center justify-center rounded-lg border border-dashed text-muted-foreground">
7
+ Right-click or long-press here
8
+ </ContextMenuTrigger>
9
+ <ContextMenuContent>
10
+ <ContextMenuItem>Copy symbol</ContextMenuItem>
11
+ <ContextMenuItem>Open chart</ContextMenuItem>
12
+ </ContextMenuContent>
13
+ </ContextMenu>
14
+ );
15
+ }
@@ -0,0 +1,8 @@
1
+ import { CopyButton } from "@siyahi/ui";
2
+
3
+ // Every command on a setup page, for a reader who wants them all at once.
4
+ const ALL = ["brew install node@24", "corepack enable", "pnpm install"].join("\n");
5
+
6
+ export default function CopyButtonExample() {
7
+ return <CopyButton value={ALL} label="Copy all" />;
8
+ }
@@ -0,0 +1,121 @@
1
+ import {
2
+ Card,
3
+ CardContent,
4
+ CardDescription,
5
+ CardHeader,
6
+ CardTitle,
7
+ DataBar,
8
+ DataTable,
9
+ DataTableBody,
10
+ DataTableHeader,
11
+ DataTableRoot,
12
+ DataTableSortHeader,
13
+ Sparkline,
14
+ useFormat,
15
+ type DataTableColumnDef,
16
+ } from "@siyahi/ui";
17
+
18
+ interface Holding {
19
+ symbol: string;
20
+ value: number;
21
+ gain: number;
22
+ /** Closing prices over the last ten sessions, oldest first. */
23
+ closes: number[];
24
+ }
25
+
26
+ const holdings: Holding[] = [
27
+ { symbol: "ITC", value: 276000, gain: -18400, closes: [478, 474, 470, 471, 466, 463, 465, 461, 459, 460] },
28
+ {
29
+ symbol: "HDFCBANK",
30
+ value: 262500,
31
+ gain: 21300,
32
+ closes: [1712, 1718, 1726, 1720, 1731, 1744, 1739, 1748, 1752, 1750],
33
+ },
34
+ {
35
+ symbol: "ICICIBANK",
36
+ value: 258000,
37
+ gain: 44100,
38
+ closes: [1250, 1262, 1258, 1271, 1266, 1280, 1284, 1279, 1288, 1290],
39
+ },
40
+ { symbol: "NIFTYBEES", value: 255600, gain: 12800, closes: [281, 282, 280, 283, 284, 283, 285, 284, 286, 284] },
41
+ { symbol: "INFY", value: 224400, gain: 30900, closes: [1820, 1834, 1829, 1841, 1852, 1848, 1860, 1855, 1866, 1870] },
42
+ { symbol: "TCS", value: 166000, gain: -2600, closes: [4180, 4172, 4165, 4170, 4158, 4150, 4161, 4155, 4148, 4150] },
43
+ ];
44
+
45
+ // Each bar is a share of its column's largest figure, so the rows draw to one scale.
46
+ const largestValue = Math.max(...holdings.map((h) => h.value));
47
+ const largestGain = Math.max(...holdings.map((h) => Math.abs(h.gain)));
48
+
49
+ function Money({ amount }: { amount: number }) {
50
+ return useFormat().money(amount);
51
+ }
52
+
53
+ const header = () => <DataTableSortHeader />;
54
+
55
+ const columns: DataTableColumnDef<Holding>[] = [
56
+ { accessorKey: "symbol", header, size: 120, meta: { label: "Symbol" } },
57
+ {
58
+ accessorKey: "value",
59
+ header,
60
+ size: 170,
61
+ meta: { label: "Value", variant: "number" },
62
+ cell: ({ row }) => (
63
+ <DataBar value={row.original.value} max={largestValue}>
64
+ <Money amount={row.original.value} />
65
+ </DataBar>
66
+ ),
67
+ },
68
+ {
69
+ accessorKey: "gain",
70
+ header,
71
+ size: 170,
72
+ meta: { label: "Gain", variant: "number" },
73
+ cell: ({ row }) => (
74
+ <DataBar value={row.original.gain} max={largestGain} tone="sign">
75
+ <Money amount={row.original.gain} />
76
+ </DataBar>
77
+ ),
78
+ },
79
+ {
80
+ id: "closes",
81
+ header: "10 days",
82
+ size: 110,
83
+ enableSorting: false,
84
+ cell: ({ row }) => {
85
+ const { closes } = row.original;
86
+ const rising = (closes.at(-1) ?? 0) >= (closes[0] ?? 0);
87
+ return (
88
+ <Sparkline
89
+ data={closes}
90
+ variant="line"
91
+ color={rising ? "var(--positive)" : "var(--negative)"}
92
+ animate={false}
93
+ className="h-5 w-20"
94
+ />
95
+ );
96
+ },
97
+ },
98
+ ];
99
+
100
+ export default function DataBarExample() {
101
+ return (
102
+ <Card>
103
+ <CardHeader>
104
+ <CardTitle>Holdings</CardTitle>
105
+ <CardDescription>Bars give each figure's size against the column's largest</CardDescription>
106
+ </CardHeader>
107
+ <CardContent>
108
+ <DataTableRoot
109
+ data={holdings}
110
+ columns={columns}
111
+ initialState={{ columnPinning: { start: ["symbol"], end: [] } }}
112
+ >
113
+ <DataTable>
114
+ <DataTableHeader />
115
+ <DataTableBody />
116
+ </DataTable>
117
+ </DataTableRoot>
118
+ </CardContent>
119
+ </Card>
120
+ );
121
+ }
@@ -0,0 +1,95 @@
1
+ import {
2
+ Card,
3
+ CardContent,
4
+ CardDescription,
5
+ CardHeader,
6
+ CardTitle,
7
+ DataTable,
8
+ DataTableBody,
9
+ DataTableCompactColumnsToggle,
10
+ DataTableHeader,
11
+ DataTableRoot,
12
+ DataTableRowCount,
13
+ DataTableSortHeader,
14
+ DataTableToolbarSection,
15
+ Delta,
16
+ useDataTable,
17
+ useFormat,
18
+ type DataTableColumnDef,
19
+ } from "@siyahi/ui";
20
+
21
+ interface Holding {
22
+ symbol: string;
23
+ sector: string;
24
+ quantity: number;
25
+ value: number;
26
+ change: number;
27
+ }
28
+
29
+ const holdings: Holding[] = [
30
+ { symbol: "INFY", sector: "IT", quantity: 120, value: 224400, change: 0.018 },
31
+ { symbol: "HDFCBANK", sector: "Banks", quantity: 150, value: 262500, change: -0.006 },
32
+ { symbol: "TCS", sector: "IT", quantity: 40, value: 166000, change: 0.004 },
33
+ { symbol: "ITC", sector: "Fast Moving Consumer Goods", quantity: 600, value: 276000, change: -0.012 },
34
+ ];
35
+
36
+ const header = () => <DataTableSortHeader />;
37
+
38
+ // While the Day column is hidden to fit, the day's move rides under the value it belongs to.
39
+ function ValueCell({ holding }: { holding: Holding }) {
40
+ const format = useFormat();
41
+ const { compactColumns } = useDataTable<Holding>();
42
+ if (!compactColumns?.hidden.has("change")) return format.money(holding.value);
43
+ return (
44
+ <div className="flex flex-col items-end">
45
+ {format.money(holding.value)}
46
+ <Delta value={holding.change} />
47
+ </div>
48
+ );
49
+ }
50
+
51
+ const columns: DataTableColumnDef<Holding>[] = [
52
+ { accessorKey: "symbol", header, size: 140, meta: { label: "Symbol", compact: true } },
53
+ { accessorKey: "sector", header, size: 120, meta: { label: "Sector" } },
54
+ { accessorKey: "quantity", header, size: 100, meta: { label: "Qty", variant: "number" } },
55
+ {
56
+ accessorKey: "value",
57
+ header,
58
+ size: 140,
59
+ meta: { label: "Value", variant: "number", compact: true },
60
+ cell: ({ row }) => <ValueCell holding={row.original} />,
61
+ },
62
+ {
63
+ accessorKey: "change",
64
+ header,
65
+ size: 110,
66
+ meta: { label: "Day", variant: "number" },
67
+ cell: ({ row }) => <Delta value={row.original.change} />,
68
+ },
69
+ ];
70
+
71
+ export default function DataTableCompactExample() {
72
+ return (
73
+ <Card>
74
+ <CardHeader>
75
+ <CardTitle>Holdings on a phone</CardTitle>
76
+ <CardDescription>
77
+ Symbol and value are the key columns. When the columns do not fit, the others hide from the right, and the
78
+ day's move rides under the value once its column is gone; All columns brings back the rest
79
+ </CardDescription>
80
+ </CardHeader>
81
+ <CardContent>
82
+ <DataTableRoot data={holdings} columns={columns}>
83
+ <DataTableToolbarSection>
84
+ <DataTableCompactColumnsToggle />
85
+ <DataTableRowCount unit="holdings" />
86
+ </DataTableToolbarSection>
87
+ <DataTable aria-label="Holdings on a phone">
88
+ <DataTableHeader />
89
+ <DataTableBody />
90
+ </DataTable>
91
+ </DataTableRoot>
92
+ </CardContent>
93
+ </Card>
94
+ );
95
+ }
@@ -0,0 +1,103 @@
1
+ import {
2
+ Button,
3
+ Card,
4
+ CardContent,
5
+ CardDescription,
6
+ CardHeader,
7
+ CardTitle,
8
+ DataTable,
9
+ DataTableBody,
10
+ DataTableFacetedFilter,
11
+ DataTableHeader,
12
+ DataTableRoot,
13
+ DataTableRowCount,
14
+ DataTableSearchFilter,
15
+ DataTableSortHeader,
16
+ DataTableToolbarSection,
17
+ Sheet,
18
+ SheetClose,
19
+ SheetContent,
20
+ SheetDescription,
21
+ SheetFooter,
22
+ SheetHeader,
23
+ SheetTitle,
24
+ SheetTrigger,
25
+ useDataTable,
26
+ type DataTableColumnDef,
27
+ } from "@siyahi/ui";
28
+
29
+ interface Holding {
30
+ symbol: string;
31
+ sector: string;
32
+ broker: string;
33
+ }
34
+ const data: Holding[] = [
35
+ { symbol: "INFY", sector: "Information technology", broker: "Kite" },
36
+ { symbol: "HDFCBANK", sector: "Banks", broker: "Dhan" },
37
+ { symbol: "TCS", sector: "Information technology", broker: "Dhan" },
38
+ ];
39
+ const header = () => <DataTableSortHeader />;
40
+ const columns: DataTableColumnDef<Holding>[] = [
41
+ { accessorKey: "symbol", header, size: 140, meta: { label: "Instrument" } },
42
+ { accessorKey: "sector", header, meta: { label: "Sector" } },
43
+ { accessorKey: "broker", header, meta: { label: "Broker" } },
44
+ ];
45
+
46
+ function Filters() {
47
+ const { table, isCompact } = useDataTable<Holding>();
48
+ const active = table.state.columnFilters.length;
49
+ const controls = (
50
+ <div className="flex flex-wrap gap-2">
51
+ <DataTableFacetedFilter accessorKey="sector" title="Sector" />
52
+ <DataTableFacetedFilter accessorKey="broker" title="Broker" />
53
+ </div>
54
+ );
55
+ if (!isCompact) return controls;
56
+ return (
57
+ <Sheet>
58
+ <SheetTrigger render={<Button variant="outline" size="sm" />}>Filters{active ? ` (${active})` : ""}</SheetTrigger>
59
+ <SheetContent>
60
+ <SheetHeader>
61
+ <SheetTitle>Holding filters</SheetTitle>
62
+ <SheetDescription>Selections stay applied when this panel closes.</SheetDescription>
63
+ </SheetHeader>
64
+ <div className="overflow-y-auto px-4">{controls}</div>
65
+ <SheetFooter>
66
+ <Button variant="outline" disabled={!active} onClick={() => table.resetColumnFilters()}>
67
+ Clear filters
68
+ </Button>
69
+ <SheetClose render={<Button />}>Done</SheetClose>
70
+ </SheetFooter>
71
+ </SheetContent>
72
+ </Sheet>
73
+ );
74
+ }
75
+
76
+ export default function DataTableFiltersExample() {
77
+ return (
78
+ <Card>
79
+ <CardHeader>
80
+ <CardTitle>Holdings with compact filters</CardTitle>
81
+ <CardDescription>Search stays visible; secondary filters move into a panel in narrow space.</CardDescription>
82
+ </CardHeader>
83
+ <CardContent>
84
+ {/* The closed filter panel is absent at first render, so configure its features explicitly. */}
85
+ <DataTableRoot data={data} columns={columns} config={{ enableFilters: true, enableSorting: true }}>
86
+ <DataTableToolbarSection>
87
+ <DataTableSearchFilter
88
+ label="Search compact example"
89
+ placeholder="Search holdings…"
90
+ className="w-full flex-none sm:w-64"
91
+ />
92
+ <Filters />
93
+ <DataTableRowCount unit="holdings" />
94
+ </DataTableToolbarSection>
95
+ <DataTable aria-label="Holdings with compact filters">
96
+ <DataTableHeader />
97
+ <DataTableBody />
98
+ </DataTable>
99
+ </DataTableRoot>
100
+ </CardContent>
101
+ </Card>
102
+ );
103
+ }
@@ -0,0 +1,98 @@
1
+ import {
2
+ Card,
3
+ CardContent,
4
+ CardDescription,
5
+ CardHeader,
6
+ CardTitle,
7
+ DataTable,
8
+ DataTableBody,
9
+ DataTableFacetedFilter,
10
+ DataTableHeader,
11
+ DataTableRoot,
12
+ DataTableRowCount,
13
+ DataTableSearchFilter,
14
+ DataTableSortHeader,
15
+ DataTableToolbarSection,
16
+ Delta,
17
+ useFormat,
18
+ type DataTableColumnDef,
19
+ } from "@siyahi/ui";
20
+
21
+ interface Holding {
22
+ symbol: string;
23
+ sector: string;
24
+ quantity: number;
25
+ value: number;
26
+ change: number;
27
+ }
28
+
29
+ const holdings: Holding[] = [
30
+ { symbol: "INFY", sector: "IT", quantity: 120, value: 224400, change: 0.018 },
31
+ { symbol: "HDFCBANK", sector: "Banks", quantity: 150, value: 262500, change: -0.006 },
32
+ { symbol: "TCS", sector: "IT", quantity: 40, value: 166000, change: 0.004 },
33
+ { symbol: "ITC", sector: "Fast Moving Consumer Goods", quantity: 600, value: 276000, change: -0.012 },
34
+ { symbol: "ICICIBANK", sector: "Banks", quantity: 200, value: 258000, change: 0.022 },
35
+ { symbol: "NIFTYBEES", sector: "ETF", quantity: 900, value: 255600, change: 0.009 },
36
+ ];
37
+
38
+ // One click sorts largest (or Z) first; the title comes from meta.label.
39
+ const header = () => <DataTableSortHeader />;
40
+
41
+ function Money({ amount }: { amount: number }) {
42
+ return useFormat().money(amount);
43
+ }
44
+
45
+ const columns: DataTableColumnDef<Holding>[] = [
46
+ { accessorKey: "symbol", header, size: 140, meta: { label: "Symbol" } },
47
+ { accessorKey: "sector", header, size: 120, meta: { label: "Sector" } },
48
+ { accessorKey: "quantity", header, size: 100, meta: { label: "Qty", variant: "number" } },
49
+ {
50
+ accessorKey: "value",
51
+ header,
52
+ size: 140,
53
+ meta: { label: "Value", variant: "number" },
54
+ cell: ({ row }) => <Money amount={row.original.value} />,
55
+ },
56
+ {
57
+ accessorKey: "change",
58
+ header,
59
+ size: 110,
60
+ meta: { label: "Day", variant: "number" },
61
+ cell: ({ row }) => <Delta value={row.original.change} />,
62
+ },
63
+ ];
64
+
65
+ export default function DataTableExample() {
66
+ return (
67
+ <Card>
68
+ <CardHeader>
69
+ <CardTitle>Holdings</CardTitle>
70
+ <CardDescription>
71
+ Search every column, filter by sector, sort any column in one click; the symbol stays put when the table
72
+ scrolls in wide panels. In narrow panels every column scrolls, leaving room for the values
73
+ </CardDescription>
74
+ </CardHeader>
75
+ <CardContent>
76
+ <DataTableRoot
77
+ data={holdings}
78
+ columns={columns}
79
+ initialState={{ columnPinning: { start: ["symbol"], end: [] } }}
80
+ >
81
+ <DataTableToolbarSection>
82
+ <DataTableSearchFilter
83
+ placeholder="Search holdings…"
84
+ label="Filter holdings"
85
+ className="flex-none sm:w-64"
86
+ />
87
+ <DataTableFacetedFilter accessorKey="sector" title="Sector" />
88
+ <DataTableRowCount unit="holdings" />
89
+ </DataTableToolbarSection>
90
+ <DataTable aria-label="Holdings">
91
+ <DataTableHeader />
92
+ <DataTableBody />
93
+ </DataTable>
94
+ </DataTableRoot>
95
+ </CardContent>
96
+ </Card>
97
+ );
98
+ }
@@ -0,0 +1,13 @@
1
+ import { Delta } from "@siyahi/ui";
2
+
3
+ export default function DeltaExample() {
4
+ return (
5
+ <div className="flex flex-wrap items-center gap-6">
6
+ <Delta value={0.0234} />
7
+ <Delta value={-0.0108} />
8
+ <Delta value={0} />
9
+ <Delta value={18250} format="money" />
10
+ <Delta value={-4300} format="money" />
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,28 @@
1
+ import {
2
+ Button,
3
+ Dialog,
4
+ DialogClose,
5
+ DialogContent,
6
+ DialogDescription,
7
+ DialogFooter,
8
+ DialogHeader,
9
+ DialogTitle,
10
+ DialogTrigger,
11
+ } from "@siyahi/ui";
12
+
13
+ export default function DialogExample() {
14
+ return (
15
+ <Dialog>
16
+ <DialogTrigger render={<Button variant="outline" className="w-fit" />}>Show fills</DialogTrigger>
17
+ <DialogContent>
18
+ <DialogHeader>
19
+ <DialogTitle>Fills for this sell</DialogTitle>
20
+ <DialogDescription>Each lot this sale was matched against, oldest first.</DialogDescription>
21
+ </DialogHeader>
22
+ <DialogFooter>
23
+ <DialogClose render={<Button variant="outline" />}>Close</DialogClose>
24
+ </DialogFooter>
25
+ </DialogContent>
26
+ </Dialog>
27
+ );
28
+ }