@siyahi/ui 0.1.9-next.21 → 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 (93) hide show
  1. package/DESIGN.md +16 -3
  2. package/agents/examples/accordion.tsx +7 -7
  3. package/agents/examples/alert.tsx +16 -15
  4. package/agents/examples/app-sidebar.tsx +3 -1
  5. package/agents/examples/badge.tsx +20 -12
  6. package/agents/examples/bar-list-labels.tsx +6 -6
  7. package/agents/examples/bar-list-sides.tsx +18 -16
  8. package/agents/examples/bar-list.tsx +8 -8
  9. package/agents/examples/breadcrumb.tsx +3 -3
  10. package/agents/examples/calendar.tsx +3 -7
  11. package/agents/examples/callout.tsx +15 -15
  12. package/agents/examples/card.tsx +5 -3
  13. package/agents/examples/change-bar.tsx +21 -21
  14. package/agents/examples/chart-area.tsx +11 -11
  15. package/agents/examples/chart-bar-flows.tsx +1 -1
  16. package/agents/examples/chart-bar-hourly.tsx +1 -1
  17. package/agents/examples/chart-bar-losses.tsx +3 -3
  18. package/agents/examples/chart-bar-teams.tsx +72 -0
  19. package/agents/examples/chart-bar-years.tsx +5 -5
  20. package/agents/examples/chart-bar.tsx +10 -10
  21. package/agents/examples/chart-category-ticks.tsx +6 -6
  22. package/agents/examples/chart-line.tsx +17 -17
  23. package/agents/examples/collapsible.tsx +5 -3
  24. package/agents/examples/command.tsx +23 -21
  25. package/agents/examples/context-menu.tsx +6 -4
  26. package/agents/examples/data-bar.tsx +32 -45
  27. package/agents/examples/data-table-compact.tsx +31 -30
  28. package/agents/examples/data-table-filters.tsx +20 -20
  29. package/agents/examples/data-table.tsx +31 -30
  30. package/agents/examples/dialog.tsx +3 -3
  31. package/agents/examples/distribution-bar-tug.tsx +36 -34
  32. package/agents/examples/dropdown-menu.tsx +2 -2
  33. package/agents/examples/heatmap-calendar.tsx +12 -10
  34. package/agents/examples/heatmap-status.tsx +11 -9
  35. package/agents/examples/heatmap-weekday.tsx +27 -30
  36. package/agents/examples/input-states.tsx +9 -9
  37. package/agents/examples/input.tsx +3 -3
  38. package/agents/examples/local-time.tsx +1 -1
  39. package/agents/examples/metric-strip.tsx +8 -8
  40. package/agents/examples/page-hero.tsx +2 -2
  41. package/agents/examples/popover.tsx +3 -3
  42. package/agents/examples/price-chart.tsx +5 -5
  43. package/agents/examples/progress-tone.tsx +10 -9
  44. package/agents/examples/progress.tsx +1 -1
  45. package/agents/examples/range-position-table.tsx +31 -31
  46. package/agents/examples/range-position.tsx +31 -29
  47. package/agents/examples/scroll-area.tsx +12 -10
  48. package/agents/examples/section-cards-select.tsx +11 -10
  49. package/agents/examples/section-cards-trend.tsx +4 -4
  50. package/agents/examples/section-cards.tsx +13 -13
  51. package/agents/examples/select.tsx +9 -9
  52. package/agents/examples/separator.tsx +3 -3
  53. package/agents/examples/sheet.tsx +1 -1
  54. package/agents/examples/slider.tsx +1 -1
  55. package/agents/examples/surfaces.tsx +16 -16
  56. package/agents/examples/tabs.tsx +7 -7
  57. package/agents/examples/target-rows.tsx +31 -27
  58. package/agents/examples/tooltip.tsx +2 -2
  59. package/agents/examples/treemap.tsx +38 -33
  60. package/agents/manifest.json +15 -15
  61. package/dist/components/registry/charts/bar-chart-card.d.ts +1 -1
  62. package/dist/components/registry/charts/bar-chart-card.js +6 -2
  63. package/dist/components/registry/charts/line-chart-card.d.ts +1 -1
  64. package/dist/components/registry/charts/line-chart-card.js +1 -1
  65. package/dist/components/registry/dashboard-01/section-cards.js +1 -1
  66. package/dist/components/registry/dashboardcn/distribution-bar.js +5 -3
  67. package/dist/components/registry/heatmap/status-heatmap.js +1 -1
  68. package/dist/components/siyahi/callout.d.ts +5 -12
  69. package/dist/components/siyahi/callout.js +5 -11
  70. package/dist/components/siyahi/delta.d.ts +5 -1
  71. package/dist/components/siyahi/delta.js +14 -9
  72. package/dist/components/siyahi/status-alert.d.ts +15 -0
  73. package/dist/components/siyahi/status-alert.js +29 -0
  74. package/dist/components/siyahi/status-badge.d.ts +15 -0
  75. package/dist/components/siyahi/status-badge.js +24 -0
  76. package/dist/components/siyahi/tone-progress.d.ts +1 -1
  77. package/dist/components/siyahi/tone-progress.js +1 -1
  78. package/dist/components/siyahi/treemap.d.ts +4 -4
  79. package/dist/components/siyahi/treemap.js +5 -5
  80. package/dist/index.d.ts +5 -4
  81. package/dist/index.js +3 -2
  82. package/dist/lib/chart-frame.js +1 -1
  83. package/dist/lib/chart-series.d.ts +1 -1
  84. package/dist/lib/format.d.ts +1 -1
  85. package/dist/lib/format.js +1 -1
  86. package/dist/lib/tone.d.ts +36 -0
  87. package/dist/lib/tone.js +35 -0
  88. package/package.json +1 -1
  89. package/report.css +14 -14
  90. package/styles/siyahi.css +92 -20
  91. package/agents/examples/chart-bar-sectors.tsx +0 -72
  92. package/dist/components/siyahi/warning-alert.d.ts +0 -10
  93. package/dist/components/siyahi/warning-alert.js +0 -20
