@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
@@ -4,38 +4,38 @@ export default function SectionCardsExample() {
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
  headline: "Up for the third month",
11
- detail: "Valued at the last close",
11
+ detail: "Paid orders, less refunds",
12
12
  },
13
13
  {
14
- label: "Invested",
14
+ label: "Target",
15
15
  value: money(4025000),
16
- headline: "SIPs on the 5th and 20th",
17
- detail: "Across 4 accounts",
16
+ headline: "Set at the start of the quarter",
17
+ detail: "Across 4 stores",
18
18
  },
19
19
  {
20
- label: "Unrealised gain",
20
+ label: "Ahead of target",
21
21
  value: moneyCompact(487300),
22
22
  badge: <Delta value={0.121} />,
23
- headline: "XIRR 14.2%",
24
- detail: "Since the first buy",
23
+ headline: "Gross margin 14.2%",
24
+ detail: "Since April",
25
25
  },
26
26
  {
27
- label: "Realised this year",
27
+ label: "Cash flow this year",
28
28
  value: moneyCompact(-61200),
29
29
  badge: <Delta value={-61200} format="money" />,
30
- headline: "Two loss-making exits",
30
+ headline: "Two large inventory buys",
31
31
  detail: "Before tax",
32
32
  },
33
33
  {
34
- label: "Dividends this year",
34
+ label: "Gift cards this year",
35
35
  value: moneyCompact(38400),
36
36
  badge: <Delta value={0.18} />,
37
- headline: "From 11 holdings",
38
- detail: "Credited to the bank",
37
+ headline: "Sold in 11 stores",
38
+ detail: "Paid at purchase",
39
39
  },
40
40
  ];
