@siyahi/ui 0.1.9-next.22 → 0.1.9-next.23

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 (80) hide show
  1. package/DESIGN.md +3 -2
  2. package/agents/examples/accordion.tsx +7 -7
  3. package/agents/examples/alert.tsx +16 -15
  4. package/agents/examples/badge.tsx +20 -12
  5. package/agents/examples/bar-list-labels.tsx +6 -6
  6. package/agents/examples/bar-list-sides.tsx +8 -8
  7. package/agents/examples/bar-list.tsx +8 -8
  8. package/agents/examples/breadcrumb.tsx +3 -3
  9. package/agents/examples/callout.tsx +15 -15
  10. package/agents/examples/card.tsx +3 -3
  11. package/agents/examples/change-bar.tsx +21 -21
  12. package/agents/examples/chart-area.tsx +11 -11
  13. package/agents/examples/chart-bar-flows.tsx +1 -1
  14. package/agents/examples/chart-bar-hourly.tsx +1 -1
  15. package/agents/examples/chart-bar-losses.tsx +3 -3
  16. package/agents/examples/chart-bar-teams.tsx +72 -0
  17. package/agents/examples/chart-bar-years.tsx +5 -5
  18. package/agents/examples/chart-bar.tsx +10 -10
  19. package/agents/examples/chart-category-ticks.tsx +6 -6
  20. package/agents/examples/chart-line.tsx +17 -17
  21. package/agents/examples/collapsible.tsx +4 -2
  22. package/agents/examples/command.tsx +6 -6
  23. package/agents/examples/context-menu.tsx +2 -2
  24. package/agents/examples/data-bar.tsx +32 -45
  25. package/agents/examples/data-table-compact.tsx +31 -30
  26. package/agents/examples/data-table-filters.tsx +20 -20
  27. package/agents/examples/data-table.tsx +31 -30
  28. package/agents/examples/dialog.tsx +3 -3
  29. package/agents/examples/distribution-bar-tug.tsx +15 -15
  30. package/agents/examples/dropdown-menu.tsx +2 -2
  31. package/agents/examples/heatmap-calendar.tsx +6 -6
  32. package/agents/examples/heatmap-status.tsx +1 -1
  33. package/agents/examples/heatmap-weekday.tsx +7 -7
  34. package/agents/examples/input-states.tsx +9 -9
  35. package/agents/examples/input.tsx +3 -3
  36. package/agents/examples/local-time.tsx +1 -1
  37. package/agents/examples/metric-strip.tsx +8 -8
  38. package/agents/examples/page-hero.tsx +2 -2
  39. package/agents/examples/popover.tsx +3 -3
  40. package/agents/examples/price-chart.tsx +3 -3
  41. package/agents/examples/progress-tone.tsx +10 -9
  42. package/agents/examples/progress.tsx +1 -1
  43. package/agents/examples/range-position-table.tsx +31 -31
  44. package/agents/examples/range-position.tsx +18 -18
  45. package/agents/examples/section-cards-select.tsx +11 -10
  46. package/agents/examples/section-cards-trend.tsx +4 -4
  47. package/agents/examples/section-cards.tsx +13 -13
  48. package/agents/examples/select.tsx +9 -9
  49. package/agents/examples/separator.tsx +3 -3
  50. package/agents/examples/sheet.tsx +1 -1
  51. package/agents/examples/slider.tsx +1 -1
  52. package/agents/examples/surfaces.tsx +16 -18
  53. package/agents/examples/tabs.tsx +7 -7
  54. package/agents/examples/target-rows.tsx +25 -23
  55. package/agents/examples/tooltip.tsx +2 -2
  56. package/agents/examples/treemap.tsx +27 -24
  57. package/agents/manifest.json +15 -15
  58. package/dist/components/registry/charts/bar-chart-card.d.ts +1 -1
  59. package/dist/components/registry/charts/line-chart-card.d.ts +1 -1
  60. package/dist/components/registry/charts/line-chart-card.js +1 -1
  61. package/dist/components/siyahi/callout.d.ts +5 -12
  62. package/dist/components/siyahi/callout.js +5 -11
  63. package/dist/components/siyahi/status-alert.d.ts +15 -0
  64. package/dist/components/siyahi/status-alert.js +29 -0
  65. package/dist/components/siyahi/status-badge.d.ts +15 -0
  66. package/dist/components/siyahi/status-badge.js +24 -0
  67. package/dist/components/siyahi/tone-progress.d.ts +1 -1
  68. package/dist/components/siyahi/tone-progress.js +1 -1
  69. package/dist/components/siyahi/treemap.d.ts +4 -4
  70. package/dist/components/siyahi/treemap.js +2 -2
  71. package/dist/index.d.ts +5 -4
  72. package/dist/index.js +3 -2
  73. package/dist/lib/chart-frame.js +1 -1
  74. package/dist/lib/chart-series.d.ts +1 -1
  75. package/dist/lib/tone.d.ts +36 -0
  76. package/dist/lib/tone.js +35 -0
  77. package/package.json +1 -1
  78. package/agents/examples/chart-bar-sectors.tsx +0 -72
  79. package/dist/components/siyahi/warning-alert.d.ts +0 -10
  80. package/dist/components/siyahi/warning-alert.js +0 -20