@@ -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,43 +10,45 @@ 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
- <CardContent className="flex flex-col gap-8 @xl/range:flex-row @xl/range:items-end">
29
- <DataList className="@xl/range:w-56 @xl/range:shrink-0">
30
- <DataListItem label="52-week low, 7 months ago">
31
- <span className="tabular-nums">{price(low)}</span>
32
- </DataListItem>
33
- <DataListItem label="52-week high, 11 weeks ago">
34
- <span className="tabular-nums">{price(high)}</span>
35
- </DataListItem>
36
- <DataListItem label="Last close">
37
- <span className="tabular-nums">{price(close)}</span>
38
- </DataListItem>
39
- </DataList>
40
- <RangePosition
41
- low={low}
42
- high={high}
43
- value={close}
44
- lowLabel="52-week low"
45
- highLabel="52-week high"
46
- caption="of the way up the 52-week range"
47
- valueFormatter={price}
48
- className="@xl/range:flex-1"
49
- />
28
+ <CardContent>
29
+ <div className="flex flex-col gap-8 @xl/range:flex-row @xl/range:items-end">
30
+ <DataList className="@xl/range:w-56 @xl/range:shrink-0">
31
+ <DataListItem label="Fastest day, 3 weeks ago">
32
+ <span className="tabular-nums">{ms(low)}</span>
33
+ </DataListItem>
34
+ <DataListItem label="Slowest day, 9 days ago">
35
+ <span className="tabular-nums">{ms(high)}</span>
36
+ </DataListItem>
37
+ <DataListItem label="Today, 95th percentile">
38
+ <span className="tabular-nums">{ms(today)}</span>
39
+ </DataListItem>
40
+ </DataList>
41
+ <RangePosition
42
+ low={low}
43
+ high={high}
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
+ className="@xl/range:flex-1"
50
+ />
51
+ </div>
50
52
  </CardContent>
51
53
  </Card>
52
54
  );
@@ -6,15 +6,17 @@ const months = Array.from({ length: 24 }, (_, i) =>
6
6
 
7
7
  export default function ScrollAreaExample() {
8
8
  return (
9
- <ScrollArea className="h-48 w-56 rounded-lg border">
10
- <div className="p-4">
11
- {months.map((month) => (
12
- <div key={month}>
13
- <div className="text-sm">{month}</div>
14
- <Separator className="my-2" />
15
- </div>
16
- ))}
17
- </div>
18
- </ScrollArea>
9
+ <div className="h-48 w-56 overflow-hidden rounded-lg border">
10
+ <ScrollArea className="h-full">
11
+ <div className="p-4">
12
+ {months.map((month) => (
13
+ <div key={month}>
14
+ <div className="text-sm">{month}</div>
15
+ <Separator className="my-2" />
16
+ </div>
17
+ ))}
18
+ </div>
19
+ </ScrollArea>
20
+ </div>
19
21
  );
20
22
  }
@@ -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} />;
@@ -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,22 +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 className="font-mono">{row.symbol}</TableCell>
79
- <TableCell className="tabular-nums">{money(row.value)}</TableCell>
76
+ {products.map((row) => (
77
+ <TableRow key={row.product}>
78
+ <TableCell>{row.product}</TableCell>
79
+ <TableCell>{money(row.revenue)}</TableCell>
80
80
  </TableRow>
81
81
  ))}
82
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,60 +10,64 @@ 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
- <CardContent className="grid gap-2">
63
- <p className="text-sm text-muted-foreground">
64
- Bar: today's weight. Tall tick: the target. Shading: within 5 points of it, darker within 2.
65
- </p>
66
- <TargetRows rows={rows} domain={[0, 0.5]} valueFormatter={(value) => f.pct(value)} />
64
+ <CardContent>
65
+ <div className="grid gap-2">
66
+ <p className="text-sm text-muted-foreground">
67
+ Bar: the share spent so far. Tall tick: the budgeted share. Shading: within 5 points of it, darker within 2.
68
+ </p>
69
+ <TargetRows rows={rows} domain={[0, 0.5]} valueFormatter={(value) => f.pct(value)} />
70
+ </div>
67
71
  </CardContent>
68
72
  </Card>
69
73
  );
@@ -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
  }