@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
package/DESIGN.md CHANGED
@@ -17,7 +17,8 @@ a meaning:
17
17
  `+` or `−`, and only a small trend icon in green or red. In plain text (labels, tooltips) write the sign; never
18
18
  colour a run of figures green and red.
19
19
  **Amber** means caution. None of them decorates.
20
- - **Emphasis tints the whole surface.** A caution is `WarningAlert`; a point set
20
+ - **Emphasis tints the whole surface.** A notice is `StatusAlert` in its tone (an
21
+ error reads like a warning, only red); a state is `StatusBadge`; a point set
21
22
  apart is `Callout` (`neutral`, `accent`, `warning`, `positive`,
22
23
  `negative`); a quotation is `Quote`. Each takes a faint wash of its colour
23
24
  inside a 1px border of the same colour all round. Large marks follow the same
@@ -37,6 +38,6 @@ a meaning:
37
38
  - **Destructive is not loss.** `--destructive` (delete, an invalid field) is a
38
39
  deeper red than `--negative` (a loss figure), so its label reads on its own
39
40
  tint; never use one for the other.
40
- - Categories (a broker, a sector, an asset class) stay neutral: outline badges,
41
+ - Categories (a team, a region, a product line) stay neutral: outline badges,
41
42
  never a hue each. Ordered buckets (largest 5, next 5, rest) use steps of one
42
43
  colour, not separate hues.
@@ -1,13 +1,13 @@
1
1
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@siyahi/ui";
2
2
 
3
3
  const questions = [
4
+ ["refresh", "When are the figures refreshed?", "Every night at midnight IST, and every minute for today's orders."],
4
5
  [
5
- "prices",
6
- "When are prices updated?",
7
- "At the exchange close each trading day, and every minute while markets are open.",
6
+ "refunds",
7
+ "How are refunds counted?",
8
+ "A refund comes off the month the order was placed in, not the month it was paid.",
8
9
  ],
9
- ["lots", "How are lots matched?", "Sells are matched to the oldest buy first, as the tax rules require."],
10
- ["brokers", "Can I add a second broker?", "Yes. Each broker is its own account, and the totals add them up."],
10
+ ["stores", "Can I add a second store?", "Yes. Each store is its own workspace, and the totals add them up."],
11
11
  ] as const;
12
12
 
