@siyahi/ui 0.1.9-next.10 → 0.1.9-next.13

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.
package/README.md CHANGED
@@ -198,6 +198,10 @@ surface.
198
198
  </SiyahiProvider>
199
199
  ```
200
200
 
201
+ Pages are dense. A `PageSection` sits 24px under its rule with 16px to its
202
+ content, so stack sections 24px apart (`flex flex-col gap-6`) and the rule sits
203
+ midway. Stat tiles are 12px in from each edge with a 24px figure.
204
+
201
205
  ## Dark mode
202
206
 
203
207
  The colour scheme follows the device (`prefers-color-scheme`). There is no
@@ -11,6 +11,11 @@ function BarChartCard({ stacked = false, selected = null, onSelect, ...props })
11
11
  ...props,
12
12
  yDomain: props.yDomain ?? (props.data.some((row) => props.series.some(({ key }) => Number(row[key]) > 0)) ? void 0 : DOWN_FROM_ZERO),
13
13
  stackOffset: stacked ? "sign" : void 0,
14
+ onClick: onSelect ? ({ activeTooltipIndex, isTooltipActive }) => {
15
+ if (!isTooltipActive || activeTooltipIndex == null) return;
16
+ const row = props.data[Number(activeTooltipIndex)];
17
+ if (row) onSelect(row[props.xKey] === selected ? null : row[props.xKey]);
18
+ } : void 0,
14
19
  children: props.series.map((item, index) => {
15
20
  const { key, label, color, negativeColor } = item;
16
21
  return /* @__PURE__ */ jsx(Bar, {
@@ -29,11 +34,6 @@ function BarChartCard({ stacked = false, selected = null, onSelect, ...props })
29
34
  0,
30
35
  0
31
36
  ] : 0,
32
- className: onSelect ? "cursor-pointer" : void 0,
33
- onClick: onSelect && ((bar) => {
34
- const value = bar.payload?.[props.xKey];
35
- if (value !== void 0) onSelect(value === selected ? null : value);
36
- }),
37
37
  children: (negativeColor || selected !== null) && props.data.map((row, i) => /* @__PURE__ */ jsx(Cell, {
38
38
  fill: negativeColor && Number(row[key]) < 0 ? negativeColor : color,
39
39
  fillOpacity: selected === null || row[props.xKey] === selected ? 1 : .35
@@ -23,7 +23,7 @@ function SectionCards({ items, selected, onSelect }) {
23
23
  "data-slot": "section-card",
24
24
  className: cn("min-w-0", ruled && "border-t border-l"),
25
25
  children: /* @__PURE__ */ jsxs(Card, {
26
- className: cn("@container/card h-full", onSelect && "relative", item.label === selected && "ring-2 ring-primary!", item.label === selected && ruled && "ring-inset", onSelect && item.disabled && "opacity-60"),
26
+ className: cn("@container/card h-full [--card-spacing:--spacing(3)]", onSelect && "relative", item.label === selected && "ring-2 ring-primary!", item.label === selected && ruled && "ring-inset", onSelect && item.disabled && "opacity-60"),
27
27
  children: [
28
28
  onSelect && /* @__PURE__ */ jsx("button", {
29
29
  type: "button",
@@ -36,7 +36,7 @@ function SectionCards({ items, selected, onSelect }) {
36
36
  /* @__PURE__ */ jsxs(CardHeader, { children: [
37
37
  /* @__PURE__ */ jsx(CardDescription, { children: item.label }),
38
38
  /* @__PURE__ */ jsx(CardTitle, {
39
- className: "text-2xl font-semibold tabular-nums @[250px]/card:text-3xl",
39
+ className: "text-2xl font-semibold tabular-nums",
40
40
  children: item.value
41
41
  }),
42
42
  item.badge && /* @__PURE__ */ jsx(CardAction, { children: /* @__PURE__ */ jsx(Badge, {
@@ -46,7 +46,7 @@ function SectionCards({ items, selected, onSelect }) {
46
46
  ] }),
47
47
  item.trend && /* @__PURE__ */ jsx(CardContent, { children: item.trend }),
48
48
  (item.headline || item.detail) && /* @__PURE__ */ jsxs(CardFooter, {
49
- className: "flex-col items-start gap-1.5 text-sm",
49
+ className: "flex-col items-start gap-1 text-sm",
50
50
  children: [item.headline && /* @__PURE__ */ jsx("div", {
51
51
  className: "flex flex-wrap gap-2 font-medium",
52
52
  children: item.headline
@@ -12,7 +12,10 @@ export interface PageSectionProps {
12
12
  action?: ReactNode;
13
13
  children?: ReactNode;
14
14
  }
15
- /** One part of a long page: a rule above, then the heading and lead on the canvas, then its content. */
15
+ /**
16
+ * One part of a long page: a rule above, then the heading and lead on the canvas, then its content. Spaced for
17
+ * density, 24px under the rule and 16px to the content, so sections stacked 24px apart sit 24px either side of it.
18
+ */
16
19
  export declare function PageSection({ id, eyebrow, title, lead, action, children }: PageSectionProps): import("react").JSX.Element;
17
20
  /** A heading inside a PageSection, one level under its title. */
18
21
  export declare function PageSubheading({ children }: {
@@ -1,11 +1,14 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  //#region src/components/siyahi/page-section.tsx
3
- /** One part of a long page: a rule above, then the heading and lead on the canvas, then its content. */
3
+ /**
4
+ * One part of a long page: a rule above, then the heading and lead on the canvas, then its content. Spaced for
5
+ * density, 24px under the rule and 16px to the content, so sections stacked 24px apart sit 24px either side of it.
6
+ */
4
7
  function PageSection({ id, eyebrow, title, lead, action, children }) {
5
8
  return /* @__PURE__ */ jsxs("section", {
6
9
  id,
7
10
  "data-slot": "page-section",
8
- className: "flex scroll-mt-6 flex-col gap-6 border-t pt-10",
11
+ className: "flex scroll-mt-6 flex-col gap-4 border-t pt-6",
9
12
  children: [/* @__PURE__ */ jsxs("div", {
10
13
  className: "flex flex-wrap items-end justify-between gap-4",
11
14
  children: [/* @__PURE__ */ jsxs("div", {
@@ -16,7 +19,7 @@ function PageSection({ id, eyebrow, title, lead, action, children }) {
16
19
  children: eyebrow
17
20
  }),
18
21
  /* @__PURE__ */ jsx("h2", {
19
- className: "text-2xl font-semibold tracking-tight",
22
+ className: "text-xl font-semibold tracking-tight",
20
23
  children: title
21
24
  }),
22
25
  lead && /* @__PURE__ */ jsx("div", {
@@ -21,7 +21,7 @@ function PanelGrid({ columns = 2, children, className }) {
21
21
  "data-slot": "panel-grid",
22
22
  className: cn("@container/panels", ruled && "overflow-hidden border-y", className),
23
23
  children: /* @__PURE__ */ jsx("div", {
24
- className: cn("grid grid-cols-1", COLUMNS[columns], ruled ? "-mt-px -ml-px" : surface === "open" ? "gap-x-10 gap-y-8" : "gap-4"),
24
+ className: cn("grid grid-cols-1", COLUMNS[columns], ruled ? "-mt-px -ml-px" : surface === "open" ? "gap-x-8 gap-y-6" : "gap-4"),
25
25
  children: Children.map(children, (child) => /* @__PURE__ */ jsx("div", {
26
26
  "data-slot": "panel",
27
27
  className: cn("min-w-0", ruled && "border-t border-l"),
@@ -1,5 +1,5 @@
1
1
  import { ChartColor, ChartSeries, ChartSeriesItem, NumericXProps, SeriesChartProps } from "./chart-series.js";
2
- import { ReactNode } from "react";
2
+ import { ComponentProps, ReactNode } from "react";
3
3
  import { AreaChart, BarChart, LineChart, YAxisProps } from "recharts";
4
4
  //#region src/lib/chart-frame.d.ts
5
5
  interface ChartFrameProps<T extends object, K extends keyof T> extends Omit<SeriesChartProps<T, K>, "yDomain">, NumericXProps {
@@ -15,6 +15,7 @@ interface ChartFrameProps<T extends object, K extends keyof T> extends Omit<Seri
15
15
  horizontal?: boolean;
16
16
  /** "sign" stacks negative values below zero and positive ones above, rather than on one running total. */
17
17
  stackOffset?: "sign";
18
+ onClick?: ComponentProps<typeof BarChart>["onClick"];
18
19
  }
19
20
  /**
20
21
  * The colour a series' Bar takes, which its legend chip shows: the negative colour when every value drawn is below
@@ -31,6 +32,6 @@ export declare function seriesRow<T>(series: ChartSeries<T>, formatValue: (value
31
32
  * that gave its category axis its own id (dash#88) got a plot split in two
32
33
  * and every tooltip headed with the series name instead of the category.
33
34
  */
34
- export declare function ChartFrame<T extends object, K extends keyof T>({ chart: Chart, children, horizontal, stackOffset, title, description, action, data, xKey, series, xFormatter, xTooltipFormatter, valueFormatter, yTickFormatter, yDomain, yTicks, height, xTickDetail, xLabel, yLabel, referenceLines, placeholder, footer, xDomain, xTicks }: ChartFrameProps<T, K>): import("react").JSX.Element;
35
+ export declare function ChartFrame<T extends object, K extends keyof T>({ chart: Chart, children, horizontal, stackOffset, onClick, title, description, action, data, xKey, series, xFormatter, xTooltipFormatter, valueFormatter, yTickFormatter, yDomain, yTicks, height, xTickDetail, xLabel, yLabel, referenceLines, placeholder, footer, xDomain, xTicks }: ChartFrameProps<T, K>): import("react").JSX.Element;
35
36
  //#endregion
36
37
  export {};
@@ -93,7 +93,7 @@ function fittedTick(data, xKey, xFormatter, detailOf, beside) {
93
93
  * that gave its category axis its own id (dash#88) got a plot split in two
94
94
  * and every tooltip headed with the series name instead of the category.
95
95
  */
96
- function ChartFrame({ chart: Chart, children, horizontal = false, stackOffset, title, description, action, data, xKey, series, xFormatter = String, xTooltipFormatter = xFormatter, valueFormatter, yTickFormatter, yDomain, yTicks, height, xTickDetail, xLabel, yLabel, referenceLines = NO_LINES, placeholder, footer, xDomain, xTicks }) {
96
+ function ChartFrame({ chart: Chart, children, horizontal = false, stackOffset, onClick, title, description, action, data, xKey, series, xFormatter = String, xTooltipFormatter = xFormatter, valueFormatter, yTickFormatter, yDomain, yTicks, height, xTickDetail, xLabel, yLabel, referenceLines = NO_LINES, placeholder, footer, xDomain, xTicks }) {
97
97
  const { numberLocale } = useLocale();
98
98
  const formatValue = valueFormatter ?? new Intl.NumberFormat(numberLocale).format;
99
99
  const config = Object.fromEntries(series.map(({ key, label, color }) => [key, {
@@ -114,12 +114,14 @@ function ChartFrame({ chart: Chart, children, horizontal = false, stackOffset, t
114
114
  children: placeholder
115
115
  }) : /* @__PURE__ */ jsx(ChartContainer, {
116
116
  config,
117
- className: "aspect-auto w-full",
117
+ className: cn("aspect-auto w-full", onClick && "cursor-pointer"),
118
118
  style: { height },
119
119
  children: /* @__PURE__ */ jsxs(Chart, {
120
120
  data,
121
121
  layout: horizontal ? "vertical" : "horizontal",
122
122
  stackOffset,
123
+ onClick,
124
+ throttledEvents: onClick ? [] : void 0,
123
125
  margin: {
124
126
  left: 0,
125
127
  right: xTicks ? endRoom(xFormatter, xTicks) : 8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siyahi/ui",
3
- "version": "0.1.9-next.10",
3
+ "version": "0.1.9-next.13",
4
4
  "description": "Stock shadcn/ui on Base UI and Tailwind v4, a finance theme, a few compositions and formatters.",
5
5
  "keywords": [
6
6
  "base-ui",