41
41
  return (
@@ -1,23 +1,23 @@
1
1
  import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@siyahi/ui";
2
2
 
3
- const accounts = [
4
- { label: "All accounts", value: "all" },
5
- { label: "Equity", value: "equity" },
6
- { label: "Mutual funds", value: "funds" },
7
- { label: "Bonds", value: "bonds" },
3
+ const stores = [
4
+ { label: "All stores", value: "all" },
5
+ { label: "Online", value: "online" },
6
+ { label: "Retail", value: "retail" },
7
+ { label: "Wholesale", value: "wholesale" },
8
8
  ];
9
9
 
10
10
  export default function SelectExample() {
11
11
  return (
12
- <Select items={accounts} defaultValue="all">
12
+ <Select items={stores} defaultValue="all">
13
13
  <SelectTrigger className="w-48">
14
14
  <SelectValue />
15
15
  </SelectTrigger>
16
16
  <SelectContent>
17
17
  <SelectGroup>
18
- {accounts.map((account) => (
19
- <SelectItem key={account.value} value={account.value}>
20
- {account.label}
18
+ {stores.map((store) => (
19
+ <SelectItem key={store.value} value={store.value}>
20
+ {store.label}
21
21
  </SelectItem>
22
22
  ))}
23
23
  </SelectGroup>
@@ -3,11 +3,11 @@ import { Separator } from "@siyahi/ui";
3
3
  export default function SeparatorExample() {
4
4
  return (
5
5
  <div className="flex h-6 items-center gap-4 text-sm">
6
- <span>Equity</span>
6
+ <span>Orders</span>
7
7
  <Separator orientation="vertical" />
8
- <span>Debt</span>
8
+ <span>Customers</span>
9
9
  <Separator orientation="vertical" />
10
- <span>Gold</span>
10
+ <span>Products</span>
11
11
  </div>
12
12
  );
13
13
  }
@@ -7,7 +7,7 @@ export default function SheetExample() {
7
7
  <SheetContent>
8
8
  <SheetHeader>
9
9
  <SheetTitle>Filters</SheetTitle>
10
- <SheetDescription>Narrow the ledger by account, symbol or date.</SheetDescription>
10
+ <SheetDescription>Narrow the orders by store, status or date.</SheetDescription>
11
11
  </SheetHeader>
12
12
  </SheetContent>
13
13
  </Sheet>
@@ -1,5 +1,5 @@
1
1
  import { Slider } from "@siyahi/ui";
2
2
 
3
3
  export default function SliderExample() {
4
- return <Slider defaultValue={[20, 80]} max={100} step={5} aria-label="Allocation band" className="max-w-sm" />;
4
+ return <Slider defaultValue={[20, 80]} max={100} step={5} aria-label="Price range" className="max-w-sm" />;
5
5
  }
@@ -32,19 +32,19 @@ const orders = [
32
32
  { hour: 15, orders: 38 },
33
33
  ];
34
34
 
35
- const holdings = [
36
- { symbol: "ITC", value: 276000 },
37
- { symbol: "INFY", value: 224400 },
38
- { symbol: "TCS", value: 166000 },
35
+ const products = [
36
+ { product: "Dinner set", revenue: 276000 },
37
+ { product: "Standing desk", revenue: 224400 },
38
+ { product: "Bookshelf", revenue: 166000 },
39
39
  ];
40
40
 
41
41
  function Dashboard() {
42
42
  const { money, moneyCompact, pct } = useFormat();
43
43
  const kpis: MetricStripItem[] = [
44
- { label: "Portfolio value", value: money(4512300), change: 0.031 },
45
- { label: "Invested", value: moneyCompact(4025000), change: 85000, changeFormat: "money" },
46
- { label: "XIRR", value: pct(0.142), change: -0.004 },
47
- { label: "Realised", value: moneyCompact(-61200), change: -61200, changeFormat: "money" },
44
+ { label: "Revenue", value: money(4512300), change: 0.031 },
45
+ { label: "Target", value: moneyCompact(4025000), change: 85000, changeFormat: "money" },
46
+ { label: "Gross margin", value: pct(0.142), change: -0.004 },
47
+ { label: "Cash flow", value: moneyCompact(-61200), change: -61200, changeFormat: "money" },
48
48
  ];
49
49
  return (
50
50
  <div className="flex flex-col gap-6">
@@ -61,24 +61,22 @@ function Dashboard() {
61
61
  />
62
62
  <Card>
63
63
  <CardHeader>
64
- <CardTitle>Holdings</CardTitle>
65
- <CardDescription>Largest three</CardDescription>
64
+ <CardTitle>Top products</CardTitle>
65
+ <CardDescription>Largest three by revenue</CardDescription>
66
66
  </CardHeader>
67
67
  <CardContent>
68
68
  <Table>
69
69
  <TableHeader>
70
70
  <TableRow>
71
- <TableHead>Symbol</TableHead>
72
- <TableHead>Value</TableHead>
71
+ <TableHead>Product</TableHead>
72
+ <TableHead>Revenue</TableHead>
73
73
  </TableRow>
74
74
  </TableHeader>
75
75
  <TableBody>
76
- {holdings.map((row) => (
77
- <TableRow key={row.symbol}>
78
- <TableCell>
79
- <span className="font-mono">{row.symbol}</span>
80
- </TableCell>
81
- <TableCell>{money(row.value)}</TableCell>
76
+ {products.map((row) => (
77
+ <TableRow key={row.product}>
78
+ <TableCell>{row.product}</TableCell>
79
+ <TableCell>{money(row.revenue)}</TableCell>
82
80
  </TableRow>
83
81
  ))}
84
82
  </TableBody>
@@ -2,15 +2,15 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@siyahi/ui";
2
2
 
3
3
  export default function TabsExample() {
4
4
  return (
5
- <Tabs defaultValue="holdings">
5
+ <Tabs defaultValue="orders">
6
6
  <TabsList>
7
- <TabsTrigger value="holdings">Holdings</TabsTrigger>
8
- <TabsTrigger value="realized">Realized</TabsTrigger>
9
- <TabsTrigger value="cash">Cash flow</TabsTrigger>
7
+ <TabsTrigger value="orders">Orders</TabsTrigger>
8
+ <TabsTrigger value="returns">Returns</TabsTrigger>
9
+ <TabsTrigger value="payouts">Payouts</TabsTrigger>
10
10
  </TabsList>
11
- <TabsContent value="holdings">What you own today, valued at the last close.</TabsContent>
12
- <TabsContent value="realized">Gains and losses booked by selling.</TabsContent>
13
- <TabsContent value="cash">Money in and out of every account.</TabsContent>
11
+ <TabsContent value="orders">Every order placed, newest first.</TabsContent>
12
+ <TabsContent value="returns">Items sent back and the refunds paid for them.</TabsContent>
13
+ <TabsContent value="payouts">Money paid out to sellers each week.</TabsContent>
14
14
  </Tabs>
15
15
  );
16
16
  }
@@ -10,59 +10,61 @@ import {
10
10
  type TargetStatus,
11
11
  } from "@siyahi/ui";
12
12
 
13
- interface Sleeve {
13
+ interface Team {
14
14
  name: string;
15
- holdings: string;
16
- /** Today's share of the portfolio and the plan's share, as fractions; made-up figures. */
15
+ costs: string;
16
+ /** The team's share of this year's spend so far and the budget's share, as fractions; made-up figures. */
17
17
  weight: number;
18
18
  target: number;
19
19
  }
20
20
 
21
- const sleeves: Sleeve[] = [
22
- { name: "Large-cap equity", holdings: "HDFCBANK, ICICIBANK, INFY, TCS", weight: 0.426, target: 0.4 },
23
- { name: "Mid and small cap", holdings: "Two mid-cap funds", weight: 0.189, target: 0.2 },
24
- { name: "Debt", holdings: "Corporate bond fund, PPF", weight: 0.194, target: 0.25 },
25
- { name: "Gold", holdings: "GOLDBEES, Sovereign Gold Bonds", weight: 0.093, target: 0.1 },
26
- { name: "International", holdings: "Nasdaq 100 fund of funds", weight: 0.098, target: 0.05 },
21
+ const teams: Team[] = [
22
+ { name: "Engineering", costs: "Cloud hosting, tools, contractors", weight: 0.426, target: 0.4 },
23
+ { name: "Marketing", costs: "Ads, events, design agency", weight: 0.189, target: 0.2 },
24
+ { name: "Sales", costs: "Travel, commissions, CRM seats", weight: 0.194, target: 0.25 },
25
+ { name: "Support", costs: "Help desk seats, training", weight: 0.093, target: 0.1 },
26
+ { name: "Operations", costs: "Office rent, facilities", weight: 0.098, target: 0.05 },
27
27
  ];
28
28
 
29
- // Within two points of the plan is on target; past five is far enough to rebalance.
29
+ // Within two points of the budget is on target; past five is far enough to review it.
30
30
  const NEAR = 0.02;
31
31
  const FAR = 0.05;
32
32
 
33
33
  const pts = (value: number) => `${(value * 100).toFixed(1)} pts`;
34
34
 
35
- function statusOf({ weight, target }: Sleeve): TargetStatus {
35
+ function statusOf({ weight, target }: Team): TargetStatus {
36
36
  const gap = weight - target;
37
37
  const size = `${pts(Math.abs(gap))} ${gap > 0 ? "over" : "under"}`;
38
38
  if (Math.abs(gap) <= NEAR) return { kind: "met", label: "On target" };
39
39
  if (Math.abs(gap) <= FAR) return { kind: "missed", label: size };
40
- return { kind: "warning", label: `${size}, rebalance` };
40
+ return { kind: "warning", label: `${size}, review` };
41
41
  }
42
42
 
43
43
  export default function TargetRowsExample() {
44
44
  const f = useFormat();
45
- const rows: TargetRow[] = sleeves.map((sleeve) => ({
46
- label: sleeve.name,
47
- detail: sleeve.holdings,
48
- value: sleeve.weight,
49
- target: sleeve.target,
45
+ const rows: TargetRow[] = teams.map((team) => ({
46
+ label: team.name,
47
+ detail: team.costs,
48
+ value: team.weight,
49
+ target: team.target,
50
50
  bands: [
51
- [sleeve.target - FAR, sleeve.target + FAR],
52
- [sleeve.target - NEAR, sleeve.target + NEAR],
51
+ [team.target - FAR, team.target + FAR],
52
+ [team.target - NEAR, team.target + NEAR],
53
53
  ],
54
- status: statusOf(sleeve),
54
+ status: statusOf(team),
55
55
  }));
56
56
  return (
57
57
  <Card>
58
58
  <CardHeader>
59
- <CardTitle>Debt is 5.6 points under its target</CardTitle>
60
- <CardDescription>Each sleeve's share of the portfolio against the plan, on one 0–50% scale</CardDescription>
59
+ <CardTitle>Sales is 5.6 points under its budget</CardTitle>
60
+ <CardDescription>
61
+ Each team's share of spend against its share of the budget, on one 0–50% scale
62
+ </CardDescription>
61
63
  </CardHeader>
62
64
  <CardContent>
63
65
  <div className="grid gap-2">
64
66
  <p className="text-sm text-muted-foreground">
65
- Bar: today's weight. Tall tick: the target. Shading: within 5 points of it, darker within 2.
67
+ Bar: the share spent so far. Tall tick: the budgeted share. Shading: within 5 points of it, darker within 2.
66
68
  </p>
67
69
  <TargetRows rows={rows} domain={[0, 0.5]} valueFormatter={(value) => f.pct(value)} />
68
70
  </div>
@@ -4,10 +4,10 @@ import { InfoIcon } from "lucide-react";
4
4
  export default function TooltipExample() {
5
5
  return (
6
6
  <Tooltip>
7
- <TooltipTrigger render={<Button variant="outline" size="icon" aria-label="About XIRR" />}>
7
+ <TooltipTrigger render={<Button variant="outline" size="icon" aria-label="About churn" />}>
8
8
  <InfoIcon />
9
9
  </TooltipTrigger>
10
- <TooltipContent>XIRR weighs every cash flow by its date.</TooltipContent>
10
+ <TooltipContent>Churn counts customers who did not renew this month.</TooltipContent>
11
11
  </Tooltip>
12
12
  );
13
13
  }
@@ -14,42 +14,45 @@ import {
14
14
  } from "@siyahi/ui";
15
15
  import { useState } from "react";
16
16
 
17
- interface Holding extends TreemapItem {
18
- broker: string;
17
+ interface City extends TreemapItem {
18
+ channel: string;
19
19
  }
20
20
 
21
- // change is the return since bought; LT came in as a transfer, with no cost basis.
22
- const holdings: Holding[] = [
23
- { name: "INFY", key: "INFY-kite", broker: "Kite", group: "IT", weight: 224400, change: 0.38 },
24
- { name: "INFY", key: "INFY-dhan", broker: "Dhan", group: "IT", weight: 152000, change: 0.12 },
25
- { name: "TCS", broker: "Kite", group: "IT", weight: 166000, change: 0.09 },
26
- { name: "WIPRO", broker: "Dhan", group: "IT", weight: 98000, change: -0.21 },
27
- { name: "HDFCBANK", broker: "Kite", group: "Banks", weight: 262500, change: -0.06 },
28
- { name: "ICICIBANK", broker: "Kite", group: "Banks", weight: 258000, change: 0.44 },
29
- { name: "SBIN", broker: "Dhan", group: "Banks", weight: 87000, change: 0.58 },
30
- { name: "ITC", broker: "Kite", group: "FMCG", weight: 276000, change: 0.27 },
31
- { name: "ASIANPAINT", broker: "Dhan", group: "FMCG", weight: 64000, change: -0.33 },
32
- { name: "NIFTYBEES", broker: "Kite", group: "ETF", weight: 255600, change: 0.16 },
33
- { name: "LT", broker: "Dhan", group: "Construction", weight: 52000, change: null },
21
+ // weight is the month's sales in ₹ and change their growth on the same month last year; Guwahati opened this year,
22
+ // so it has no last year to grow from. Mumbai sells online and in stores, so it draws two tiles under one name.
23
+ const cities: City[] = [
24
+ { name: "Mumbai", key: "mumbai-online", channel: "Online", group: "West", weight: 224400, change: 0.38 },
25
+ { name: "Mumbai", key: "mumbai-stores", channel: "Stores", group: "West", weight: 152000, change: 0.12 },
26
+ { name: "Pune", channel: "Stores", group: "West", weight: 166000, change: 0.09 },
27
+ { name: "Surat", channel: "Online", group: "West", weight: 98000, change: -0.21 },
28
+ { name: "Bengaluru", channel: "Stores", group: "South", weight: 262500, change: -0.06 },
29
+ { name: "Chennai", channel: "Stores", group: "South", weight: 258000, change: 0.44 },
30
+ { name: "Kochi", channel: "Online", group: "South", weight: 87000, change: 0.58 },
31
+ { name: "Delhi", channel: "Stores", group: "North", weight: 276000, change: 0.27 },
32
+ { name: "Jaipur", channel: "Online", group: "North", weight: 64000, change: -0.33 },
33
+ { name: "Kolkata", channel: "Stores", group: "East", weight: 255600, change: 0.16 },
34
+ { name: "Guwahati", channel: "Online", group: "Northeast", weight: 52000, change: null },
34
35
  ];
35
36
 
36
37
  export default function TreemapExample() {
37
- const [hovered, setHovered] = useState<Holding | null>(null);
38
- const [selected, setSelected] = useState<Holding | null>(null);
38
+ const [hovered, setHovered] = useState<City | null>(null);
39
+ const [selected, setSelected] = useState<City | null>(null);
39
40
  const { money, pct } = useFormat();
40
- const figures = (h: Holding) =>
41
- `${money(h.weight)} · ${h.change === null ? "no cost basis" : `${h.change < 0 ? "▼" : "▲"} ${pct(Math.abs(h.change))}`}`;
41
+ const figures = (c: City) =>
42
+ `${money(c.weight)} · ${c.change === null ? "new this year" : `${c.change < 0 ? "\u2212" : "+"}${pct(Math.abs(c.change))}`}`;
42
43
  return (
43
44
  <Card>
44
45
  <CardHeader>
45
- <CardTitle>Holdings by sector</CardTitle>
46
- <CardDescription>Area is the holding's value; colour is its return, deepest at ±60%</CardDescription>
46
+ <CardTitle>Sales by region</CardTitle>
47
+ <CardDescription>
48
+ Area is the city's sales this month; colour is its growth on last year, deepest at ±60%
49
+ </CardDescription>
47
50
  </CardHeader>
48
51
  <CardContent>
49
52
  <Tooltip open={hovered !== null} trackCursorAxis="both">
50
53
  <TooltipTrigger render={<div />}>
51
54
  <Treemap
52
- items={holdings}
55
+ items={cities}
53
56
  height={320}
54
57
  range={0.6}
55
58
  onHover={setHovered}
@@ -62,7 +65,7 @@ export default function TreemapExample() {
62
65
  {hovered && (
63
66
  <>
64
67
  <span className="font-medium">
65
- {hovered.name} · {hovered.broker}
68
+ {hovered.name} · {hovered.channel}
66
69
  </span>
67
70
  <span>{hovered.group}</span>
68
71
  <span>{figures(hovered)}</span>
@@ -76,7 +79,7 @@ export default function TreemapExample() {
76
79
  {selected ? (
77
80
  <>
78
81
  <span className="font-medium">
79
- {selected.name} · {selected.broker}
82
+ {selected.name} · {selected.channel}
80
83
  </span>{" "}
81
84
  · {selected.group} · {figures(selected)}
82
85
  </>
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "needs": [
18
18
  {
19
- "need": "Values over time or another ordered axis (months, hours, price buckets)",
19
+ "need": "Values over time or another ordered axis (months, hours, size buckets)",
20
20
  "guidance": "`BarChartCard`, `AreaChartCard` or `LineChartCard`",
21
21
  "components": [
22
22
  "BarChartCard",
@@ -32,14 +32,14 @@
32
32
  ]
33
33
  },
34
34
  {
35
- "need": "A running level, such as a portfolio's value against money put in",
35
+ "need": "A running level, such as revenue against its target",
36
36
  "guidance": "`AreaChartCard`",
37
37
  "components": [
38
38
  "AreaChartCard"
39
39
  ]
40
40
  },
41
41
  {
42
- "need": "Series compared point by point, such as a return against an index",
42
+ "need": "Series compared point by point, such as growth against a benchmark",
43
43
  "guidance": "`LineChartCard`",
44
44
  "components": [
45
45
  "LineChartCard"
@@ -53,7 +53,7 @@
53
53
  ]
54
54
  },
55
55
  {
56
- "need": "Long category names, such as sectors",
56
+ "need": "Long category names, such as teams or product categories",
57
57
  "guidance": "`BarChartCard` with `horizontal`",
58
58
  "components": [
59
59
  "BarChartCard"
@@ -118,28 +118,28 @@
118
118
  ]
119
119
  },
120
120
  {
121
- "need": "Figures against their targets, such as allocation against plan",
121
+ "need": "Figures against their targets, such as spend against budget",
122
122
  "guidance": "`TargetRows`, with neutral `bands` and a `status` per row",
123
123
  "components": [
124
124
  "TargetRows"
125
125
  ]
126
126
  },
127
127
  {
128
- "need": "Where a value sits in its range, such as a price in its 52-week range",
128
+ "need": "Where a value sits in its range, such as today's response time in its 30-day range",
129
129
  "guidance": "`RangePosition`; `variant=\"compact\"` in a table cell",
130
130
  "components": [
131
131
  "RangePosition"
132
132
  ]
133
133
  },
134
134
  {
135
- "need": "One instrument's price history",
135
+ "need": "A long daily series, such as a price or an order value",
136
136
  "guidance": "`PriceChart`",
137
137
  "components": [
138
138
  "PriceChart"
139
139
  ]
140
140
  },
141
141
  {
142
- "need": "Holdings sized by weight and coloured by change",
142
+ "need": "Items sized by weight and coloured by change, such as sales by city",
143
143
  "guidance": "`Treemap`",
144
144
  "components": [
145
145
  "Treemap"
@@ -304,10 +304,9 @@
304
304
  {
305
305
  "file": "agents/examples/alert.tsx",
306
306
  "components": [
307
- "Alert",
308
307
  "AlertDescription",
309
308
  "AlertTitle",
310
- "WarningAlert"
309
+ "StatusAlert"
311
310
  ]
312
311
  },
313
312
  {
@@ -328,7 +327,8 @@
328
327
  "file": "agents/examples/badge.tsx",
329
328
  "components": [
330
329
  "Badge",
331
- "Delta"
330
+ "Delta",
331
+ "StatusBadge"
332
332
  ]
333
333
  },
334
334
  {
@@ -401,11 +401,11 @@
401
401
  {
402
402
  "file": "agents/examples/callout.tsx",
403
403
  "components": [
404
+ "AlertDescription",
405
+ "AlertTitle",
404
406
  "Callout",
405
407
  "Quote",
406
- "WarningAlert",
407
- "AlertDescription",
408
- "AlertTitle"
408
+ "StatusAlert"
409
409
  ]
410
410
  },
411
411
  {
@@ -472,7 +472,7 @@
472
472
  ]
473
473
  },
474
474
  {
475
- "file": "agents/examples/chart-bar-sectors.tsx",
475
+ "file": "agents/examples/chart-bar-teams.tsx",
476
476
  "components": [
477
477
  "BarChartCard",
478
478
  "ToggleGroup",
@@ -3,7 +3,7 @@ import { SeriesChartProps } from "../../../lib/chart-series.js";
3
3
  export interface BarChartCardProps<T extends object, K extends keyof T> extends SeriesChartProps<T, K> {
4
4
  /** Stack the series in one bar per point instead of side by side. */
5
5
  stacked?: boolean;
6
- /** Bars run sideways, categories down the left: for long names, such as sectors. */
6
+ /** Bars run sideways, categories down the left: for long names, such as product categories. */
7
7
  horizontal?: boolean;
8
8
  /** The picked category's x value: its bars stay solid and the rest fade. */
9
9
  selected?: T[K] | null;
@@ -3,6 +3,6 @@ import { ChartCurve, NumericXProps, SeriesChartProps } from "../../../lib/chart-
3
3
  export interface LineChartCardProps<T extends object, K extends keyof T> extends SeriesChartProps<T, K>, NumericXProps {
4
4
  curve?: ChartCurve;
5
5
  }
6
- /** Values over an ordered axis as lines: one series, or several to compare, such as a portfolio against its index. */
6
+ /** Values over an ordered axis as lines: one series, or several to compare, such as sales against a target. */
7
7
  export declare function LineChartCard<T extends object, K extends keyof T>({ curve, ...props }: LineChartCardProps<T, K>): import("react").JSX.Element;
8
8
  //#endregion
@@ -3,7 +3,7 @@ import { ChartFrame, endDot } from "../../../lib/chart-frame.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { Line, LineChart } from "recharts";
5
5
  //#region src/components/registry/charts/line-chart-card.tsx
6
- /** Values over an ordered axis as lines: one series, or several to compare, such as a portfolio against its index. */
6
+ /** Values over an ordered axis as lines: one series, or several to compare, such as sales against a target. */
7
7
  function LineChartCard({ curve = "monotone", ...props }) {
8
8
  return /* @__PURE__ */ jsx(ChartFrame, {
9
9
  chart: LineChart,
@@ -1,24 +1,17 @@
1
+ import { Tone } from "../../lib/tone.js";
1
2
  import { ComponentProps, ReactNode } from "react";
2
3
  //#region src/components/siyahi/callout.d.ts
3
- declare const TONES: {
4
- readonly neutral: "border-border bg-muted/50 [&_[data-slot=callout-icon]]:text-muted-foreground";
5
- readonly accent: "border-chart-1/35 bg-chart-1/8 [&_[data-slot=callout-icon]]:text-link";
6
- readonly warning: "border-warning/45 bg-warning/10 [&_[data-slot=callout-icon]]:text-warning";
7
- readonly positive: "border-positive/40 bg-positive/8 [&_[data-slot=callout-icon]]:text-positive";
8
- readonly negative: "border-negative/40 bg-negative/8 [&_[data-slot=callout-icon]]:text-negative";
9
- };
10
4
  export interface CalloutProps extends Omit<ComponentProps<"aside">, "title"> {
11
5
  /** neutral for an aside, accent for a key point, warning for a caution, positive or negative for a gain or a loss. */
12
- tone?: keyof typeof TONES;
6
+ tone?: Tone;
13
7
  /** A lucide icon, drawn in the tone's colour. */
14
8
  icon?: ReactNode;
15
9
  title?: ReactNode;
16
10
  }
17
11
  /**
18
12
  * A point set apart from the prose: a takeaway, a caveat, a definition. The whole box takes the tone, a faint wash
19
- * inside a border of the same colour; never a single coloured edge. For a notice that interrupts, use Alert or
20
- * WarningAlert instead.
13
+ * inside a border of the same colour; never a single coloured edge. For a notice that interrupts, use StatusAlert
14
+ * instead.
21
15
  */
22
16
  export declare function Callout({ tone, icon, title, className, children, ...props }: CalloutProps): import("react").JSX.Element;
23
- //#endregion
24
- export {};
17
+ //#endregion
@@ -1,28 +1,22 @@
1
+ import { TONES } from "../../lib/tone.js";
1
2
  import { cn } from "cn";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region src/components/siyahi/callout.tsx
4
- const TONES = {
5
- neutral: "border-border bg-muted/50 [&_[data-slot=callout-icon]]:text-muted-foreground",
6
- accent: "border-chart-1/35 bg-chart-1/8 [&_[data-slot=callout-icon]]:text-link",
7
- warning: "border-warning/45 bg-warning/10 [&_[data-slot=callout-icon]]:text-warning",
8
- positive: "border-positive/40 bg-positive/8 [&_[data-slot=callout-icon]]:text-positive",
9
- negative: "border-negative/40 bg-negative/8 [&_[data-slot=callout-icon]]:text-negative"
10
- };
11
5
  /**
12
6
  * A point set apart from the prose: a takeaway, a caveat, a definition. The whole box takes the tone, a faint wash
13
- * inside a border of the same colour; never a single coloured edge. For a notice that interrupts, use Alert or
14
- * WarningAlert instead.
7
+ * inside a border of the same colour; never a single coloured edge. For a notice that interrupts, use StatusAlert
8
+ * instead.
15
9
  */
16
10
  function Callout({ tone = "neutral", icon, title, className, children, ...props }) {
17
11
  return /* @__PURE__ */ jsxs("aside", {
18
12
  "data-slot": "callout",
19
13
  "data-tone": tone,
20
- className: cn("flex gap-3 rounded-lg border px-4 py-3 text-sm", TONES[tone], className),
14
+ className: cn("flex gap-3 rounded-lg border px-4 py-3 text-sm", TONES[tone].box, className),
21
15
  ...props,
22
16
  children: [icon && /* @__PURE__ */ jsx("span", {
23
17
  "data-slot": "callout-icon",
24
18
  "aria-hidden": true,
25
- className: "mt-0.5 shrink-0 [&>svg]:size-4",
19
+ className: cn("mt-0.5 shrink-0 [&>svg]:size-4", TONES[tone].ink),
26
20
  children: icon
27
21
  }), /* @__PURE__ */ jsxs("div", {
28
22
  className: "flex min-w-0 flex-col gap-1",
@@ -0,0 +1,15 @@
1
+ import { Tone } from "../../lib/tone.js";
2
+ import { Alert } from "../ui/alert.js";
3
+ import { ComponentProps } from "react";
4
+ //#region src/components/siyahi/status-alert.d.ts
5
+ export interface StatusAlertProps extends Omit<ComponentProps<typeof Alert>, "variant"> {
6
+ /** neutral for information, warning for a caution, negative for an error, positive for a success. */
7
+ tone?: Tone;
8
+ }
9
+ /**
10
+ * A notice the reader must not miss: the whole card takes its tone, a faint wash inside a border of the same colour,
11
+ * with the tone's icon. Title and description stay in the text colours so they read on the wash. Never mark a notice
12
+ * with a single coloured edge. Put an AlertTitle and an AlertDescription inside.
13
+ */
14
+ export declare function StatusAlert({ tone, className, children, ...props }: StatusAlertProps): import("react").JSX.Element;
15
+ //#endregion