13
13
  function Questions() {
@@ -24,13 +24,13 @@ export default function AccordionExample() {
24
24
  <div className="grid gap-6 md:grid-cols-2">
25
25
  <div className="flex flex-col gap-2">
26
26
  <p className="text-sm text-muted-foreground">One open at a time</p>
27
- <Accordion aria-label="One open at a time" defaultValue={["prices"]}>
27
+ <Accordion aria-label="One open at a time" defaultValue={["refresh"]}>
28
28
  <Questions />
29
29
  </Accordion>
30
30
  </div>
31
31
  <div className="flex flex-col gap-2">
32
32
  <p className="text-sm text-muted-foreground">Several open</p>
33
- <Accordion aria-label="Several open" multiple defaultValue={["prices", "lots"]}>
33
+ <Accordion aria-label="Several open" multiple defaultValue={["refresh", "refunds"]}>
34
34
  <Questions />
35
35
  </Accordion>
36
36
  </div>
@@ -1,23 +1,24 @@
1
- import { Alert, AlertDescription, AlertTitle, WarningAlert } from "@siyahi/ui";
2
- import { CircleAlertIcon, InfoIcon } from "lucide-react";
1
+ import { AlertDescription, AlertTitle, StatusAlert } from "@siyahi/ui";
3
2
 
4
3
  export default function AlertExample() {
5
4
  return (
6
5
  <div className="flex flex-col gap-3">
7
- <Alert>
8
- <InfoIcon />
9
- <AlertTitle>Prices are delayed</AlertTitle>
10
- <AlertDescription>Quotes refresh every fifteen minutes during market hours.</AlertDescription>
11
- </Alert>
12
- <WarningAlert>
13
- <AlertTitle>Two trades are unmatched</AlertTitle>
14
- <AlertDescription>The contract notes list trades the ledger does not have yet.</AlertDescription>
15
- </WarningAlert>
16
- <Alert variant="destructive">
17
- <CircleAlertIcon />
6
+ <StatusAlert>
7
+ <AlertTitle>Figures are delayed</AlertTitle>
8
+ <AlertDescription>Sales figures refresh every fifteen minutes during opening hours.</AlertDescription>
9
+ </StatusAlert>
10
+ <StatusAlert tone="warning">
11
+ <AlertTitle>Two payments are unmatched</AlertTitle>
12
+ <AlertDescription>The bank statement lists payments no order accounts for yet.</AlertDescription>
13
+ </StatusAlert>
14
+ <StatusAlert tone="negative">
18
15
  <AlertTitle>Import failed</AlertTitle>
19
- <AlertDescription>The statement could not be read. Download it again and retry.</AlertDescription>
20
- </Alert>
16
+ <AlertDescription>The CSV could not be read. Export it again and retry.</AlertDescription>
17
+ </StatusAlert>
18
+ <StatusAlert tone="positive">
19
+ <AlertTitle>Refunds are settled</AlertTitle>
20
+ <AlertDescription>All 14 refunds from last week have reached the customers' accounts.</AlertDescription>
21
+ </StatusAlert>
21
22
  </div>
22
23
  );
23
24
  }
@@ -1,18 +1,26 @@
1
- import { Badge, Delta } from "@siyahi/ui";
1
+ import { Badge, Delta, StatusBadge } from "@siyahi/ui";
2
2
 
3
3
  export default function BadgeExample() {
4
4
  return (
5
- <div className="flex flex-wrap items-center gap-2">
6
- <Badge>Equity</Badge>
7
- <Badge variant="secondary">Mutual fund</Badge>
8
- <Badge variant="outline">Zerodha</Badge>
9
- <Badge variant="destructive">Failed</Badge>
10
- <Badge variant="outline">
11
- <Delta value={0.042} />
12
- </Badge>
13
- <Badge variant="outline">
14
- <Delta value={-0.013} />
15
- </Badge>
5
+ <div className="flex flex-col gap-3">
6
+ <div className="flex flex-wrap items-center gap-2">
7
+ <StatusBadge tone="positive">Paid</StatusBadge>
8
+ <StatusBadge tone="warning">Pending</StatusBadge>
9
+ <StatusBadge tone="negative">Failed</StatusBadge>
10
+ <StatusBadge tone="accent">New</StatusBadge>
11
+ <StatusBadge>Draft</StatusBadge>
12
+ </div>
13
+ <div className="flex flex-wrap items-center gap-2">
14
+ <Badge>Active</Badge>
15
+ <Badge variant="secondary">Archived</Badge>
16
+ <Badge variant="outline">Engineering</Badge>
17
+ <Badge variant="outline">
18
+ <Delta value={0.042} />
19
+ </Badge>
20
+ <Badge variant="outline">
21
+ <Delta value={-0.013} />
22
+ </Badge>
23
+ </div>
16
24
  </div>
17
25
  );
18
26
  }
@@ -1,9 +1,9 @@
1
1
  import { BarList, Card, CardContent, CardDescription, CardHeader, CardTitle, useFormat } from "@siyahi/ui";
2
2
 
3
- const sectors = [
4
- { name: "Information Technology and Services", value: 100 },
5
- { name: "Fast Moving Consumer Goods", value: 70 },
6
- { name: "Automobile and Auto Components", value: 50 },
3
+ const categories = [
4
+ { name: "Home Appliances and Kitchen Equipment", value: 100 },
5
+ { name: "Health, Beauty and Personal Care", value: 70 },
6
+ { name: "Books, Stationery and Office Supplies", value: 50 },
7
7
  ];
8
8
 
9
9
  export default function BarListLabelsExample() {
@@ -11,11 +11,11 @@ export default function BarListLabelsExample() {
11
11
  return (
12
12
  <Card>
13
13
  <CardHeader>
14
- <CardTitle>Orders by sector, ranked</CardTitle>
14
+ <CardTitle>Orders by category, ranked</CardTitle>
15
15
  <CardDescription>Full labels and order counts stay readable in narrow panels</CardDescription>
16
16
  </CardHeader>
17
17
  <CardContent>
18
- <BarList data={sectors} valueFormatter={count} />
18
+ <BarList data={categories} valueFormatter={count} />
19
19
  </CardContent>
20
20
  </Card>
21
21
  );
@@ -1,14 +1,14 @@
1
1
  import { BarList, Card, CardContent, CardDescription, CardHeader, CardTitle, useFormat } from "@siyahi/ui";
2
2
 
3
- // The biggest unrealised gains and losses; made-up figures.
3
+ // This quarter's revenue against last quarter's, by city: the biggest rises and falls; made-up figures.
4
4
  const gains = [
5
- { name: "INFY", value: 84000 },
6
- { name: "TCS", value: 52000 },
7
- { name: "HDFCBANK", value: 31000 },
5
+ { name: "Mumbai", value: 84000 },
6
+ { name: "Bengaluru", value: 52000 },
7
+ { name: "Pune", value: 31000 },
8
8
  ];
9
9
  const losses = [
10
- { name: "ITC", value: 18400 },
11
- { name: "WIPRO", value: 7600 },
10
+ { name: "Kolkata", value: 18400 },
11
+ { name: "Jaipur", value: 7600 },
12
12
  ];
13
13
 
14
14
  export default function BarListSidesExample() {
@@ -18,8 +18,8 @@ export default function BarListSidesExample() {
18
18
  return (
19
19
  <Card>
20
20
  <CardHeader>
21
- <CardTitle>What drives the P&L</CardTitle>
22
- <CardDescription>The biggest ₹ gains and losses, on one scale</CardDescription>
21
+ <CardTitle>What moved revenue</CardTitle>
22
+ <CardDescription>The biggest ₹ rises and falls by city, on one scale</CardDescription>
23
23
  </CardHeader>
24
24
  {/* Each list is a column of its own, headed and ruled off, with its figures at its own right edge, so a
25
25
  gain's figure never reads as the label of the loss beside it. */}
@@ -1,11 +1,11 @@
1
1
  import { BarList, Card, CardContent, CardDescription, CardHeader, CardTitle, Delta, useFormat } from "@siyahi/ui";
2
2
 
3
- // detail is the loss as a share of what the holding cost.
4
- const largestLosses = [
5
- { name: "ITC", value: 18400, detail: <Delta value={-0.062} /> },
6
- { name: "HDFCBANK", value: 12900, detail: <Delta value={-0.047} /> },
7
- { name: "WIPRO", value: 7600, detail: <Delta value={-0.072} /> },
8
- { name: "Asian Paints (India)", value: 4100, detail: <Delta value={-0.06} /> },
3
+ // value is the drop in a customer's monthly spend; detail is that drop as a share of last month's.
4
+ const largestDrops = [
5
+ { name: "Sharma Textiles", value: 18400, detail: <Delta value={-0.062} /> },
6
+ { name: "Bluepine Logistics", value: 12900, detail: <Delta value={-0.047} /> },
7
+ { name: "Lakeview Clinics", value: 7600, detail: <Delta value={-0.072} /> },
8
+ { name: "Coastal Foods (India)", value: 4100, detail: <Delta value={-0.06} /> },
9
9
  ];
10
10
 
11
11
  export default function BarListExample() {
@@ -14,10 +14,10 @@ export default function BarListExample() {
14
14
  <Card>
15
15
  <CardHeader>
16
16
  <CardTitle>Needs attention</CardTitle>
17
- <CardDescription>Largest unrealised losses</CardDescription>
17
+ <CardDescription>Customers whose spend fell most this month</CardDescription>
18
18
  </CardHeader>
19
19
  <CardContent>
20
- <BarList data={largestLosses} valueFormatter={(v) => money(v)} showPercentage />
20
+ <BarList data={largestDrops} valueFormatter={(v) => money(v)} showPercentage />
21
21
  </CardContent>
22
22
  </Card>
23
23
  );
@@ -12,15 +12,15 @@ export default function BreadcrumbExample() {
12
12
  <Breadcrumb>
13
13
  <BreadcrumbList>
14
14
  <BreadcrumbItem>
15
- <BreadcrumbLink href="#/components">Portfolio</BreadcrumbLink>
15
+ <BreadcrumbLink href="#/components">Projects</BreadcrumbLink>
16
16
  </BreadcrumbItem>
17
17
  <BreadcrumbSeparator />
18
18
  <BreadcrumbItem>
19
- <BreadcrumbLink href="#/components">Equity</BreadcrumbLink>
19
+ <BreadcrumbLink href="#/components">Website</BreadcrumbLink>
20
20
  </BreadcrumbItem>
21
21
  <BreadcrumbSeparator />
22
22
  <BreadcrumbItem>
23
- <BreadcrumbPage>INFY</BreadcrumbPage>
23
+ <BreadcrumbPage>Checkout redesign</BreadcrumbPage>
24
24
  </BreadcrumbItem>
25
25
  </BreadcrumbList>
26
26
  </Breadcrumb>
@@ -1,33 +1,33 @@
1
- import { Callout, Quote, WarningAlert, AlertDescription, AlertTitle } from "@siyahi/ui";
1
+ import { AlertDescription, AlertTitle, Callout, Quote, StatusAlert } from "@siyahi/ui";
2
2
  import { LightbulbIcon, InfoIcon, TriangleAlertIcon, TrendingUpIcon, TrendingDownIcon } from "lucide-react";
3
3
 
4
4
  export default function CalloutExample() {
5
5
  return (
6
6
  <div className="grid max-w-2xl gap-3">
7
7
  <Callout tone="accent" icon={<LightbulbIcon />} title="The takeaway">
8
- Two of eleven gold rules made a profit in the final test; <strong>none</strong> held up in both metals.
8
+ Two of eleven pricing tests raised revenue; <strong>none</strong> held up in both regions.
9
9
  </Callout>
10
- <Callout icon={<InfoIcon />} title="How the test was run">
11
- One mini lot per trade, after charges and a harsher assumed execution cost.
10
+ <Callout icon={<InfoIcon />} title="How the tests were run">
11
+ Four weeks each on a random tenth of new visitors, with refunds and payment fees taken off.
12
12
  </Callout>
13
13
  <Callout tone="warning" icon={<TriangleAlertIcon />} title="Do not use the combined result">
14
- Its test used later information, so its profit claims are withdrawn.
14
+ It counted orders placed before the test began, so its revenue claims are withdrawn.
15
15
  </Callout>
16
16
  <div className="grid gap-3 sm:grid-cols-2">
17
- <Callout tone="positive" icon={<TrendingUpIcon />} title="Best rule">
18
- A failed range break reverses: <strong>▲₹10,616</strong>.
17
+ <Callout tone="positive" icon={<TrendingUpIcon />} title="Best test">
18
+ Annual plan shown first: <strong className="whitespace-nowrap">+₹10,616</strong> a week.
19
19
  </Callout>
20
- <Callout tone="negative" icon={<TrendingDownIcon />} title="Worst rule">
21
- Break the first-hour range: <strong>▼₹70,679</strong>.
20
+ <Callout tone="negative" icon={<TrendingDownIcon />} title="Worst test">
21
+ Free delivery only above ₹999: <strong className="whitespace-nowrap">−₹70,679</strong> a week.
22
22
  </Callout>
23
23
  </div>
24
- <Quote source="eMudhra's incident notice, 21 Oct 2026">
25
- The affected intermediate keys were generated with insufficient entropy and have been revoked.
24
+ <Quote source="The hosting provider's incident report, 21 Oct 2026">
25
+ Requests to the Mumbai region failed for 42 minutes after a configuration change, which has been rolled back.
26
26
  </Quote>
27
- <WarningAlert>
28
- <AlertTitle>Ledger history is incomplete</AlertTitle>
29
- <AlertDescription>Dhan's cash ledger starts in April 2024; earlier flows are missing.</AlertDescription>
30
- </WarningAlert>
27
+ <StatusAlert tone="warning">
28
+ <AlertTitle>Order history is incomplete</AlertTitle>
29
+ <AlertDescription>The old shop's export starts in April 2024; earlier orders are missing.</AlertDescription>
30
+ </StatusAlert>
31
31
  </div>
32
32
  );
33
33
  }
@@ -16,8 +16,8 @@ export default function CardExample() {
16
16
  return (
17
17
  <Card>
18
18
  <CardHeader>
19
- <CardTitle>Portfolio value</CardTitle>
20
- <CardDescription>Across all accounts</CardDescription>
19
+ <CardTitle>Revenue this quarter</CardTitle>
20
+ <CardDescription>Across all stores</CardDescription>
21
21
  <CardAction>
22
22
  <Button variant="outline" size="sm">
23
23
  <DownloadIcon />
@@ -29,7 +29,7 @@ export default function CardExample() {
29
29
  <p className="text-3xl font-semibold">{money(4512300)}</p>
30
30
  </CardContent>
31
31
  <CardFooter>
32
- <p className="text-muted-foreground">Updated after the market close</p>
32
+ <p className="text-muted-foreground">Updated every night at midnight</p>
33
33
  </CardFooter>
34
34
  </Card>
35
35
  );
@@ -17,33 +17,33 @@ import {
17
17
  type DataTableColumnDef,
18
18
  } from "@siyahi/ui";
19
19
 
20
- interface Holding {
21
- symbol: string;
22
- /** Value at the close of 31 January and of 28 February, in rupees; made-up figures. */
20
+ interface Region {
21
+ region: string;
22
+ /** Revenue in January and in February, in rupees; made-up figures. */
23
23
  january: number;
24
24
  february: number;
25
25
  change: number;
26
26
  }
27
27
 
28
- const holding = (symbol: string, january: number, february: number): Holding => ({
29
- symbol,
28
+ const region = (name: string, january: number, february: number): Region => ({
29
+ region: name,
30
30
  january,
31
31
  february,
32
32
  change: february / january - 1,
33
33
  });
34
34
 
35
- const holdings: Holding[] = [
36
- holding("ICICIBANK", 231900, 258000),
37
- holding("HDFCBANK", 248300, 262500),
38
- holding("TCS", 161300, 166000),
39
- holding("NIFTYBEES", 250400, 255600),
40
- holding("ITC", 283100, 276000),
41
- holding("INFY", 241800, 224400),
35
+ const regions: Region[] = [
36
+ region("West", 231900, 258000),
37
+ region("South", 248300, 262500),
38
+ region("Central", 161300, 166000),
39
+ region("East", 250400, 255600),
40
+ region("Northeast", 283100, 276000),
41
+ region("North", 241800, 224400),
42
42
  ];
43
43
 
44
44
  // Every bar is a share of the column's largest move, and the column holds gains and losses, so the bars diverge.
45
- const largestChange = Math.max(...holdings.map((h) => Math.abs(h.change)));
46
- const diverging = holdings.some((h) => h.change < 0) && holdings.some((h) => h.change > 0);
45
+ const largestChange = Math.max(...regions.map((r) => Math.abs(r.change)));
46
+ const diverging = regions.some((r) => r.change < 0) && regions.some((r) => r.change > 0);
47
47
 
48
48
  function Money({ amount, muted = false }: { amount: number; muted?: boolean }) {
49
49
  const text = useFormat().money(amount);
@@ -52,20 +52,20 @@ function Money({ amount, muted = false }: { amount: number; muted?: boolean }) {
52
52
 
53
53
  const header = () => <DataTableSortHeader />;
54
54
 
55
- const columns: DataTableColumnDef<Holding>[] = [
56
- { accessorKey: "symbol", header, size: 130, meta: { label: "Holding", compact: true } },
55
+ const columns: DataTableColumnDef<Region>[] = [
56
+ { accessorKey: "region", header, size: 130, meta: { label: "Region", compact: true } },
57
57
  {
58
58
  accessorKey: "january",
59
59
  header,
60
60
  size: 130,
61
- meta: { label: "31 Jan", variant: "number" },
61
+ meta: { label: "January", variant: "number" },
62
62
  cell: ({ row }) => <Money amount={row.original.january} muted />,
63
63
  },
64
64
  {
65
65
  accessorKey: "february",
66
66
  header,
67
67
  size: 130,
68
- meta: { label: "28 Feb", variant: "number", compact: true },
68
+ meta: { label: "February", variant: "number", compact: true },
69
69
  cell: ({ row }) => <Money amount={row.original.february} />,
70
70
  },
71
71
  {
@@ -81,11 +81,11 @@ export default function ChangeBarExample() {
81
81
  return (
82
82
  <Card>
83
83
  <CardHeader>
84
- <CardTitle>ICICIBANK rose 11.3% in February, INFY fell 7.2%</CardTitle>
85
- <CardDescription>Each holding's value at the end of February against the end of January</CardDescription>
84
+ <CardTitle>The West grew 11.3% in February, the North fell 7.2%</CardTitle>
85
+ <CardDescription>Each region's revenue in February against January</CardDescription>
86
86
  </CardHeader>
87
87
  <CardContent>
88
- <DataTableRoot data={holdings} columns={columns}>
88
+ <DataTableRoot data={regions} columns={columns}>
89
89
  <DataTableToolbarSection>
90
90
  <DataTableCompactColumnsToggle />
91
91
  </DataTableToolbarSection>
@@ -1,27 +1,27 @@
1
1
  import { AreaChartCard, ToggleGroup, ToggleGroupItem, useFormat, type ChartSeries } from "@siyahi/ui";
2
2
 
3
3
  const data = [
4
- { month: "May", value: 3820000, invested: 3600000 },
5
- { month: "Jun", value: 3950000, invested: 3685000 },
6
- { month: "Jul", value: 4110000, invested: 3770000 },
7
- { month: "Aug", value: 4020000, invested: 3855000 },
8
- { month: "Sep", value: 4380000, invested: 3940000 },
9
- { month: "Oct", value: 4512300, invested: 4025000 },
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
10
  ];
11
11
 
12
12
  // The title states the finding, not the measure: what the reader would say after looking.
13
- // The first series fills; the money put in draws as a line over it.
13
+ // The first series fills; the target draws as a line over it.
14
14
  const series: ChartSeries<(typeof data)[number]> = [
15
- { key: "value", label: "Value", color: "var(--chart-1)" },
16
- { key: "invested", label: "Invested", color: "var(--chart-2)" },
15
+ { key: "revenue", label: "Revenue", color: "var(--chart-1)" },
16
+ { key: "target", label: "Target", color: "var(--chart-2)" },
17
17
  ];
18
18
 
19
19
  export default function ChartAreaExample() {
20
20
  const { money, moneyCompact } = useFormat();
21
21
  return (
22
22
  <AreaChartCard
23
- title="₹4.9L ahead of the money put in"
24
- description="Portfolio value against money invested, at each month end"
23
+ title="October revenue ₹4.9L ahead of target"
24
+ description="Each month's revenue against its target"
25
25
  action={
26
26
  <ToggleGroup defaultValue={["6M"]} variant="outline" size="sm" aria-label="Range">
27
27
  <ToggleGroupItem value="6M">6M</ToggleGroupItem>
@@ -1,6 +1,6 @@
1
1
  import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
2
 
3
- // Money into and out of the account each month; out is negative. Made-up figures.
3
+ // Money into and out of a shop's bank account each month; out is negative. Made-up figures.
4
4
  const data = [
5
5
  { month: "Jul", in: 84000, out: -52000 },
6
6
  { month: "Aug", in: 61000, out: -73000 },
@@ -1,6 +1,6 @@
1
1
  import { BarChartCard } from "@siyahi/ui";
2
2
 
3
- // Market hours in IST; each row is the hour an order was placed in.
3
+ // Opening hours in IST; each row is the hour an order was placed in.
4
4
  const data = [
5
5
  { hour: 9, orders: 42 },
6
6
  { hour: 10, orders: 31 },
@@ -1,6 +1,6 @@
1
1
  import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
2
2
 
3
- // F&O net realized per financial year, a loss every year; made-up figures.
3
+ // A new product line's operating result per financial year, a loss every year; made-up figures.
4
4
  const data = [
5
5
  { fy: "FY23", net: -48000 },
6
6
  { fy: "FY24", net: -91000 },
@@ -9,14 +9,14 @@ const data = [
9
9
  ];
10
10
 
11
11
  const series: ChartSeries<(typeof data)[number]> = [
12
- { key: "net", label: "F&O net realized", color: "var(--positive)", negativeColor: "var(--negative)" },
12
+ { key: "net", label: "Operating result", color: "var(--positive)", negativeColor: "var(--negative)" },
13
13
  ];
14
14
 
15
15
  export default function ChartBarLossesExample() {
16
16
  const { money, moneyCompact } = useFormat();
17
17
  return (
18
18
  <BarChartCard
19
- title="F&O realized by financial year"
19
+ title="Operating loss by financial year"
20
20
  description="A loss every year, so every bar runs down from zero"
21
21
  data={data}
22
22
  xKey="fy"
@@ -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 ? `+${points.toFixed(1)} pts over` : `\u2212${points.toFixed(1)} pts under`;
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)} vs ${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
+ }
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
  import { BarChartCard, useFormat, type ChartSeries } from "@siyahi/ui";
3
3
 
4
- // Net realized gain per financial year (April to March); made-up figures.
4
+ // Net profit per financial year (April to March); made-up figures.
5
5
  const data = [
6
6
  { fy: "FY22", net: 142000 },
7
7
  { fy: "FY23", net: 186000 },
@@ -12,19 +12,19 @@ const data = [
12
12
 
13
13
  // A gain and a loss take the meaning colours; the arrow in each tick says the same without colour.
14
14
  const series: ChartSeries<(typeof data)[number]> = [
15
- { key: "net", label: "Net realized", color: "var(--positive)", negativeColor: "var(--negative)" },
15
+ { key: "net", label: "Net profit", color: "var(--positive)", negativeColor: "var(--negative)" },
16
16
  ];
17
17
 
18
18
  export default function ChartBarYearsExample() {
19
19
  const { money, moneyCompact } = useFormat();
20
20
  // The page owns the pick, so it can narrow the rest of the page to that year.
21
21
  const [year, setYear] = useState<string | null>(null);
22
- const signed = (v: number) => `${v < 0 ? "▼" : "▲"}${moneyCompact(Math.abs(v))}`;
22
+ const signed = (v: number) => `${v < 0 ? "\u2212" : "+"}${moneyCompact(Math.abs(v))}`;
23
23
  return (
24
24
  <BarChartCard
25
- title="Realized by financial year"
25
+ title="Profit by financial year"
26
26
  description={
27
- year ? `${year} picked; click it again for every year` : "April to March, gross. Click a year to pick it."
27
+ year ? `${year} picked; click it again for every year` : "April to March, before tax. Click a year to pick it."
28
28
  }
29
29
  data={data}
30
30
  xKey="fy"