@siyahi/ui 0.1.9-next.3 → 0.1.9-next.31

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 (254) hide show
  1. package/DESIGN.md +251 -0
  2. package/README.md +94 -177
  3. package/THIRD_PARTY_NOTICES.md +11 -11
  4. package/agents/examples/accordion.tsx +39 -0
  5. package/agents/examples/alert.tsx +24 -0
  6. package/agents/examples/app-sidebar.tsx +40 -0
  7. package/agents/examples/avatar.tsx +24 -0
  8. package/agents/examples/badge.tsx +26 -0
  9. package/agents/examples/bar-list-labels.tsx +22 -0
  10. package/agents/examples/bar-list-sides.tsx +40 -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 +11 -0
  16. package/agents/examples/callout.tsx +33 -0
  17. package/agents/examples/card.tsx +36 -0
  18. package/agents/examples/change-bar.tsx +104 -0
  19. package/agents/examples/change-grid-money.tsx +36 -0
  20. package/agents/examples/change-grid.tsx +43 -0
  21. package/agents/examples/chart-area-log.tsx +45 -0
  22. package/agents/examples/chart-area.tsx +39 -0
  23. package/agents/examples/chart-bar-flows.tsx +32 -0
  24. package/agents/examples/chart-bar-hourly.tsx +28 -0
  25. package/agents/examples/chart-bar-losses.tsx +29 -0
  26. package/agents/examples/chart-bar-teams.tsx +72 -0
  27. package/agents/examples/chart-bar-years.tsx +42 -0
  28. package/agents/examples/chart-bar.tsx +56 -0
  29. package/agents/examples/chart-category-ticks.tsx +50 -0
  30. package/agents/examples/chart-line-events.tsx +47 -0
  31. package/agents/examples/chart-line-forecast.tsx +36 -0
  32. package/agents/examples/chart-line-log.tsx +39 -0
  33. package/agents/examples/chart-line-quiet.tsx +114 -0
  34. package/agents/examples/chart-line-timeline.tsx +41 -0
  35. package/agents/examples/chart-line.tsx +57 -0
  36. package/agents/examples/chart-panels.tsx +94 -0
  37. package/agents/examples/code-block.tsx +40 -0
  38. package/agents/examples/collapsible.tsx +18 -0
  39. package/agents/examples/command.tsx +29 -0
  40. package/agents/examples/context-menu.tsx +17 -0
  41. package/agents/examples/copy-button.tsx +8 -0
  42. package/agents/examples/data-bar.tsx +114 -0
  43. package/agents/examples/data-table-compact.tsx +93 -0
  44. package/agents/examples/data-table-filters.tsx +103 -0
  45. package/agents/examples/data-table.tsx +96 -0
  46. package/agents/examples/delta.tsx +18 -0
  47. package/agents/examples/dialog.tsx +28 -0
  48. package/agents/examples/distribution-bar-budget.tsx +30 -0
  49. package/agents/examples/distribution-bar-tug.tsx +74 -0
  50. package/agents/examples/drawdown-chart.tsx +35 -0
  51. package/agents/examples/dropdown-menu.tsx +31 -0
  52. package/agents/examples/field.tsx +108 -0
  53. package/agents/examples/formatters.tsx +42 -0
  54. package/agents/examples/heatmap-calendar-signed.tsx +67 -0
  55. package/agents/examples/heatmap-calendar.tsx +62 -0
  56. package/agents/examples/heatmap-status.tsx +61 -0
  57. package/agents/examples/heatmap-weekday.tsx +72 -0
  58. package/agents/examples/histogram-chart.tsx +28 -0
  59. package/agents/examples/input-states.tsx +23 -0
  60. package/agents/examples/input.tsx +17 -0
  61. package/agents/examples/local-time.tsx +14 -0
  62. package/agents/examples/metric-strip.tsx +46 -0
  63. package/agents/examples/overview-dashboard.tsx +180 -0
  64. package/agents/examples/page-hero.tsx +38 -0
  65. package/agents/examples/page-section.tsx +52 -0
  66. package/agents/examples/popover.tsx +23 -0
  67. package/agents/examples/price-chart.tsx +32 -0
  68. package/agents/examples/progress-tone.tsx +29 -0
  69. package/agents/examples/progress.tsx +10 -0
  70. package/agents/examples/range-position-table.tsx +113 -0
  71. package/agents/examples/range-position.tsx +55 -0
  72. package/agents/examples/scatter-chart-quadrants.tsx +63 -0
  73. package/agents/examples/scatter-chart-scales.tsx +46 -0
  74. package/agents/examples/scatter-chart.tsx +78 -0
  75. package/agents/examples/scroll-area.tsx +22 -0
  76. package/agents/examples/section-cards-select.tsx +28 -0
  77. package/agents/examples/section-cards-trend.tsx +32 -0
  78. package/agents/examples/section-cards.tsx +48 -0
  79. package/agents/examples/select.tsx +27 -0
  80. package/agents/examples/separator.tsx +13 -0
  81. package/agents/examples/sheet.tsx +15 -0
  82. package/agents/examples/skeleton.tsx +11 -0
  83. package/agents/examples/slider.tsx +5 -0
  84. package/agents/examples/slope-chart-market.tsx +33 -0
  85. package/agents/examples/slope-chart.tsx +26 -0
  86. package/agents/examples/stale-blocks.tsx +56 -0
  87. package/agents/examples/surfaces.tsx +116 -0
  88. package/agents/examples/table.tsx +60 -0
  89. package/agents/examples/tabs.tsx +16 -0
  90. package/agents/examples/target-rows.tsx +74 -0
  91. package/agents/examples/toggle-group.tsx +12 -0
  92. package/agents/examples/toggle.tsx +11 -0
  93. package/agents/examples/tooltip.tsx +13 -0
  94. package/agents/examples/treemap.tsx +93 -0
  95. package/agents/examples/waterfall-chart-stores.tsx +27 -0
  96. package/agents/examples/waterfall-chart.tsx +37 -0
  97. package/agents/manifest.json +1391 -0
  98. package/agents/report-rules.json +7 -0
  99. package/dist/components/registry/charts/area-chart-card.d.ts +7 -3
  100. package/dist/components/registry/charts/area-chart-card.js +56 -10
  101. package/dist/components/registry/charts/bar-chart-card.d.ts +1 -1
  102. package/dist/components/registry/charts/bar-chart-card.js +20 -22
  103. package/dist/components/registry/charts/line-chart-card.d.ts +3 -3
  104. package/dist/components/registry/charts/line-chart-card.js +44 -9
  105. package/dist/components/registry/dashboard-01/section-cards.d.ts +6 -0
  106. package/dist/components/registry/dashboard-01/section-cards.js +51 -35
  107. package/dist/components/registry/dashboardcn/bar-list.js +17 -10
  108. package/dist/components/registry/dashboardcn/distribution-bar.js +6 -4
  109. package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +29 -0
  110. package/dist/components/registry/dashboardcn/kpi-row-card.js +81 -0
  111. package/dist/components/registry/dashboardcn/sparkline.d.ts +22 -0
  112. package/dist/components/registry/dashboardcn/sparkline.js +117 -0
  113. package/dist/components/registry/heatmap/calendar-heatmap.d.ts +11 -3
  114. package/dist/components/registry/heatmap/calendar-heatmap.js +164 -45
  115. package/dist/components/registry/heatmap/status-heatmap.d.ts +5 -3
  116. package/dist/components/registry/heatmap/status-heatmap.js +115 -54
  117. package/dist/components/registry/heatmap/weekday-heatmap.d.ts +9 -3
  118. package/dist/components/registry/heatmap/weekday-heatmap.js +83 -53
  119. package/dist/components/registry/niko-table/core/data-table-context.d.ts +18 -1
  120. package/dist/components/registry/niko-table/core/data-table-context.js +7 -1
  121. package/dist/components/registry/niko-table/core/data-table-grouped-row.js +3 -1
  122. package/dist/components/registry/niko-table/core/data-table-root.js +39 -4
  123. package/dist/components/registry/niko-table/core/data-table-structure.js +17 -12
  124. package/dist/components/registry/niko-table/core/data-table.d.ts +2 -2
  125. package/dist/components/registry/niko-table/core/data-table.js +5 -1
  126. package/dist/components/registry/niko-table/filters/table-faceted-filter.js +5 -5
  127. package/dist/components/registry/niko-table/filters/table-search-filter.js +1 -1
  128. package/dist/components/registry/niko-table/lib/flex-columns.d.ts +1 -1
  129. package/dist/components/registry/niko-table/lib/flex-columns.js +3 -3
  130. package/dist/components/registry/niko-table/lib/styles.d.ts +1 -1
  131. package/dist/components/registry/niko-table/lib/styles.js +3 -3
  132. package/dist/components/registry/niko-table/types/index.d.ts +9 -0
  133. package/dist/components/registry/niko-table/ui/table.js +2 -2
  134. package/dist/components/registry/sidebar-07/app-sidebar.d.ts +1 -1
  135. package/dist/components/registry/sidebar-07/app-sidebar.js +3 -1
  136. package/dist/components/registry/sidebar-07/nav-main.d.ts +2 -1
  137. package/dist/components/registry/sidebar-07/nav-main.js +16 -3
  138. package/dist/components/siyahi/callout.d.ts +17 -0
  139. package/dist/components/siyahi/callout.js +34 -0
  140. package/dist/components/siyahi/change-bar.d.ts +21 -0
  141. package/dist/components/siyahi/change-bar.js +35 -0
  142. package/dist/components/siyahi/change-grid.d.ts +31 -0
  143. package/dist/components/siyahi/change-grid.js +74 -0
  144. package/dist/components/siyahi/data-bar.d.ts +19 -0
  145. package/dist/components/siyahi/data-bar.js +29 -0
  146. package/dist/components/siyahi/data-table-compact-columns-toggle.d.ts +4 -0
  147. package/dist/components/siyahi/data-table-compact-columns-toggle.js +19 -0
  148. package/dist/components/siyahi/data-table-footnote.d.ts +12 -0
  149. package/dist/components/siyahi/data-table-footnote.js +35 -0
  150. package/dist/components/siyahi/default-sidebar-open.d.ts +8 -0
  151. package/dist/components/siyahi/default-sidebar-open.js +13 -0
  152. package/dist/components/siyahi/delta.d.ts +5 -1
  153. package/dist/components/siyahi/delta.js +14 -9
  154. package/dist/components/siyahi/drawdown-chart.d.ts +34 -0
  155. package/dist/components/siyahi/drawdown-chart.js +102 -0
  156. package/dist/components/siyahi/histogram-chart.d.ts +57 -0
  157. package/dist/components/siyahi/histogram-chart.js +134 -0
  158. package/dist/components/siyahi/page-hero.d.ts +23 -0
  159. package/dist/components/siyahi/page-hero.js +43 -0
  160. package/dist/components/siyahi/page-section.d.ts +4 -1
  161. package/dist/components/siyahi/page-section.js +6 -3
  162. package/dist/components/siyahi/page-toc.d.ts +20 -0
  163. package/dist/components/siyahi/page-toc.js +76 -0
  164. package/dist/components/siyahi/panel-grid.d.ts +24 -0
  165. package/dist/components/siyahi/panel-grid.js +37 -0
  166. package/dist/components/siyahi/quote.d.ts +12 -0
  167. package/dist/components/siyahi/quote.js +23 -0
  168. package/dist/components/siyahi/range-position.d.ts +24 -0
  169. package/dist/components/siyahi/range-position.js +105 -0
  170. package/dist/components/siyahi/scale-toggle.d.ts +32 -0
  171. package/dist/components/siyahi/scale-toggle.js +61 -0
  172. package/dist/components/siyahi/scatter-chart.d.ts +69 -0
  173. package/dist/components/siyahi/scatter-chart.js +395 -0
  174. package/dist/components/siyahi/siyahi-provider.d.ts +15 -2
  175. package/dist/components/siyahi/siyahi-provider.js +17 -4
  176. package/dist/components/siyahi/slope-chart.d.ts +35 -0
  177. package/dist/components/siyahi/slope-chart.js +159 -0
  178. package/dist/components/siyahi/stale-note.d.ts +9 -0
  179. package/dist/components/siyahi/stale-note.js +12 -0
  180. package/dist/components/siyahi/status-alert.d.ts +15 -0
  181. package/dist/components/siyahi/status-alert.js +29 -0
  182. package/dist/components/siyahi/status-badge.d.ts +15 -0
  183. package/dist/components/siyahi/status-badge.js +24 -0
  184. package/dist/components/siyahi/target-rows.d.ts +34 -0
  185. package/dist/components/siyahi/target-rows.js +97 -0
  186. package/dist/components/siyahi/tone-progress.d.ts +1 -1
  187. package/dist/components/siyahi/tone-progress.js +1 -1
  188. package/dist/components/siyahi/treemap.d.ts +8 -5
  189. package/dist/components/siyahi/treemap.js +80 -34
  190. package/dist/components/siyahi/waterfall-chart.d.ts +51 -0
  191. package/dist/components/siyahi/waterfall-chart.js +147 -0
  192. package/dist/components/ui/accordion.js +5 -5
  193. package/dist/components/ui/alert.js +2 -2
  194. package/dist/components/ui/badge.js +1 -1
  195. package/dist/components/ui/breadcrumb.js +2 -2
  196. package/dist/components/ui/button.js +10 -10
  197. package/dist/components/ui/calendar.js +1 -1
  198. package/dist/components/ui/card.js +4 -4
  199. package/dist/components/ui/chart.js +1 -1
  200. package/dist/components/ui/code-block.js +13 -12
  201. package/dist/components/ui/command.js +7 -6
  202. package/dist/components/ui/context-menu.js +7 -7
  203. package/dist/components/ui/dialog.js +5 -5
  204. package/dist/components/ui/dropdown-menu.js +8 -8
  205. package/dist/components/ui/field.d.ts +26 -0
  206. package/dist/components/ui/field.js +109 -0
  207. package/dist/components/ui/input-group.js +11 -11
  208. package/dist/components/ui/input.js +1 -1
  209. package/dist/components/ui/label.d.ts +5 -0
  210. package/dist/components/ui/label.js +13 -0
  211. package/dist/components/ui/popover.js +3 -3
  212. package/dist/components/ui/progress.js +1 -1
  213. package/dist/components/ui/select.js +6 -6
  214. package/dist/components/ui/sheet.js +5 -5
  215. package/dist/components/ui/sidebar.js +17 -18
  216. package/dist/components/ui/skeleton.js +1 -1
  217. package/dist/components/ui/slider.js +2 -2
  218. package/dist/components/ui/table.js +2 -2
  219. package/dist/components/ui/tabs.js +2 -2
  220. package/dist/components/ui/textarea.js +1 -1
  221. package/dist/components/ui/toggle-group.js +2 -2
  222. package/dist/components/ui/toggle.js +4 -4
  223. package/dist/components/ui/tooltip.js +2 -2
  224. package/dist/index.d.ts +35 -8
  225. package/dist/index.js +30 -4
  226. package/dist/lib/chart-frame.d.ts +51 -7
  227. package/dist/lib/chart-frame.js +390 -133
  228. package/dist/lib/chart-marks.d.ts +83 -0
  229. package/dist/lib/chart-marks.js +216 -0
  230. package/dist/lib/chart-series.d.ts +42 -10
  231. package/dist/lib/compact-columns.d.ts +19 -0
  232. package/dist/lib/compact-columns.js +55 -0
  233. package/dist/lib/fit-text.d.ts +6 -0
  234. package/dist/lib/fit-text.js +11 -0
  235. package/dist/lib/format.d.ts +8 -3
  236. package/dist/lib/format.js +55 -17
  237. package/dist/lib/heat.d.ts +7 -0
  238. package/dist/lib/heat.js +14 -0
  239. package/dist/lib/heatmap-navigation.d.ts +8 -0
  240. package/dist/lib/heatmap-navigation.js +49 -0
  241. package/dist/lib/scatter.d.ts +88 -0
  242. package/dist/lib/scatter.js +179 -0
  243. package/dist/lib/ticks.d.ts +27 -0
  244. package/dist/lib/ticks.js +67 -0
  245. package/dist/lib/tone.d.ts +36 -0
  246. package/dist/lib/tone.js +35 -0
  247. package/dist/lib/treemap.d.ts +0 -5
  248. package/dist/lib/treemap.js +1 -11
  249. package/dist/lib/use-element-width.d.ts +5 -0
  250. package/dist/lib/use-element-width.js +15 -0
  251. package/package.json +5 -1
  252. package/registry.lock.json +16 -0
  253. package/report.css +63 -47
  254. package/styles/siyahi.css +708 -55