@@ -11,17 +11,17 @@ import {
11
11
  type DistributionSegment,
12
12
  } from "@siyahi/ui";
13
13
 
14
- // Each closed position's net realized, ₹; made-up figures.
15
- const positions = [
16
- { name: "INFY", value: 61000 },
17
- { name: "TCS", value: 38000 },
18
- { name: "HDFCBANK", value: 17000 },
19
- { name: "ITC", value: -26000 },
20
- { name: "WIPRO", value: -14000 },
21
- { name: "SBIN", value: -6000 },
14
+ // Each finished marketing campaign's net return, ₹: sales it brought in less what it cost; made-up figures.
15
+ const campaigns = [
16
+ { name: "Festive sale", value: 61000 },
17
+ { name: "Referrals", value: 38000 },
18
+ { name: "Email win-back", value: 17000 },
19
+ { name: "Billboards", value: -26000 },
20
+ { name: "Podcast ads", value: -14000 },
21
+ { name: "Trade fair", value: -6000 },
22
22
  ];
23
- const won = positions.filter((p) => p.value > 0).reduce((sum, p) => sum + p.value, 0);
24
- const lost = positions.filter((p) => p.value < 0).reduce((sum, p) => sum + p.value, 0);
23
+ const won = campaigns.filter((c) => c.value > 0).reduce((sum, c) => sum + c.value, 0);
24
+ const lost = campaigns.filter((c) => c.value < 0).reduce((sum, c) => sum + c.value, 0);
25
25
  // One scale both ways, so whichever side reaches farther is the net.
26
26
  const reach = Math.max(won, -lost);
27
27
 
@@ -31,7 +31,7 @@ export default function DistributionBarTugExample() {
31
31
  <Card>
32
32
  <CardHeader>
33
33
  <CardTitle>The tug-of-war</CardTitle>
34
- <CardDescription>Each closed position, losses left of break-even and gains right</CardDescription>
34
+ <CardDescription>Each finished campaign, losses left of break-even and gains right</CardDescription>
35
35
  </CardHeader>
36
36
  <CardContent>
37
37
  <div className="flex flex-col gap-2">
@@ -42,7 +42,7 @@ export default function DistributionBarTugExample() {
42
42
  markers={[{ at: 0 }]}
43
43
  highlighted={focus?.name ?? null}
44
44
  onHover={setFocus}
45
- segments={positions.map(({ name, value }) => ({
45
+ segments={campaigns.map(({ name, value }) => ({
46
46
  name,
47
47
  value,
48
48
  color: value > 0 ? "var(--positive)" : "var(--negative)",
@@ -50,11 +50,11 @@ export default function DistributionBarTugExample() {
50
50
  />
51
51
  <div className="grid grid-cols-3 text-xs text-muted-foreground tabular-nums">
52
52
  <span>
53
- losers <Delta value={lost} format="money" />
53
+ lost <Delta value={lost} format="money" />
54
54
  </span>
55
55
  <span className="text-center">break-even</span>
56
56
  <span className="text-right">
57
- winners <Delta value={won} format="money" />
57
+ earned <Delta value={won} format="money" />
58
58
  </span>
59
59
  </div>
60
60
  </div>
@@ -66,7 +66,7 @@ export default function DistributionBarTugExample() {
66
66
  <Delta value={focus.value} format="money" />
67
67
  </p>
68
68
  ) : (
69
- <p className="text-muted-foreground">Hover a band to see its position.</p>
69
+ <p className="text-muted-foreground">Hover a band to see its campaign.</p>
70
70
  )}
71
71
  </CardFooter>
72
72
  </Card>
@@ -19,8 +19,8 @@ export default function DropdownMenuExample() {
19
19
  </DropdownMenuTrigger>
20
20
  <DropdownMenuContent>
21
21
  <DropdownMenuGroup>
22
- <DropdownMenuLabel>Holding</DropdownMenuLabel>
23
- <DropdownMenuItem>View lots</DropdownMenuItem>
22
+ <DropdownMenuLabel>Order</DropdownMenuLabel>
23
+ <DropdownMenuItem>View parcels</DropdownMenuItem>
24
24
  <DropdownMenuItem>Export CSV</DropdownMenuItem>
25
25
  </DropdownMenuGroup>
26
26
  <DropdownMenuSeparator />
@@ -13,7 +13,7 @@ import {
13
13
  CardTitle,
14
14
  } from "@siyahi/ui";
15
15
 
16
- // A year of trading days with a count of trades on each.
16
+ // A year of working days with a count of production deploys on each.
17
17
  const data = Array.from({ length: 365 }, (_, i) => {
18
18
  const day = new Date(Date.UTC(2025, 9, 20 + i));
19
19
  const weekday = day.getUTCDay();
@@ -29,11 +29,11 @@ export default function HeatmapCalendarExample() {
29
29
  return (
30
30
  <Card>
31
31
  <CardHeader>
32
- <CardTitle>Trades per day</CardTitle>
32
+ <CardTitle>Deploys per day</CardTitle>
33
33
  <CardDescription>The last 12 months; counts use a single-hue fade of --chart-1</CardDescription>
34
34
  </CardHeader>
35
35
  <CardContent>
36
- <CalendarHeatmap data={data} labels={{ heatmapLabel: "Trades per day over the last 12 months" }}>
36
+ <CalendarHeatmap data={data} labels={{ heatmapLabel: "Deploys per day over the last 12 months" }}>
37
37
  <CalendarHeatmapBody>
38
38
  {({ activity, dayIndex, weekIndex }) => (
39
39
  <CalendarHeatmapBlock
@@ -49,10 +49,10 @@ export default function HeatmapCalendarExample() {
49
49
  <div className="flex w-full flex-wrap items-center justify-between gap-x-6 gap-y-2">
50
50
  <p aria-live="polite" className="text-sm">
51
51
  {picked
52
- ? `${picked.date}: ${count(picked.value)} trades`
53
- : "Select a day for its trade count. Use arrow keys to move between days."}
52
+ ? `${picked.date}: ${count(picked.value)} deploys`
53
+ : "Select a day for its deploy count. Use arrow keys to move between days."}
54
54
  </p>
55
- <CalendarHeatmapLegend labels={{ less: "0 trades", more: `${count(busiest)} trades` }} />
55
+ <CalendarHeatmapLegend labels={{ less: "0 deploys", more: `${count(busiest)} deploys` }} />
56
56
  </div>
57
57
  </CalendarHeatmapFooter>
58
58
  </CalendarHeatmap>
@@ -26,7 +26,7 @@ export default function HeatmapStatusExample() {
26
26
  return (
27
27
  <Card>
28
28
  <CardHeader>
29
- <CardTitle>Price feed</CardTitle>
29
+ <CardTitle>Checkout API</CardTitle>
30
30
  <CardDescription>Daily health: healthy, degraded or critical</CardDescription>
31
31
  </CardHeader>
32
32
  <CardContent>
@@ -12,7 +12,7 @@ import {
12
12
  WeekdayHeatmapLegend,
13
13
  } from "@siyahi/ui";
14
14
 
15
- // Orders placed by weekday and hour of the trading session.
15
+ // Support tickets opened by weekday and office hour; the overnight queue lands at 9.
16
16
  const data = [1, 2, 3, 4, 5].flatMap((weekday) =>
17
17
  [9, 10, 11, 12, 13, 14, 15].map((hour) => ({
18
18
  weekday,
@@ -33,8 +33,8 @@ export default function HeatmapWeekdayExample() {
33
33
  return (
34
34
  <Card>
35
35
  <CardHeader>
36
- <CardTitle>When orders are placed</CardTitle>
37
- <CardDescription>Weekday by hour in India Standard Time, market hours only</CardDescription>
36
+ <CardTitle>When support tickets arrive</CardTitle>
37
+ <CardDescription>Weekday by hour in India Standard Time, office hours only</CardDescription>
38
38
  </CardHeader>
39
39
  {/* Seven hours by five days is a small grid: capped, it keeps square cells, and the legend and the answer
40
40
  sit beside it instead of a wide empty card. */}
@@ -53,15 +53,15 @@ export default function HeatmapWeekdayExample() {
53
53
  <div className="flex flex-col items-start gap-3 text-sm">
54
54
  <WeekdayHeatmapLegend
55
55
  className="ml-0"
56
- labels={{ less: "0 orders", more: `${count(busiest.value)} orders an hour` }}
56
+ labels={{ less: "0 tickets", more: `${count(busiest.value)} tickets an hour` }}
57
57
  />
58
58
  <p>
59
- Busiest: {DAYS[busiest.weekday]} at {hourLabel(busiest.hour)}, {count(busiest.value)} orders
59
+ Busiest: {DAYS[busiest.weekday]} at {hourLabel(busiest.hour)}, {count(busiest.value)} tickets
60
60
  </p>
61
61
  <p aria-live="polite" className="text-muted-foreground">
62
62
  {picked
63
- ? `${DAYS[picked.weekday]}, ${hourLabel(picked.hour)} IST: ${count(picked.value)} orders`
64
- : "Select a cell for its order count. Use arrow keys to move between cells."}
63
+ ? `${DAYS[picked.weekday]}, ${hourLabel(picked.hour)} IST: ${count(picked.value)} tickets`
64
+ : "Select a cell for its ticket count. Use arrow keys to move between cells."}
65
65
  </p>
66
66
  </div>
67
67
  </div>
@@ -10,23 +10,23 @@ export default function InputStatesExample() {
10
10
  </label>
11
11
  <Input id="budget" inputMode="numeric" defaultValue="25,000" aria-describedby="budget-hint" />
12
12
  <p id="budget-hint" className="text-sm text-muted-foreground">
13
- In rupees, before brokerage
13
+ In rupees, before tax
14
14
  </p>
15
15
  </div>
16
16
  <div className="grid gap-1.5">
17
- <label htmlFor="folio" className="text-sm font-medium">
18
- Folio number
17
+ <label htmlFor="pin" className="text-sm font-medium">
18
+ PIN code
19
19
  </label>
20
- <Input id="folio" defaultValue="12/34" aria-invalid aria-describedby="folio-error" />
21
- <p id="folio-error" className="text-sm text-destructive">
22
- A folio is digits only, such as 1234567
20
+ <Input id="pin" defaultValue="56/001" aria-invalid aria-describedby="pin-error" />
21
+ <p id="pin-error" className="text-sm text-destructive">
22
+ A PIN code is six digits, such as 560001
23
23
  </p>
24
24
  </div>
25
25
  <div className="grid gap-1.5">
26
- <label htmlFor="broker" className="text-sm font-medium text-muted-foreground">
27
- Broker
26
+ <label htmlFor="team" className="text-sm font-medium text-muted-foreground">
27
+ Team
28
28
  </label>
29
- <Input id="broker" defaultValue="Kite" disabled />
29
+ <Input id="team" defaultValue="Finance" disabled />
30
30
  </div>
31
31
  </div>
32
32
  );
@@ -4,14 +4,14 @@ import { SearchIcon } from "lucide-react";
4
4
  export default function InputExample() {
5
5
  return (
6
6
  <div className="flex max-w-sm flex-col gap-3">
7
- <Input placeholder="Folio number" aria-label="Folio number" />
7
+ <Input placeholder="Order number" aria-label="Order number" />
8
8
  <InputGroup>
9
9
  <InputGroupAddon>
10
10
  <SearchIcon />
11
11
  </InputGroupAddon>
12
- <InputGroupInput placeholder="Search symbols" aria-label="Search symbols" />
12
+ <InputGroupInput placeholder="Search customers" aria-label="Search customers" />
13
13
  </InputGroup>
14
- <Textarea placeholder="Note for this trade" aria-label="Note" />
14
+ <Textarea placeholder="Note for this order" aria-label="Note" />
15
15
  </div>
16
16
  );
17
17
  }
@@ -4,7 +4,7 @@ export default function LocalTimeExample() {
4
4
  return (
5
5
  <>
6
6
  <p>
7
- Prices as of <LocalTime value="2026-10-20T10:00:00Z" />. Hover the time to see it on your own clock.
7
+ Figures as of <LocalTime value="2026-10-20T10:00:00Z" />. Hover the time to see it on your own clock.
8
8
  </p>
9
9
  <p>
10
10
  Daily snapshot of <LocalTime value="2026-06-26T04:11:00Z" withDate />.
@@ -5,33 +5,33 @@ export default function MetricStripExample() {
5
5
  // trend is each figure's month-end run, oldest first.
6
6
  const items: MetricStripItem[] = [
7
7
  {
8
- label: "Portfolio value",
8
+ label: "Revenue",
9
9
  value: money(4512300),
10
10
  change: 0.031,
11
11
  note: "vs Sep",
12
12
  trend: [3820000, 3950000, 4110000, 4020000, 4380000, 4512300],
13
13
  },
14
14
  {
15
- label: "Invested",
15
+ label: "Target",
16
16
  value: moneyCompact(4025000),
17
17
  change: 85000,
18
18
  changeFormat: "money",
19
19
  trend: [3600000, 3685000, 3770000, 3855000, 3940000, 4025000],
20
20
  },
21
- { label: "XIRR", value: pct(0.142), change: -0.004, trend: [0.151, 0.149, 0.152, 0.144, 0.146, 0.142] },
21
+ { label: "Gross margin", value: pct(0.142), change: -0.004, trend: [0.151, 0.149, 0.152, 0.144, 0.146, 0.142] },
22
22
  {
23
- label: "Realised",
23
+ label: "Cash flow",
24
24
  value: moneyCompact(-61200),
25
25
  change: -61200,
26
26
  changeFormat: "money",
27
27
  trend: [14200, -3800, 9100, 2600, -18400, -61200],
28
28
  },
29
- { label: "Dividends", value: moneyCompact(38400), change: 0.18, trend: [4100, 0, 12800, 3300, 9900, 8300] },
30
- { label: "Holdings", value: count(42), note: "3 bought in Oct", trend: [38, 39, 39, 40, 39, 42] },
29
+ { label: "Gift cards", value: moneyCompact(38400), change: 0.18, trend: [4100, 0, 12800, 3300, 9900, 8300] },
30
+ { label: "Products", value: count(42), note: "3 added in Oct", trend: [38, 39, 39, 40, 39, 42] },
31
31
  ];
32
32
  return (
33
33
  <MetricStrip
34
- title="Portfolio up 3.1% in October"
34
+ title="Revenue up 3.1% in October"
35
35
  description="Month-end figures with the six-month run behind each"
36
36
  action={
37
37
  <ToggleGroup defaultValue={["1M"]} variant="outline" size="sm" aria-label="Period">
@@ -40,7 +40,7 @@ export default function MetricStripExample() {
40
40
  </ToggleGroup>
41
41
  }
42
42
  items={items}
43
- footer={<p className="text-muted-foreground">Valued at the last close, 31 Oct 2026</p>}
43
+ footer={<p className="text-muted-foreground">Booked up to 31 Oct 2026</p>}
44
44
  />
45
45
  );
46
46
  }
@@ -19,8 +19,8 @@ export default function PageHeroExample() {
19
19
  <PageHero
20
20
  eyebrow="@siyahi/ui"
21
21
  title="Siyahi"
22
- lead="Ink for numbers. A design system for pages people read figures from: portfolios, ledgers, research."
23
- detail="Stock shadcn/ui on Base UI and Tailwind v4, with a finance theme, charts and tables that fit a phone, Indian-aware formatters and a lint. Siyahi is Hindi for ink."
22
+ lead="Ink for numbers. A design system for pages people read figures from: dashboards, ledgers, reports."
23
+ detail="Stock shadcn/ui on Base UI and Tailwind v4, with a theme for figures, charts and tables that fit a phone, Indian-aware formatters and a lint. Siyahi is Hindi for ink."
24
24
  actions={
25
25
  <>
26
26
  <Button nativeButton={false} render={<a href="#/data" />}>
@@ -11,11 +11,11 @@ import {
11
11
  export default function PopoverExample() {
12
12
  return (
13
13
  <Popover>
14
- <PopoverTrigger render={<Button variant="outline" className="w-fit" />}>How is this priced?</PopoverTrigger>
14
+ <PopoverTrigger render={<Button variant="outline" className="w-fit" />}>How is this counted?</PopoverTrigger>
15
15
  <PopoverContent align="start">
16
16
  <PopoverHeader>
17
- <PopoverTitle>Last close</PopoverTitle>
18
- <PopoverDescription>Holdings are valued at the exchange's last closing price.</PopoverDescription>
17
+ <PopoverTitle>Paid orders</PopoverTitle>
18
+ <PopoverDescription>Revenue counts paid orders, less refunds, on the day each was placed.</PopoverDescription>
19
19
  </PopoverHeader>
20
20
  </PopoverContent>
21
21
  </Popover>
@@ -1,6 +1,6 @@
1
1
  import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, PriceChart } from "@siyahi/ui";
2
2
 
3
- // A made-up daily close series for one year.
3
+ // A made-up daily series for one year: the average order value, in rupees.
4
4
  const data = Array.from({ length: 250 }, (_, i) => {
5
5
  const day = new Date(Date.UTC(2025, 9, 20 + Math.floor((i * 7) / 5)));
6
6
  return { time: day.toISOString().slice(0, 10), value: 1500 + i * 1.2 + Math.sin(i / 9) * 60 + Math.sin(i / 3) * 18 };
@@ -10,8 +10,8 @@ export default function PriceChartExample() {
10
10
  return (
11
11
  <Card>
12
12
  <CardHeader>
13
- <CardTitle>INFY</CardTitle>
14
- <CardDescription>Daily close, one year</CardDescription>
13
+ <CardTitle>Average order value</CardTitle>
14
+ <CardDescription>Daily, one year, ₹</CardDescription>
15
15
  </CardHeader>
16
16
  <CardContent>
17
17
  <PriceChart data={data} height={256} />
@@ -1,22 +1,23 @@
1
1
  import { ToneProgress, useFormat } from "@siyahi/ui";
2
2
 
3
- const positions = [
4
- { symbol: "INFY", realized: 84200, share: 0.41 },
5
- { symbol: "ITC", realized: -61200, share: 0.3 },
6
- { symbol: "TCS", realized: 21000, share: 0.1 },
3
+ // Each sales channel's profit or loss this quarter, and its share of all the profit and loss booked; made-up figures.
4
+ const channels = [
5
+ { channel: "Online", profit: 84200, share: 0.41 },
6
+ { channel: "Retail", profit: -61200, share: 0.3 },
7
+ { channel: "Export", profit: 21000, share: 0.1 },
7
8
  ];
8
9
 
9
10
  export default function ProgressToneExample() {
10
11
  const { pct } = useFormat();
11
12
  return (
12
13
  <div className="flex max-w-sm flex-col gap-3 text-sm">
13
- {positions.map((p) => (
14
- <div key={p.symbol} className="flex items-center gap-3">
15
- <span className="w-16 font-medium">{p.symbol}</span>
14
+ {channels.map((p) => (
15
+ <div key={p.channel} className="flex items-center gap-3">
16
+ <span className="w-16 font-medium">{p.channel}</span>
16
17
  <ToneProgress
17
- tone={p.realized >= 0 ? "positive" : "negative"}
18
+ tone={p.profit >= 0 ? "positive" : "negative"}
18
19
  value={p.share * 100}
19
- aria-label={`${p.symbol}'s share of the booked P&L`}
20
+ aria-label={`${p.channel}'s share of the quarter's profit and loss`}
20
21
  getAriaValueText={() => pct(p.share)}
21
22
  className="w-24"
22
23
  />
@@ -3,7 +3,7 @@ import { Progress, ProgressLabel, ProgressValue } from "@siyahi/ui";
3
3
  export default function ProgressExample() {
4
4
  return (
5
5
  <Progress value={64} className="max-w-sm">
6
- <ProgressLabel>Statements imported</ProgressLabel>
6
+ <ProgressLabel>Orders imported</ProgressLabel>
7
7
  <ProgressValue />
8
8
  </Progress>
9
9
  );
@@ -16,61 +16,61 @@ import {
16
16
  type DataTableColumnDef,
17
17
  } from "@siyahi/ui";
18
18
 
19
- interface Holding {
20
- symbol: string;
21
- /** Last close and the 52-week low and high closes, in rupees; made-up figures. */
22
- close: number;
19
+ interface Service {
20
+ service: string;
21
+ /** Today's 95th-percentile response time and the fastest and slowest day of the last 30, in ms; made-up figures. */
22
+ today: number;
23
23
  low: number;
24
24
  high: number;
25
- /** How far up its range the close sits, 0 at the low and 1 at the high, so the column sorts. */
25
+ /** How far up its range today sits, 0 at the fastest day and 1 at the slowest, so the column sorts. */
26
26
  position: number;
27
27
  }
28
28
 
29
- const holding = (symbol: string, close: number, low: number, high: number): Holding => ({
30
- symbol,
31
- close,
29
+ const service = (name: string, today: number, low: number, high: number): Service => ({
30
+ service: name,
31
+ today,
32
32
  low,
33
33
  high,
34
- position: (close - low) / (high - low),
34
+ position: (today - low) / (high - low),
35
35
  });
36
36
 
37
- const holdings: Holding[] = [
38
- holding("NIFTYBEES", 284, 241.2, 291.8),
39
- holding("INFY", 1870, 1307, 2006.45),
40
- holding("ICICIBANK", 1290, 1051.05, 1362.35),
41
- holding("TCS", 4150, 3591.5, 4592.25),
42
- holding("ITC", 460, 399.35, 528.5),
43
- holding("HDFCBANK", 1750, 1613.6, 2027.4),
37
+ const services: Service[] = [
38
+ service("search", 284, 241, 292),
39
+ service("catalogue", 187, 131, 201),
40
+ service("checkout", 329, 265, 342),
41
+ service("images", 415, 359, 459),
42
+ service("payments", 460, 399, 529),
43
+ service("login", 175, 161, 203),
44
44
  ];
45
45
 
46
- function Price({ amount }: { amount: number }) {
47
- return useFormat().money(amount, 2);
46
+ function Milliseconds({ value }: { value: number }) {
47
+ return `${useFormat().count(value)} ms`;
48
48
  }
49
49
 
50
50
  const header = () => <DataTableSortHeader />;
51
51
 
52
- const columns: DataTableColumnDef<Holding>[] = [
53
- { accessorKey: "symbol", header, size: 130, meta: { label: "Symbol", compact: true } },
52
+ const columns: DataTableColumnDef<Service>[] = [
53
+ { accessorKey: "service", header, size: 130, meta: { label: "Service", compact: true } },
54
54
  {
55
- accessorKey: "close",
55
+ accessorKey: "today",
56
56
  header,
57
57
  size: 120,
58
- meta: { label: "Close", variant: "number" },
59
- cell: ({ row }) => <Price amount={row.original.close} />,
58
+ meta: { label: "p95 today", variant: "number" },
59
+ cell: ({ row }) => <Milliseconds value={row.original.today} />,
60
60
  },
61
61
  {
62
62
  accessorKey: "position",
63
63
  header,
64
64
  size: 200,
65
- meta: { label: "52-week range", compact: true },
65
+ meta: { label: "30-day range", compact: true },
66
66
  cell: ({ row }) => (
67
67
  <RangePosition
68
68
  variant="compact"
69
69
  low={row.original.low}
70
70
  high={row.original.high}
71
- value={row.original.close}
72
- lowLabel="52-week low"
73
- highLabel="52-week high"
71
+ value={row.original.today}
72
+ lowLabel="30-day fastest"
73
+ highLabel="30-day slowest"
74
74
  />
75
75
  ),
76
76
  },
@@ -80,17 +80,17 @@ export default function RangePositionTableExample() {
80
80
  return (
81
81
  <Card>
82
82
  <CardHeader>
83
- <CardTitle>NIFTYBEES trades near its 52-week high, HDFCBANK near its low</CardTitle>
83
+ <CardTitle>Search is near its slowest of the month, login near its fastest</CardTitle>
84
84
  <CardDescription>
85
- Each close on a track from the year's low close to its high; sort to rank them
85
+ Each service's response time today on a track from its fastest day to its slowest; sort to rank them
86
86
  </CardDescription>
87
87
  </CardHeader>
88
88
  <CardContent>
89
- <DataTableRoot data={holdings} columns={columns}>
89
+ <DataTableRoot data={services} columns={columns}>
90
90
  <DataTableToolbarSection>
91
91
  <DataTableCompactColumnsToggle />
92
92
  </DataTableToolbarSection>
93
- <DataTable aria-label="Holdings in their 52-week range">
93
+ <DataTable aria-label="Services in their 30-day range">
94
94
  <DataTableHeader />
95
95
  <DataTableBody />
96
96
  </DataTable>
@@ -10,42 +10,42 @@ import {
10
10
  useFormat,
11
11
  } from "@siyahi/ui";
12
12
 
13
- // HDFCBANK over the last 52 weeks; made-up figures.
14
- const low = 1613.6;
15
- const high = 2027.4;
16
- const close = 1750.0;
13
+ // Checkout's daily 95th-percentile response time over the last 30 days, in ms; made-up figures.
14
+ const low = 161;
15
+ const high = 203;
16
+ const today = 175;
17
17
 
18
18
  export default function RangePositionExample() {
19
19
  const f = useFormat();
20
- const price = (value: number) => f.money(value, 2);
20
+ const ms = (value: number) => `${f.count(value)} ms`;
21
21
  return (
22
22
  // Side by side once the card, not the screen, has room: in a narrow panel on a wide screen they stack.
23
23
  <Card className="@container/range">
24
24
  <CardHeader>
25
- <CardTitle>HDFCBANK sits {f.pct((close - low) / (high - low), 0)} of the way up its 52-week range</CardTitle>
26
- <CardDescription>The last close against the year's lowest and highest close</CardDescription>
25
+ <CardTitle>Checkout sits {f.pct((today - low) / (high - low), 0)} of the way up its 30-day range</CardTitle>
26
+ <CardDescription>Today's response time against the month's fastest and slowest day</CardDescription>
27
27
  </CardHeader>
28
28
  <CardContent>
29
29
  <div className="flex flex-col gap-8 @xl/range:flex-row @xl/range:items-end">
30
30
  <DataList className="@xl/range:w-56 @xl/range:shrink-0">
31
- <DataListItem label="52-week low, 7 months ago">
32
- <span className="tabular-nums">{price(low)}</span>
31
+ <DataListItem label="Fastest day, 3 weeks ago">
32
+ <span className="tabular-nums">{ms(low)}</span>
33
33
  </DataListItem>
34
- <DataListItem label="52-week high, 11 weeks ago">
35
- <span className="tabular-nums">{price(high)}</span>
34
+ <DataListItem label="Slowest day, 9 days ago">
35
+ <span className="tabular-nums">{ms(high)}</span>
36
36
  </DataListItem>
37
- <DataListItem label="Last close">
38
- <span className="tabular-nums">{price(close)}</span>
37
+ <DataListItem label="Today, 95th percentile">
38
+ <span className="tabular-nums">{ms(today)}</span>
39
39
  </DataListItem>
40
40
  </DataList>
41
41
  <RangePosition
42
42
  low={low}
43
43
  high={high}
44
- value={close}
45
- lowLabel="52-week low"
46
- highLabel="52-week high"
47
- caption="of the way up the 52-week range"
48
- valueFormatter={price}
44
+ value={today}
45
+ lowLabel="30-day fastest"
46
+ highLabel="30-day slowest"
47
+ caption="of the way up the 30-day range"
48
+ valueFormatter={ms}
49
49
  className="@xl/range:flex-1"
50
50
  />
51
51
  </div>
@@ -1,25 +1,26 @@
1
1
  import { Delta, SectionCards, SiyahiProvider, useFormat, type SectionCard } from "@siyahi/ui";
2
2
  import { useState } from "react";
3
3
 
4
- const classes = [
5
- { label: "All", net: 110200, positions: 181 },
6
- { label: "Equity", net: 171400, positions: 164 },
7
- { label: "Gold bonds", net: 0, positions: 0 },
8
- { label: "F&O", net: -61200, positions: 17 },
4
+ // Each sales channel's profit this quarter and its orders; made-up figures.
5
+ const channels = [
6
+ { label: "All", net: 110200, orders: 181 },
7
+ { label: "Online", net: 171400, orders: 164 },
8
+ { label: "Wholesale", net: 0, orders: 0 },
9
+ { label: "Marketplace", net: -61200, orders: 17 },
9
10
  ];
10
11
 
11
12
  export default function SectionCardsSelectExample() {
12
13
  const [scope, setScope] = useState("All");
13
14
  const { count } = useFormat();
14
- const items: SectionCard[] = classes.map((c) => ({
15
+ const items: SectionCard[] = channels.map((c) => ({
15
16
  label: c.label,
16
17
  value: <Delta value={c.net} format="money" />,
17
- detail: `${count(c.positions)} positions`,
18
- // Nothing to show for a class with no positions, so it cannot be picked.
19
- disabled: c.positions === 0,
18
+ detail: `${count(c.orders)} orders`,
19
+ // Nothing to show for a channel with no orders, so it cannot be picked.
20
+ disabled: c.orders === 0,
20
21
  }));
21
22
  return (
22
- // On a ruled surface the tiles part with hairlines, as on a trading screen, instead of sitting as cards.
23
+ // On a ruled surface the tiles part with hairlines, as on a dense operations screen, instead of sitting as cards.
23
24
  <SiyahiProvider surface="ruled">
24
25
  <div className="flex flex-col gap-3">
25
26
  <SectionCards items={items} selected={scope} onSelect={setScope} />
@@ -4,14 +4,14 @@ export default function SectionCardsTrendExample() {
4
4
  const { money, moneyCompact } = useFormat();
5
5
  const items: SectionCard[] = [
6
6
  {
7
- label: "Portfolio value",
7
+ label: "Revenue",
8
8
  value: money(4512300),
9
9
  badge: <Delta value={0.031} />,
10
10
  trend: <Sparkline data={[3820000, 3950000, 4110000, 4020000, 4380000, 4512300]} />,
11
11
  detail: "Month-end, last six months",
12
12
  },
13
13
  {
14
- label: "Realised this year",
14
+ label: "Cash flow this year",
15
15
  value: moneyCompact(-61200),
16
16
  badge: <Delta value={-61200} format="money" />,
17
17
  // A run of losses: the meaning colour, not a chart slot.
@@ -19,11 +19,11 @@ export default function SectionCardsTrendExample() {
19
19
  detail: "Running total since April",
20
20
  },
21
21
  {
22
- label: "Dividends this year",
22
+ label: "Gift cards this year",
23
23
  value: moneyCompact(38400),
24
24
  badge: <Delta value={0.18} />,
25
25
  trend: <Sparkline data={[4100, 0, 12800, 3300, 9900, 8300]} variant="line" curve="linear" />,
26
- detail: "Credited each month",
26
+ detail: "Sold each month",
27
27
  },
28
28
  ];
29
29
  return <SectionCards items={items} />;