@hackcove/ui-react 0.10.3 → 0.10.5

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/dist/trend.js ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The scale shared by `TrendChart` and the `StatTile` sparkline. Internal: not exported from
3
+ * `index.ts`.
4
+ */
5
+ /**
6
+ * The top of a y-axis that starts at 0: the smallest of 2, 4 or 10 times a whole power of ten
7
+ * (1, 10, 100, …) that is at least `top`. Its half is then a whole number: 1 gives 2, 3 gives
8
+ * 4, 5 gives 10, 13 gives 20. Nothing above 0 gives 2.
9
+ */
10
+ export function scaleMax(top) {
11
+ for (let power = 1;; power *= 10) {
12
+ for (const step of [2, 4, 10]) {
13
+ if (step * power >= top)
14
+ return step * power;
15
+ }
16
+ }
17
+ }
18
+ /** A value as drawn: a negative one is 0, and a missing or non-finite one is `null`. */
19
+ export function drawn(value) {
20
+ if (value == null || !Number.isFinite(value))
21
+ return null;
22
+ return Math.max(0, value);
23
+ }
24
+ /** The largest drawn value of every list, or 0. */
25
+ export function largest(lists) {
26
+ let top = 0;
27
+ for (const list of lists) {
28
+ for (const value of list)
29
+ top = Math.max(top, drawn(value) ?? 0);
30
+ }
31
+ return top;
32
+ }
33
+ /** `value` as a height on a 0 to 100 plot, measured down from the top (SVG's y). */
34
+ export function plotY(value, max) {
35
+ return 100 - (value / max) * 100;
36
+ }
37
+ /**
38
+ * The polylines of a line through `points`, broken at every missing one: one `points` string per
39
+ * run of present values. A run of one point repeats it, so a round cap draws it as a dot.
40
+ */
41
+ export function runs(points) {
42
+ const out = [];
43
+ let run = [];
44
+ const close = () => {
45
+ const [only] = run;
46
+ if (run.length === 1 && only !== undefined)
47
+ run.push(only);
48
+ if (run.length > 0)
49
+ out.push(run.join(" "));
50
+ run = [];
51
+ };
52
+ for (const point of points) {
53
+ if (point === null)
54
+ close();
55
+ else
56
+ run.push(`${round(point.x)},${round(point.y)}`);
57
+ }
58
+ close();
59
+ return out;
60
+ }
61
+ /** Four decimals, so the markup stays short and stable. */
62
+ export function round(n) {
63
+ return Math.round(n * 10000) / 10000;
64
+ }
@@ -118,6 +118,8 @@ const SECTION = {
118
118
  app: "text-base/6 font-semibold",
119
119
  prose: "text-2xl/8 font-semibold tracking-tight",
120
120
  };
121
+ /** The offset an anchored heading keeps from the top, so the sticky header does not cover it. */
122
+ const SCROLL_TARGET = "scroll-mt-28";
121
123
  /**
122
124
  * Top-level section header. `h2`, text-base/6 semibold, primary text (text-2xl/8 semibold tight
123
125
  * inside a `Prose`). `rule` sets
@@ -129,10 +131,12 @@ export function SectionHeading({ rule, description, ...props }) {
129
131
  const hairline = "mb-4 border-b border-slate-200/70 pb-2";
130
132
  const size = useProse() ? SECTION.prose : SECTION.app;
131
133
  const hasDescription = description != null && description !== false;
134
+ // An `id` makes the heading a link target, so an anchor jump leaves it clear of the sticky header.
135
+ const scroll = props.id === undefined ? undefined : SCROLL_TARGET;
132
136
  if (!hasDescription) {
133
- return pinned("h2", cx(rule && hairline, size), "default", props);
137
+ return pinned("h2", cx(rule && hairline, size, scroll), "default", props);
134
138
  }
135
- return (_jsxs("div", { className: cx("flex flex-col gap-1", rule && hairline), children: [pinned("h2", size, "default", props), _jsx(Text, { as: "p", color: "tertiary", children: description })] }));
139
+ return (_jsxs("div", { className: cx("flex flex-col gap-1", rule && hairline), children: [pinned("h2", cx(size, scroll), "default", props), _jsx(Text, { as: "p", color: "tertiary", children: description })] }));
136
140
  }
137
141
  const SUBSECTION_SIZE = {
138
142
  sm: { app: "text-sm/5 font-semibold", prose: "text-base/7 font-semibold" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hackcove/ui-react",
3
- "version": "0.10.3",
3
+ "version": "0.10.5",
4
4
  "description": "Hack Cove React components: primitives, typography roles and a safe Markdown renderer, written against Tailwind v4 utilities. Pair with a theme from @hackcove/themes.",
5
5
  "keywords": [
6
6
  "components",
@@ -78,16 +78,6 @@
78
78
  }
79
79
  },
80
80
  "nx": {
81
- "name": "ui-react",
82
- "tags": [
83
- "kind:package"
84
- ],
85
- "targets": {
86
- "build": {
87
- "outputs": [
88
- "{projectRoot}/dist"
89
- ]
90
- }
91
- }
81
+ "name": "ui-react"
92
82
  }
93
83
  }