@@ -0,0 +1,39 @@
1
+ import { AreaChartCard, ToggleGroup, ToggleGroupItem, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ const data = [
4
+ { month: "May", revenue: 3820000, target: 3600000 },
5
+ { month: "Jun", revenue: 3950000, target: 3685000 },
6
+ { month: "Jul", revenue: 4110000, target: 3770000 },
7
+ { month: "Aug", revenue: 4020000, target: 3855000 },
8
+ { month: "Sep", revenue: 4380000, target: 3940000 },
9
+ { month: "Oct", revenue: 4512300, target: 4025000 },
10
+ ];
11
+
12
+ // The title states the finding, not the measure: what the reader would say after looking.
13
+ // The first series fills; the target draws as a line over it.
14
+ const series: ChartSeries<(typeof data)[number]> = [
15
+ { key: "revenue", label: "Revenue", color: "var(--chart-1)" },
16
+ { key: "target", label: "Target", color: "var(--chart-2)" },
17
+ ];
18
+
19
+ export default function ChartAreaExample() {
20
+ const { money, moneyCompact } = useFormat();
21
+ return (
22
+ <AreaChartCard
23
+ title="October revenue ₹4.9L ahead of target"
24
+ description="Each month's revenue against its target"
25
+ action={
26
+ <ToggleGroup defaultValue={["6M"]} variant="outline" size="sm" aria-label="Range">
27
+ <ToggleGroupItem value="6M">6M</ToggleGroupItem>
28
+ <ToggleGroupItem value="1Y">1Y</ToggleGroupItem>
29
+ </ToggleGroup>
30
+ }
31
+ data={data}
32
+ xKey="month"
33
+ series={series}
34
+ valueFormatter={money}
35
+ yTickFormatter={moneyCompact}
36
+ height={256}
37
+ />
38
+ );
39
+ }
@@ -0,0 +1,32 @@
1
+ import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // Money into and out of a shop's bank account each month; out is negative. Made-up figures.
4
+ const data = [
5
+ { month: "Jul", in: 84000, out: -52000 },
6
+ { month: "Aug", in: 61000, out: -73000 },
7
+ { month: "Sep", in: 92000, out: -48000 },
8
+ { month: "Oct", in: 70000, out: -66000 },
9
+ ];
10
+
11
+ // Money moving is not a gain or a loss, so in and out take chart colours, not green and red.
12
+ const series: ChartSeries<(typeof data)[number]> = [
13
+ { key: "in", label: "In", color: "var(--chart-1)" },
14
+ { key: "out", label: "Out", color: "var(--chart-2)" },
15
+ ];
16
+
17
+ export default function ChartBarFlowsExample() {
18
+ const { money, moneyCompact } = useFormat();
19
+ return (
20
+ <BarChartCard
21
+ title="Cash in and out by month"
22
+ description="Money in above the line, money out below it"
23
+ data={data}
24
+ xKey="month"
25
+ series={series}
26
+ stacked
27
+ valueFormatter={money}
28
+ yTickFormatter={moneyCompact}
29
+ height={256}
30
+ />
31
+ );
32
+ }
@@ -0,0 +1,28 @@
1
+ import { BarChartCard } from "@siyahi/ui";
2
+
3
+ // Opening hours in IST; each row is the hour an order was placed in.
4
+ const data = [
5
+ { hour: 9, orders: 42 },
6
+ { hour: 10, orders: 31 },
7
+ { hour: 11, orders: 18 },
8
+ { hour: 12, orders: 12 },
9
+ { hour: 13, orders: 15 },
10
+ { hour: 14, orders: 24 },
11
+ { hour: 15, orders: 38 },
12
+ ];
13
+
14
+ export default function ChartBarHourlyExample() {
15
+ return (
16
+ <BarChartCard
17
+ title="Orders by hour"
18
+ description="Last 30 days, by the hour each order was placed"
19
+ data={data}
20
+ xKey="hour"
21
+ xFormatter={(hour) => `${String(hour).padStart(2, "0")}:00`}
22
+ xLabel="Hour of day (IST)"
23
+ yLabel="Orders"
24
+ series={[{ key: "orders", label: "Orders", color: "var(--chart-1)" }]}
25
+ height={256}
26
+ />
27
+ );
28
+ }
@@ -0,0 +1,29 @@
1
+ import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // A new product line's operating result per financial year, a loss every year; made-up figures.
4
+ const data = [
5
+ { fy: "FY23", net: -48000 },
6
+ { fy: "FY24", net: -91000 },
7
+ { fy: "FY25", net: -27000 },
8
+ { fy: "FY26", net: -63000 },
9
+ ];
10
+
11
+ const series: ChartSeries<(typeof data)[number]> = [
12
+ { key: "net", label: "Operating result", color: "var(--positive)", negativeColor: "var(--negative)" },
13
+ ];
14
+
15
+ export default function ChartBarLossesExample() {
16
+ const { money, moneyCompact } = useFormat();
17
+ return (
18
+ <BarChartCard
19
+ title="Operating loss by financial year"
20
+ description="FY26 ends in March 2026. A loss every year, so every bar runs down from zero."
21
+ data={data}
22
+ xKey="fy"
23
+ series={series}
24
+ valueFormatter={money}
25
+ yTickFormatter={moneyCompact}
26
+ height={240}
27
+ />
28
+ );
29
+ }
@@ -0,0 +1,72 @@
1
+ import { useState } from "react";
2
+ import { BarChartCard, ToggleGroup, ToggleGroupItem, useFormat, type ChartSeries } from "@siyahi/ui";
3
+
4
+ // Each team's share of this year's spend against a comparison; made-up figures.
5
+ const SHARES = {
6
+ Plan: [
7
+ { team: "Engineering and Infrastructure", actual: 0.34, comparison: 0.37 },
8
+ { team: "Sales and Business Development", actual: 0.21, comparison: 0.13 },
9
+ { team: "Finance, Legal & Compliance", actual: 0.06, comparison: 0.1 },
10
+ { team: "Marketing and Communications", actual: 0.12, comparison: 0.08 },
11
+ { team: "Customer Support and Success", actual: 0.09, comparison: 0.07 },
12
+ { team: "Operations", actual: 0.08, comparison: 0.04 },
13
+ ],
14
+ "Last year": [
15
+ { team: "Engineering and Infrastructure", actual: 0.34, comparison: 0.31 },
16
+ { team: "Sales and Business Development", actual: 0.21, comparison: 0.1 },
17
+ { team: "Finance, Legal & Compliance", actual: 0.06, comparison: 0.08 },
18
+ { team: "Marketing and Communications", actual: 0.12, comparison: 0.07 },
19
+ { team: "Customer Support and Success", actual: 0.09, comparison: 0.07 },
20
+ { team: "Operations", actual: 0.08, comparison: 0.06 },
21
+ ],
22
+ };
23
+ type Comparison = keyof typeof SHARES;
24
+ type Row = (typeof SHARES)[Comparison][number];
25
+
26
+ export default function ChartBarTeamsExample() {
27
+ const { pct } = useFormat();
28
+ const [comparison, setComparison] = useState<Comparison>("Plan");
29
+ const rows = SHARES[comparison];
30
+ const series: ChartSeries<Row> = [
31
+ { key: "actual", label: "This year", color: "var(--chart-1)" },
32
+ { key: "comparison", label: comparison, color: "var(--chart-2)" },
33
+ ];
34
+ const gap = (row: Row) => {
35
+ const points = Math.abs(row.actual - row.comparison) * 100;
36
+ return `${row.actual >= row.comparison ? "+" : "\u2212"}${points.toFixed(1)} points`;
37
+ };
38
+ return (
39
+ <BarChartCard
40
+ title="Spend by team against plan or last year"
41
+ description="Each team's share of this year's spend and of the comparison"
42
+ action={
43
+ <ToggleGroup
44
+ value={[comparison]}
45
+ onValueChange={([next]) => {
46
+ // Pressing the selected comparison again would leave none selected; keep it.
47
+ if (next) setComparison(next as Comparison);
48
+ }}
49
+ variant="outline"
50
+ size="sm"
51
+ aria-label="Compare with"
52
+ >
53
+ <ToggleGroupItem value="Plan">Plan</ToggleGroupItem>
54
+ <ToggleGroupItem value="Last year">Last year</ToggleGroupItem>
55
+ </ToggleGroup>
56
+ }
57
+ horizontal
58
+ data={rows}
59
+ xKey="team"
60
+ xTickDetail={(row) => `${pct(row.actual)} against ${pct(row.comparison)}, ${gap(row)}`}
61
+ series={series}
62
+ valueFormatter={(v) => pct(v)}
63
+ // A tick format puts the value axis along the bottom of the sideways bars.
64
+ yTickFormatter={(v) => pct(v, 0)}
65
+ // Sideways, y is still the value: the axis runs 0 to 40% and the cap is a value level.
66
+ yDomain={[0, 0.4]}
67
+ referenceLines={[{ y: 0.3, label: "cap 30%", labelPosition: "insideBottomRight" }]}
68
+ height={rows.length * 56 + 48}
69
+ footer={<p className="text-muted-foreground">Salaries are left out; they are budgeted separately.</p>}
70
+ />
71
+ );
72
+ }
@@ -0,0 +1,42 @@
1
+ import { useState } from "react";
2
+ import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
3
+
4
+ // Net profit per financial year (April to March); made-up figures.
5
+ const data = [
6
+ { fy: "FY22", net: 142000 },
7
+ { fy: "FY23", net: 186000 },
8
+ { fy: "FY24", net: -164000 },
9
+ { fy: "FY25", net: 128000 },
10
+ { fy: "FY26", net: -121000 },
11
+ ];
12
+
13
+ // A gain and a loss take the meaning colours; the arrow in each tick says the same without colour.
14
+ const series: ChartSeries<(typeof data)[number]> = [
15
+ { key: "net", label: "Net profit", color: "var(--positive)", negativeColor: "var(--negative)" },
16
+ ];
17
+
18
+ export default function ChartBarYearsExample() {
19
+ const { money, moneyCompact } = useFormat();
20
+ // The page owns the pick, so it can narrow the rest of the page to that year.
21
+ const [year, setYear] = useState<string | null>(null);
22
+ const signed = (v: number) => `${v < 0 ? "\u2212" : "+"}${moneyCompact(Math.abs(v))}`;
23
+ return (
24
+ <BarChartCard
25
+ title="Profit by financial year"
26
+ description={
27
+ year
28
+ ? `${year} picked (April to March, before tax). Click it again for every year.`
29
+ : "April to March, before tax; FY26 ends in March 2026. Click a year to pick it."
30
+ }
31
+ data={data}
32
+ xKey="fy"
33
+ xTickDetail={(row) => signed(row.net)}
34
+ selected={year}
35
+ onSelect={setYear}
36
+ series={series}
37
+ valueFormatter={money}
38
+ yTickFormatter={moneyCompact}
39
+ height={272}
40
+ />
41
+ );
42
+ }
@@ -0,0 +1,56 @@
1
+ import { useState } from "react";
2
+ import { BarChartCard, ToggleGroup, ToggleGroupItem, useFormat, type ChartSeries } from "@siyahi/ui";
3
+
4
+ const data = [
5
+ { quarter: "Q1", online: 120000, retail: 40000, wholesale: 15000, marketplace: 9000, events: 4000 },
6
+ { quarter: "Q2", online: 95000, retail: 52000, wholesale: 20000, marketplace: 6000, events: 3000 },
7
+ { quarter: "Q3", online: 140000, retail: 38000, wholesale: 12000, marketplace: 11000, events: 5000 },
8
+ { quarter: "Q4", online: 160000, retail: 45000, wholesale: 25000, marketplace: 7000, events: 2000 },
9
+ ];
10
+
11
+ // Series take the slots in order: neighbours differ in lightness, slots two
12
+ // apart differ in hue.
13
+ const series: ChartSeries<(typeof data)[number]> = [
14
+ { key: "online", label: "Online", color: "var(--chart-1)" },
15
+ { key: "retail", label: "Retail", color: "var(--chart-2)" },
16
+ { key: "wholesale", label: "Wholesale", color: "var(--chart-3)" },
17
+ { key: "marketplace", label: "Marketplace", color: "var(--chart-4)" },
18
+ { key: "events", label: "Events", color: "var(--chart-5)" },
19
+ ];
20
+
21
+ export default function ChartBarExample() {
22
+ const { money, moneyCompact } = useFormat();
23
+ const [layout, setLayout] = useState("grouped");
24
+ return (
25
+ <BarChartCard
26
+ title="Revenue by channel and quarter"
27
+ description={
28
+ layout === "grouped"
29
+ ? "Each channel's revenue, side by side"
30
+ : "Each channel's revenue, stacked into the quarter's total"
31
+ }
32
+ action={
33
+ <ToggleGroup
34
+ value={[layout]}
35
+ onValueChange={([next]) => {
36
+ // Pressing the selected layout again would leave none selected; keep it.
37
+ if (next) setLayout(next);
38
+ }}
39
+ variant="outline"
40
+ size="sm"
41
+ aria-label="Layout"
42
+ >
43
+ <ToggleGroupItem value="grouped">Grouped</ToggleGroupItem>
44
+ <ToggleGroupItem value="stacked">Stacked</ToggleGroupItem>
45
+ </ToggleGroup>
46
+ }
47
+ data={data}
48
+ xKey="quarter"
49
+ series={series}
50
+ stacked={layout === "stacked"}
51
+ valueFormatter={money}
52
+ yTickFormatter={moneyCompact}
53
+ height={256}
54
+ />
55
+ );
56
+ }
@@ -0,0 +1,50 @@
1
+ import { AreaChartCard, BarChartCard, LineChartCard, type SeriesChartProps } from "@siyahi/ui";
2
+
3
+ const data = Array.from({ length: 84 }, (_, index) => ({
4
+ month: `${2019 + Math.floor(index / 12)}-${String((index % 12) + 1).padStart(2, "0")}`,
5
+ orders: 20 + ((index * 7) % 31),
6
+ }));
7
+ const props: SeriesChartProps<(typeof data)[number], "month"> = {
8
+ title: "Monthly orders, bars",
9
+ description: "Demo orders per month, 2019–2025; only April is labelled",
10
+ data,
11
+ xKey: "month",
12
+ xTicks: data.filter(({ month }) => month.endsWith("-04")).map(({ month }) => month),
13
+ xFormatter: (month) => `Apr ${month.slice(2, 4)}`,
14
+ xTooltipFormatter: (month) => month,
15
+ series: [{ key: "orders", label: "Orders", color: "var(--chart-1)" }],
16
+ height: 200,
17
+ };
18
+
19
+ export default function ChartCategoryTicksExample() {
20
+ return (
21
+ <div className="flex flex-col gap-4">
22
+ <BarChartCard {...props} />
23
+ <BarChartCard
24
+ {...props}
25
+ title="Monthly orders, sideways"
26
+ description="Demo orders per month in 2019; only April is labelled"
27
+ data={data.slice(0, 12)}
28
+ xTicks={["2019-04"]}
29
+ horizontal
30
+ height={300}
31
+ />
32
+ <BarChartCard
33
+ title="Orders by category"
34
+ description="Demo orders; one long category label on a narrow chart"
35
+ data={[
36
+ { category: "Home Appliances and Kitchen Equipment", orders: 100 },
37
+ { category: "Other", orders: 50 },
38
+ { category: "Third", orders: 70 },
39
+ ]}
40
+ xKey="category"
41
+ xTicks={["Home Appliances and Kitchen Equipment"]}
42
+ series={[{ key: "orders", label: "Orders", color: "var(--chart-1)" }]}
43
+ horizontal
44
+ height={220}
45
+ />
46
+ <LineChartCard {...props} title="Monthly orders, line" />
47
+ <AreaChartCard {...props} title="Monthly orders, area" />
48
+ </div>
49
+ );
50
+ }
@@ -0,0 +1,47 @@
1
+ import { LineChartCard, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // A sample every 15 s from 19:33:58; the numbers are made up for the catalogue.
4
+ const START = (19 * 60 + 33) * 60 + 58;
5
+ const PRESSURE = [
6
+ 4, 18, 41, 58, 63, 66, 61, 70, 72, 68, 64, 71, 74, 69, 66, 62, 67, 73, 70, 65, 68, 71, 66, 63, 69, 72,
7
+ ];
8
+ const data = PRESSURE.map((pressure, i) => ({ second: i * 15, pressure }));
9
+
10
+ const series: ChartSeries<(typeof data)[number]> = [
11
+ { key: "pressure", label: "Full pressure", color: "var(--chart-1)" },
12
+ ];
13
+
14
+ const pad = (n: number) => String(n).padStart(2, "0");
15
+
16
+ function clock(second: number) {
17
+ const t = START + second;
18
+ return `${Math.floor(t / 3600)}:${pad(Math.floor(t / 60) % 60)}:${pad(t % 60)}`;
19
+ }
20
+
21
+ export default function ChartLineEventsExample() {
22
+ return (
23
+ <LineChartCard
24
+ title="Memory pressure of a test group, %"
25
+ description="Share of time the group stalled waiting for memory, as the kernel's 10 s average (avg10), sampled every 15 s, times in IST"
26
+ data={data}
27
+ xKey="second"
28
+ // A numeric axis: ticks fall on whole minutes, 2 s after the first sample.
29
+ xDomain={[0, 390]}
30
+ xTicks={[2, 62, 122, 182, 242, 302, 362]}
31
+ xFormatter={(second) => clock(second).slice(0, 5)}
32
+ xTooltipFormatter={(second) => `${clock(second)} IST, 10 s average`}
33
+ series={series}
34
+ curve="linear"
35
+ valueFormatter={(v) => `${v}%`}
36
+ yDomain={[0, 100]}
37
+ yTicks={[0, 25, 50, 75, 100]}
38
+ referenceLines={[
39
+ { y: 80, label: "old limit, 80%" },
40
+ { y: 50, label: "new limit, 50%", emphasis: "strong" },
41
+ { x: 313, label: "limit 50%", labelPosition: "insideBottomRight" },
42
+ { x: 367, label: "killed", emphasis: "strong", labelPosition: "insideTopRight" },
43
+ ]}
44
+ height={224}
45
+ />
46
+ );
47
+ }
@@ -0,0 +1,36 @@
1
+ import { LineChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // Net worth's growth against the plan since May; November and December are a forecast.
4
+ const worth = [
5
+ { month: "May", actual: 0, plan: 0 },
6
+ { month: "Jun", actual: 0.025, plan: 0.022 },
7
+ { month: "Jul", actual: 0.061, plan: 0.044 },
8
+ { month: "Aug", actual: 0.047, plan: 0.067 },
9
+ { month: "Sep", actual: 0.11, plan: 0.089 },
10
+ { month: "Oct", actual: 0.156, plan: 0.111 },
11
+ { month: "Nov", actual: 0.177, plan: 0.133 },
12
+ { month: "Dec", actual: 0.202, plan: 0.156 },
13
+ ];
14
+ const series: ChartSeries<(typeof worth)[number]> = [
15
+ { key: "actual", label: "Net worth", color: "var(--chart-1)" },
16
+ { key: "plan", label: "Plan", color: "var(--chart-2)" },
17
+ ];
18
+
19
+ // Today is a rule in the link colour; from forecastFrom the lines dash, a hatched band covers the stretch and the end
20
+ // dots are hollow.
21
+ export default function ChartLineForecastExample() {
22
+ const { pct } = useFormat();
23
+ return (
24
+ <LineChartCard
25
+ title="Growth against plan"
26
+ description="Since May, month-end; November and December are a forecast"
27
+ data={worth}
28
+ xKey="month"
29
+ series={series}
30
+ today="Oct"
31
+ forecastFrom="Oct"
32
+ valueFormatter={pct}
33
+ height={256}
34
+ />
35
+ );
36
+ }
@@ -0,0 +1,39 @@
1
+ import { Badge, LineChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // Monthly active users in the app's first year, made up for the catalogue: from a few hundred to tens of thousands.
4
+ const data = [
5
+ { month: "Nov", users: 240 },
6
+ { month: "Dec", users: 410 },
7
+ { month: "Jan", users: 780 },
8
+ { month: "Feb", users: 1350 },
9
+ { month: "Mar", users: 2100 },
10
+ { month: "Apr", users: 3900 },
11
+ { month: "May", users: 6200 },
12
+ { month: "Jun", users: 9800 },
13
+ { month: "Jul", users: 14100 },
14
+ { month: "Aug", users: 21500 },
15
+ { month: "Sep", users: 30200 },
16
+ { month: "Oct", users: 46800 },
17
+ ];
18
+
19
+ const series: ChartSeries<(typeof data)[number]> = [{ key: "users", label: "Active users", color: "var(--chart-1)" }];
20
+
21
+ export default function ChartLineLogExample() {
22
+ const { count } = useFormat();
23
+ return (
24
+ <LineChartCard
25
+ title="Active users grew about 1.5× a month all year"
26
+ description="On log, steady growth is a straight line; Linear shows how much of it came in the last few months."
27
+ action={<Badge variant="outline">First year</Badge>}
28
+ data={data}
29
+ xKey="month"
30
+ series={series}
31
+ // Log is selected first; the buttons in the header let the reader switch.
32
+ yScale="log"
33
+ yScaleToggle
34
+ yLabel="Active users"
35
+ valueFormatter={count}
36
+ height={256}
37
+ />
38
+ );
39
+ }
@@ -0,0 +1,114 @@
1
+ import { LineChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
+
3
+ // Eight funds' month-end growth; November and December are a forecast.
4
+ const growth = [
5
+ { month: "May", flexi: 0, debt: 0, small: 0, intl: 0, liquid: 0, midcap: 0, nifty: 0, gold: 0 },
6
+ {
7
+ month: "Jun",
8
+ flexi: 0.018,
9
+ debt: 0.006,
10
+ small: 0.034,
11
+ intl: 0.012,
12
+ liquid: 0.005,
13
+ midcap: 0.022,
14
+ nifty: 0.025,
15
+ gold: 0.041,
16
+ },
17
+ {
18
+ month: "Jul",
19
+ flexi: 0.049,
20
+ debt: 0.013,
21
+ small: 0.012,
22
+ intl: 0.038,
23
+ liquid: 0.011,
24
+ midcap: 0.03,
25
+ nifty: 0.061,
26
+ gold: 0.072,
27
+ },
28
+ {
29
+ month: "Aug",
30
+ flexi: 0.058,
31
+ debt: 0.02,
32
+ small: -0.041,
33
+ intl: 0.066,
34
+ liquid: 0.017,
35
+ midcap: 0.011,
36
+ nifty: 0.047,
37
+ gold: 0.118,
38
+ },
39
+ {
40
+ month: "Sep",
41
+ flexi: 0.094,
42
+ debt: 0.027,
43
+ small: -0.018,
44
+ intl: 0.081,
45
+ liquid: 0.023,
46
+ midcap: 0.052,
47
+ nifty: 0.11,
48
+ gold: 0.153,
49
+ },
50
+ {
51
+ month: "Oct",
52
+ flexi: 0.141,
53
+ debt: 0.034,
54
+ small: -0.052,
55
+ intl: 0.119,
56
+ liquid: 0.029,
57
+ midcap: 0.078,
58
+ nifty: 0.156,
59
+ gold: 0.196,
60
+ },
61
+ {
62
+ month: "Nov",
63
+ flexi: 0.166,
64
+ debt: 0.043,
65
+ small: -0.04,
66
+ intl: 0.142,
67
+ liquid: 0.037,
68
+ midcap: 0.099,
69
+ nifty: 0.177,
70
+ gold: 0.221,
71
+ },
72
+ {
73
+ month: "Dec",
74
+ flexi: 0.189,
75
+ debt: 0.052,
76
+ small: -0.031,
77
+ intl: 0.164,
78
+ liquid: 0.046,
79
+ midcap: 0.12,
80
+ nifty: 0.202,
81
+ gold: 0.245,
82
+ },
83
+ ];
84
+
85
+ // The palette has five colours, so past five the page names the few it is about in colour; the rest are muted, draw
86
+ // first in grey, each still named at its end.
87
+ const QUIET = "var(--muted-foreground)";
88
+ const series: ChartSeries<(typeof growth)[number]> = [
89
+ { key: "flexi", label: "Flexi cap", color: QUIET },
90
+ { key: "debt", label: "Debt", color: QUIET },
91
+ { key: "small", label: "Small cap", color: QUIET },
92
+ { key: "intl", label: "International", color: QUIET },
93
+ { key: "liquid", label: "Liquid", color: QUIET },
94
+ { key: "midcap", label: "Mid cap", color: QUIET },
95
+ { key: "nifty", label: "Nifty 50", color: "var(--chart-1)" },
96
+ { key: "gold", label: "Gold", color: "var(--chart-2)" },
97
+ ];
98
+
99
+ export default function ChartLineQuietExample() {
100
+ const { pct } = useFormat();
101
+ return (
102
+ <LineChartCard
103
+ title="Growth by fund"
104
+ description="Eight funds; the two you are watching in colour"
105
+ data={growth}
106
+ xKey="month"
107
+ series={series}
108
+ today="Oct"
109
+ forecastFrom="Oct"
110
+ valueFormatter={pct}
111
+ height={256}
112
+ />
113
+ );
114
+ }
@@ -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: "Program memory", 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="From sar -r, times in IST. Used excludes the page cache; program memory is what sar calls anon."
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
+ }