@watt-ui/react 0.1.4 → 0.2.0

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 (98) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +9 -9
  3. package/dist/chart/category-engine.d.ts +2 -0
  4. package/dist/chart/category-engine.d.ts.map +1 -0
  5. package/dist/chart/category-engine.js +9 -0
  6. package/dist/chart/category-engine.js.map +1 -0
  7. package/dist/chart/category-options.d.ts +23 -0
  8. package/dist/chart/category-options.d.ts.map +1 -0
  9. package/dist/chart/category-options.js +120 -0
  10. package/dist/chart/category-options.js.map +1 -0
  11. package/dist/components/asset-tree.d.ts.map +1 -1
  12. package/dist/components/asset-tree.js +16 -2
  13. package/dist/components/asset-tree.js.map +1 -1
  14. package/dist/components/battery-soc.d.ts.map +1 -1
  15. package/dist/components/battery-soc.js +5 -1
  16. package/dist/components/battery-soc.js.map +1 -1
  17. package/dist/components/category-chart.d.ts +37 -0
  18. package/dist/components/category-chart.d.ts.map +1 -0
  19. package/dist/components/category-chart.js +251 -0
  20. package/dist/components/category-chart.js.map +1 -0
  21. package/dist/components/energy-flow.d.ts +2 -1
  22. package/dist/components/energy-flow.d.ts.map +1 -1
  23. package/dist/components/energy-flow.js +2 -2
  24. package/dist/components/energy-flow.js.map +1 -1
  25. package/dist/components/equipment-card.d.ts +12 -0
  26. package/dist/components/equipment-card.d.ts.map +1 -0
  27. package/dist/components/equipment-card.js +18 -0
  28. package/dist/components/equipment-card.js.map +1 -0
  29. package/dist/components/equipment-heatmap.d.ts +33 -0
  30. package/dist/components/equipment-heatmap.d.ts.map +1 -0
  31. package/dist/components/equipment-heatmap.js +161 -0
  32. package/dist/components/equipment-heatmap.js.map +1 -0
  33. package/dist/components/equipment-table.d.ts +34 -0
  34. package/dist/components/equipment-table.d.ts.map +1 -0
  35. package/dist/components/equipment-table.js +141 -0
  36. package/dist/components/equipment-table.js.map +1 -0
  37. package/dist/components/metric-trend.d.ts +13 -0
  38. package/dist/components/metric-trend.d.ts.map +1 -0
  39. package/dist/components/metric-trend.js +30 -0
  40. package/dist/components/metric-trend.js.map +1 -0
  41. package/dist/components/operating-timeline.d.ts +31 -0
  42. package/dist/components/operating-timeline.d.ts.map +1 -0
  43. package/dist/components/operating-timeline.js +61 -0
  44. package/dist/components/operating-timeline.js.map +1 -0
  45. package/dist/components/plant-fleet-map.d.ts +32 -0
  46. package/dist/components/plant-fleet-map.d.ts.map +1 -0
  47. package/dist/components/plant-fleet-map.js +56 -0
  48. package/dist/components/plant-fleet-map.js.map +1 -0
  49. package/dist/components/threshold-gauge.d.ts +19 -0
  50. package/dist/components/threshold-gauge.d.ts.map +1 -0
  51. package/dist/components/threshold-gauge.js +54 -0
  52. package/dist/components/threshold-gauge.js.map +1 -0
  53. package/dist/components/time-range-selector.d.ts +16 -0
  54. package/dist/components/time-range-selector.d.ts.map +1 -0
  55. package/dist/components/time-range-selector.js +47 -0
  56. package/dist/components/time-range-selector.js.map +1 -0
  57. package/dist/icons/index.d.ts +17 -1
  58. package/dist/icons/index.d.ts.map +1 -1
  59. package/dist/icons/index.js +98 -1
  60. package/dist/icons/index.js.map +1 -1
  61. package/dist/index.d.ts +19 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +9 -0
  64. package/dist/index.js.map +1 -1
  65. package/dist/map/land.d.ts +2 -0
  66. package/dist/map/land.d.ts.map +1 -0
  67. package/dist/map/land.js +3 -0
  68. package/dist/map/land.js.map +1 -0
  69. package/dist/server.d.ts +5 -0
  70. package/dist/server.d.ts.map +1 -1
  71. package/dist/server.js +21 -1
  72. package/dist/server.js.map +1 -1
  73. package/dist/styles.css +133 -4
  74. package/dist/virtual-focus.d.ts +3 -0
  75. package/dist/virtual-focus.d.ts.map +1 -0
  76. package/dist/virtual-focus.js +23 -0
  77. package/dist/virtual-focus.js.map +1 -0
  78. package/package.json +37 -1
  79. package/src/chart/category-engine.ts +8 -0
  80. package/src/chart/category-options.ts +158 -0
  81. package/src/components/asset-tree.tsx +21 -5
  82. package/src/components/battery-soc.tsx +8 -0
  83. package/src/components/category-chart.tsx +452 -0
  84. package/src/components/energy-flow.tsx +3 -1
  85. package/src/components/equipment-card.tsx +46 -0
  86. package/src/components/equipment-heatmap.tsx +298 -0
  87. package/src/components/equipment-table.tsx +302 -0
  88. package/src/components/metric-trend.tsx +87 -0
  89. package/src/components/operating-timeline.tsx +182 -0
  90. package/src/components/plant-fleet-map.tsx +173 -0
  91. package/src/components/threshold-gauge.tsx +152 -0
  92. package/src/components/time-range-selector.tsx +126 -0
  93. package/src/icons/index.tsx +107 -0
  94. package/src/index.ts +44 -0
  95. package/src/map/land.ts +2 -0
  96. package/src/server.ts +28 -1
  97. package/src/styles.css +133 -4
  98. package/src/virtual-focus.ts +27 -0
@@ -0,0 +1,34 @@
1
+ import type { Density, MotionProps } from "../types.js";
2
+ import type { ReactElement, RefAttributes } from "react";
3
+ export interface EquipmentColumn<T> {
4
+ id: string;
5
+ header: React.ReactNode;
6
+ cell: (item: T) => React.ReactNode;
7
+ width?: string;
8
+ sortable?: boolean;
9
+ }
10
+ export interface TableSort {
11
+ columnId: string;
12
+ direction: "ascending" | "descending";
13
+ }
14
+ export interface EquipmentTableProps<T extends {
15
+ id: string;
16
+ }> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onSelect">, MotionProps {
17
+ items: readonly T[];
18
+ columns: readonly EquipmentColumn<T>[];
19
+ sort?: TableSort;
20
+ onSortChange?: (sort: TableSort) => void;
21
+ selectedId?: string | null;
22
+ onRowSelect?: (item: T) => void;
23
+ density?: Density;
24
+ height?: number;
25
+ rowHeight?: number;
26
+ virtualized?: boolean;
27
+ empty?: React.ReactNode;
28
+ }
29
+ export declare const EquipmentTable: {
30
+ Root: <T extends {
31
+ id: string;
32
+ }>(props: EquipmentTableProps<T> & RefAttributes<HTMLDivElement>) => ReactElement;
33
+ };
34
+ //# sourceMappingURL=equipment-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equipment-table.d.ts","sourceRoot":"","sources":["../../src/components/equipment-table.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAgB,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvE,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,WAAW,GAAG,YAAY,CAAC;CACvC;AACD,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAC3D,SACE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,EACnE,WAAW;IACb,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAqQD,eAAO,MAAM,cAAc;UACC,CAAC,CAAC,SAAS;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EACjD,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,cAAc,CAAC,KAC1D,YAAY;CAClB,CAAC"}
@@ -0,0 +1,141 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useEffect, useMemo, useRef, useState } from "react";
4
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
5
+ import { useVirtualizer } from "@tanstack/react-virtual";
6
+ import { ArrowDown, ArrowUp } from "lucide-react";
7
+ import { cx } from "../internal.js";
8
+ import { MotionProvider, motionStyle } from "../motion.js";
9
+ import { useVirtualFocus } from "../virtual-focus.js";
10
+ function Root({ items, columns, sort, onSortChange, selectedId, onRowSelect, density = "comfortable", height = 360, rowHeight = density === "compact" ? 36 : 48, virtualized = true, empty, motion, style, className, onKeyDown, ...props }, ref) {
11
+ if (!Number.isFinite(height) ||
12
+ height <= 0 ||
13
+ !Number.isFinite(rowHeight) ||
14
+ rowHeight < 24)
15
+ throw new Error("EquipmentTable requires a positive height and rowHeight >= 24");
16
+ useMemo(() => {
17
+ for (const list of [items, columns]) {
18
+ const ids = new Set();
19
+ for (const item of list) {
20
+ if (!item.id || ids.has(item.id))
21
+ throw new Error("EquipmentTable row and column IDs must be nonempty and unique");
22
+ ids.add(item.id);
23
+ }
24
+ }
25
+ if (!columns.length)
26
+ throw new Error("EquipmentTable needs at least one column");
27
+ }, [items, columns]);
28
+ const host = useRef(null);
29
+ const hostRef = useComposedRefs(host, ref);
30
+ const [focused, setFocused] = useState(0);
31
+ const virtualizer = useVirtualizer({
32
+ count: items.length,
33
+ getScrollElement: () => host.current,
34
+ estimateSize: () => rowHeight,
35
+ initialRect: { width: 0, height },
36
+ overscan: 5,
37
+ enabled: virtualized,
38
+ getItemKey: (index) => items[index].id,
39
+ scrollMargin: rowHeight,
40
+ });
41
+ useEffect(() => {
42
+ virtualizer.measure();
43
+ }, [virtualizer, rowHeight]);
44
+ const focus = useVirtualFocus(host, (index) => virtualizer.scrollToIndex(index, { align: "auto" }));
45
+ const rows = virtualized
46
+ ? virtualizer.getVirtualItems()
47
+ : items.map((item, index) => ({
48
+ key: item.id,
49
+ index,
50
+ start: index * rowHeight,
51
+ }));
52
+ const tabIndex = rows.some((row) => row.index === focused)
53
+ ? focused
54
+ : rows[0]?.index;
55
+ const gridTemplateColumns = columns
56
+ .map((column) => column.width ?? "minmax(140px, 1fr)")
57
+ .join(" ");
58
+ return (_jsx(MotionProvider, { motion: motion, children: _jsxs("div", { ...props, ref: hostRef, role: onRowSelect ? "grid" : "table", tabIndex: props.tabIndex ?? (!onRowSelect || !items.length ? 0 : undefined), "aria-rowcount": items.length + 1, "aria-colcount": columns.length, "data-slot": "equipment-table", "data-density": density, className: cx("watt-root relative overflow-auto text-sm", className), style: { maxHeight: height, ...style, ...motionStyle(motion) }, onKeyDown: (event) => {
59
+ onKeyDown?.(event);
60
+ if (event.defaultPrevented ||
61
+ !onRowSelect ||
62
+ event.target !== event.currentTarget.ownerDocument.activeElement)
63
+ return;
64
+ const target = event.target;
65
+ if (target.dataset.slot !== "equipment-table-row")
66
+ return;
67
+ const index = Number(target.dataset.focusIndex);
68
+ let next;
69
+ switch (event.key) {
70
+ case "ArrowDown":
71
+ next = Math.min(items.length - 1, index + 1);
72
+ break;
73
+ case "ArrowUp":
74
+ next = Math.max(0, index - 1);
75
+ break;
76
+ case "Home":
77
+ next = 0;
78
+ break;
79
+ case "End":
80
+ next = items.length - 1;
81
+ break;
82
+ case "Enter":
83
+ case " ":
84
+ event.preventDefault();
85
+ onRowSelect(items[index]);
86
+ return;
87
+ default:
88
+ return;
89
+ }
90
+ event.preventDefault();
91
+ setFocused(next);
92
+ focus(next);
93
+ }, children: [_jsx("div", { role: "rowgroup", className: "sticky top-0 z-10 bg-[var(--watt-surface)]", children: _jsx("div", { role: "row", "aria-rowindex": 1, style: {
94
+ display: "grid",
95
+ gridTemplateColumns,
96
+ minWidth: "max-content",
97
+ minHeight: rowHeight,
98
+ }, children: columns.map((column) => (_jsx("div", { role: "columnheader", "aria-sort": column.sortable
99
+ ? sort?.columnId === column.id
100
+ ? sort.direction
101
+ : "none"
102
+ : undefined, className: "flex items-center border-b border-[var(--watt-border)] px-3 font-medium", children: column.sortable && onSortChange ? (_jsxs("button", { type: "button", className: "watt-choice inline-flex min-h-9 items-center gap-2 rounded-sm text-left focus-visible:outline-2 focus-visible:outline-[var(--watt-accent)]", onClick: () => onSortChange({
103
+ columnId: column.id,
104
+ direction: sort?.columnId === column.id &&
105
+ sort.direction === "ascending"
106
+ ? "descending"
107
+ : "ascending",
108
+ }), children: [column.header, sort?.columnId === column.id &&
109
+ (sort.direction === "ascending" ? (_jsx(ArrowUp, { size: 14 })) : (_jsx(ArrowDown, { size: 14 })))] })) : (column.header) }, column.id))) }) }), !items.length ? (empty) : (_jsx("div", { role: "rowgroup", style: {
110
+ position: "relative",
111
+ height: virtualized ? virtualizer.getTotalSize() : undefined,
112
+ }, children: rows.map((row) => {
113
+ const item = items[row.index];
114
+ return (_jsx("div", { role: "row", "aria-rowindex": row.index + 2, "data-slot": "equipment-table-row", "aria-selected": onRowSelect ? selectedId === item.id : undefined, "data-focus-index": row.index, "data-selected": selectedId === item.id || undefined, tabIndex: onRowSelect ? (tabIndex === row.index ? 0 : -1) : undefined, className: "watt-motion border-b border-[var(--watt-border)] last:border-0 outline-offset-[-2px] data-[selected]:bg-[var(--watt-subtle)] focus-visible:outline-2 focus-visible:outline-[var(--watt-accent)]", style: {
115
+ display: "grid",
116
+ gridTemplateColumns,
117
+ minWidth: "max-content",
118
+ height: rowHeight,
119
+ ...(virtualized
120
+ ? {
121
+ position: "absolute",
122
+ top: 0,
123
+ left: 0,
124
+ width: "100%",
125
+ transform: `translateY(${row.start - rowHeight}px)`,
126
+ }
127
+ : {}),
128
+ }, onFocus: (event) => {
129
+ if (event.target === event.currentTarget)
130
+ setFocused(row.index);
131
+ }, onClick: (event) => {
132
+ if (event.target.closest("button,a,input,select,textarea"))
133
+ return;
134
+ onRowSelect?.(item);
135
+ }, children: columns.map((column) => (_jsx("div", { role: onRowSelect ? "gridcell" : "cell", className: "flex min-w-0 items-center overflow-hidden px-3", children: column.cell(item) }, column.id))) }, item.id));
136
+ }) }))] }) }));
137
+ }
138
+ export const EquipmentTable = {
139
+ Root: forwardRef(Root),
140
+ };
141
+ //# sourceMappingURL=equipment-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equipment-table.js","sourceRoot":"","sources":["../../src/components/equipment-table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type MetricValueProps } from "./power-metric.js";
2
+ import type { RootProps, MotionProps, PartProps } from "../types.js";
3
+ export interface MetricTrendProps extends RootProps, MotionProps {
4
+ direction: "up" | "down" | "flat";
5
+ tone?: "neutral" | "positive" | "warning" | "critical";
6
+ }
7
+ export declare const MetricTrend: {
8
+ Root: import("react").ForwardRefExoticComponent<MetricTrendProps & import("react").RefAttributes<HTMLElement>>;
9
+ Indicator: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
10
+ Value: import("react").ForwardRefExoticComponent<MetricValueProps & import("react").RefAttributes<HTMLElement>>;
11
+ Label: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
12
+ };
13
+ //# sourceMappingURL=metric-trend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-trend.d.ts","sourceRoot":"","sources":["../../src/components/metric-trend.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrE,MAAM,WAAW,gBAAiB,SAAQ,SAAS,EAAE,WAAW;IAC9D,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;CACxD;AAED,eAAO,MAAM,WAAW;;;;;CAyEvB,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, forwardRef, useContext } from "react";
4
+ import { ArrowUpRight, ArrowDownRight, ArrowRight } from "lucide-react";
5
+ import { Slot } from "@radix-ui/react-slot";
6
+ import { cx, part } from "../internal.js";
7
+ import { MotionProvider, motionStyle } from "../motion.js";
8
+ import { PowerMetric } from "./power-metric.js";
9
+ const Context = createContext("flat");
10
+ export const MetricTrend = {
11
+ Root: forwardRef(function MetricTrendRoot({ direction, tone = "neutral", density = "comfortable", motion, style, asChild, className, ...props }, ref) {
12
+ const Component = asChild ? Slot : "span";
13
+ return (_jsx(MotionProvider, { motion: motion, children: _jsx(Context.Provider, { value: direction, children: _jsx(Component, { ...props, ref: ref, "data-slot": "metric-trend", "data-direction": direction, "data-tone": tone, "data-density": density, style: { ...style, ...motionStyle(motion) }, className: cx("watt-root inline-flex items-center gap-1.5 text-sm data-[tone=positive]:text-[var(--watt-positive)] data-[tone=warning]:text-[var(--watt-warning)] data-[tone=critical]:text-[var(--watt-critical)] data-[density=compact]:text-xs", className) }) }) }));
14
+ }),
15
+ Indicator: forwardRef(function TrendIndicator({ asChild, children, ...props }, ref) {
16
+ const direction = useContext(Context);
17
+ const Icon = direction === "up"
18
+ ? ArrowUpRight
19
+ : direction === "down"
20
+ ? ArrowDownRight
21
+ : ArrowRight;
22
+ const Component = asChild ? Slot : "span";
23
+ return (_jsx(Component, { ...props, ref: ref, "data-slot": "metric-trend-indicator", children: children ?? _jsx(Icon, { size: 16, "aria-hidden": "true" }) }));
24
+ }),
25
+ Value: forwardRef(function TrendValue({ className, ...props }, ref) {
26
+ return (_jsx(PowerMetric.Value, { ...props, ref: ref, className: cx("text-[length:inherit] font-medium tracking-normal", className) }));
27
+ }),
28
+ Label: part("metric-trend-label", "", "span"),
29
+ };
30
+ //# sourceMappingURL=metric-trend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-trend.js","sourceRoot":"","sources":["../../src/components/metric-trend.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,mBAAmB,CAAC;AAMvE,MAAM,OAAO,GAAG,aAAa,CAAgC,MAAM,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,UAAU,CAAgC,SAAS,eAAe,CACtE,EACE,SAAS,EACT,IAAI,GAAG,SAAS,EAChB,OAAO,GAAG,aAAa,EACvB,MAAM,EACN,KAAK,EACL,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG;QAEH,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1C,OAAO,CACL,KAAC,cAAc,IAAC,MAAM,EAAE,MAAM,YAC5B,KAAC,OAAO,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,YAChC,KAAC,SAAS,OACJ,KAAK,EACT,GAAG,EAAE,GAAY,eACP,cAAc,oBACR,SAAS,eACd,IAAI,kBACD,OAAO,EACrB,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,EAC3C,SAAS,EAAE,EAAE,CACX,oOAAoO,EACpO,SAAS,CACV,GACD,GACe,GACJ,CAClB,CAAC;IACJ,CAAC,CAAC;IACF,SAAS,EAAE,UAAU,CAAyB,SAAS,cAAc,CACnE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAC/B,GAAG;QAEH,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,IAAI,GACR,SAAS,KAAK,IAAI;YAChB,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,SAAS,KAAK,MAAM;gBACpB,CAAC,CAAC,cAAc;gBAChB,CAAC,CAAC,UAAU,CAAC;QACnB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1C,OAAO,CACL,KAAC,SAAS,OACJ,KAAK,EACT,GAAG,EAAE,GAAY,eACP,wBAAwB,YAEjC,QAAQ,IAAI,KAAC,IAAI,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,GACxC,CACb,CAAC;IACJ,CAAC,CAAC;IACF,KAAK,EAAE,UAAU,CAAgC,SAAS,UAAU,CAClE,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EACvB,GAAG;QAEH,OAAO,CACL,KAAC,WAAW,CAAC,KAAK,OACZ,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,mDAAmD,EACnD,SAAS,CACV,GACD,CACH,CAAC;IACJ,CAAC,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,EAAE,MAAM,CAAC;CAC9C,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Timestamp, TimeRange, Density, MotionProps } from "../types.js";
2
+ import type { ReactElement, RefAttributes } from "react";
3
+ export interface TimelineTrack {
4
+ id: string;
5
+ label: React.ReactNode;
6
+ }
7
+ export interface TimelineEvent {
8
+ id: string;
9
+ trackId: string;
10
+ start: Timestamp;
11
+ end: Timestamp;
12
+ label: string;
13
+ color?: string;
14
+ }
15
+ export interface OperatingTimelineProps<T extends TimelineEvent = TimelineEvent> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onSelect">, MotionProps {
16
+ events: readonly T[];
17
+ tracks: readonly TimelineTrack[];
18
+ range: TimeRange;
19
+ timeZone: string;
20
+ selectedId?: string | null;
21
+ onEventSelect?: (event: T) => void;
22
+ children?: (event: T) => React.ReactNode;
23
+ density?: Density;
24
+ timeFormatter?: (timestamp: number) => string;
25
+ empty?: React.ReactNode;
26
+ }
27
+ export declare const OperatingTimeline: {
28
+ Root: <T extends TimelineEvent>(props: OperatingTimelineProps<T> & RefAttributes<HTMLDivElement>) => ReactElement;
29
+ Legend: import("react").ForwardRefExoticComponent<import("../types.js").PartProps & RefAttributes<HTMLElement>>;
30
+ };
31
+ //# sourceMappingURL=operating-timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operating-timeline.d.ts","sourceRoot":"","sources":["../../src/components/operating-timeline.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAgB,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AACD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,CAC7E,SACE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,EACnE,WAAW;IACb,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AA4ID,eAAO,MAAM,iBAAiB;UACF,CAAC,CAAC,SAAS,aAAa,EAChD,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,cAAc,CAAC,KAC7D,YAAY;;CAKlB,CAAC"}
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useMemo, useState } from "react";
4
+ import { cx, part } from "../internal.js";
5
+ import { parseTimestamp } from "../domain.js";
6
+ import { motionStyle } from "../motion.js";
7
+ function Root({ events, tracks, range, timeZone, selectedId, onEventSelect, children, density = "comfortable", timeFormatter, empty, motion, style, className, ...props }, ref) {
8
+ const [internal, setInternal] = useState(null);
9
+ const selected = selectedId === undefined ? internal : selectedId;
10
+ const grouped = useMemo(() => {
11
+ if (!Number.isFinite(range[0]) ||
12
+ !Number.isFinite(range[1]) ||
13
+ range[1] <= range[0])
14
+ throw new Error("OperatingTimeline requires finite start < end");
15
+ const groups = new Map(tracks.map((track) => [
16
+ track.id,
17
+ [],
18
+ ]));
19
+ if (groups.size !== tracks.length || tracks.some((track) => !track.id))
20
+ throw new Error("Timeline track IDs must be nonempty and unique");
21
+ const ids = new Set();
22
+ for (const event of events) {
23
+ const start = parseTimestamp(event.start), end = parseTimestamp(event.end);
24
+ if (!event.id ||
25
+ ids.has(event.id) ||
26
+ start === null ||
27
+ end === null ||
28
+ end < start ||
29
+ !groups.has(event.trackId))
30
+ throw new Error("Timeline events need unique IDs, a known track and valid start <= end");
31
+ ids.add(event.id);
32
+ if (end >= range[0] && start <= range[1])
33
+ groups.get(event.trackId).push({ event, start, end });
34
+ }
35
+ return groups;
36
+ }, [events, tracks, range]);
37
+ const label = timeFormatter ??
38
+ new Intl.DateTimeFormat("en-GB", {
39
+ timeZone,
40
+ dateStyle: "short",
41
+ timeStyle: "short",
42
+ hour12: false,
43
+ }).format;
44
+ const rowHeight = density === "compact" ? 40 : 52;
45
+ return (_jsx("div", { ...props, ref: ref, "data-slot": "operating-timeline", tabIndex: props.tabIndex ?? 0, "data-density": density, className: cx("watt-root overflow-auto text-sm", className), style: { ...style, ...motionStyle(motion) }, children: _jsxs("div", { className: "min-w-[280px]", children: [_jsxs("div", { "data-slot": "operating-timeline-range", className: "mb-3 grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] gap-2 pl-28 text-xs text-[var(--watt-muted)]", children: [_jsx("span", { children: label(range[0]) }), _jsx("span", { children: timeZone }), _jsx("span", { className: "text-right", children: label(range[1]) })] }), !events.length && empty, tracks.map((track) => (_jsxs("div", { "data-slot": "operating-timeline-track", className: "grid grid-cols-[7rem_minmax(0,1fr)] items-center border-b border-[var(--watt-border)] last:border-0", style: { minHeight: rowHeight }, children: [_jsx("span", { className: "pr-3 text-xs", children: track.label }), _jsx("div", { role: "list", "aria-label": typeof track.label === "string" ? track.label : track.id, className: "relative", style: { height: rowHeight }, children: grouped.get(track.id).map(({ event, start, end }) => (_jsx("div", { role: "listitem", className: "watt-motion watt-timeline-event absolute inset-y-2", style: {
46
+ left: `clamp(0px, ${((Math.max(start, range[0]) - range[0]) / (range[1] - range[0])) * 100}%, calc(100% - 16px))`,
47
+ minWidth: 16,
48
+ width: `${Math.max(0.6, ((Math.min(end, range[1]) - Math.max(start, range[0])) / (range[1] - range[0])) * 100)}%`,
49
+ }, children: _jsx("button", { type: "button", "data-slot": "operating-timeline-event", "data-selected": selected === event.id || undefined, "aria-pressed": selected === event.id, "aria-label": `${event.label}, ${label(start)}–${label(end)} ${timeZone}`, className: "h-full w-full overflow-hidden rounded-sm border border-[var(--watt-border)] px-1.5 text-left text-xs whitespace-nowrap outline-offset-2 data-[selected]:outline-2 data-[selected]:outline-[var(--watt-accent)] focus-visible:outline-2 focus-visible:outline-[var(--watt-accent)]", style: {
50
+ backgroundColor: event.color ?? "var(--watt-subtle)",
51
+ }, onClick: () => {
52
+ if (selectedId === undefined)
53
+ setInternal(event.id);
54
+ onEventSelect?.(event);
55
+ }, children: children ? children(event) : event.label }) }, event.id))) })] }, track.id)))] }) }));
56
+ }
57
+ export const OperatingTimeline = {
58
+ Root: forwardRef(Root),
59
+ Legend: part("operating-timeline-legend", "flex flex-wrap gap-4 text-xs text-[var(--watt-muted)]"),
60
+ };
61
+ //# sourceMappingURL=operating-timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operating-timeline.js","sourceRoot":"","sources":["../../src/components/operating-timeline.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { DataQuality, Density, EquipmentStatus, MotionProps } from "../types.js";
2
+ import type { ReactElement, RefAttributes } from "react";
3
+ export interface FleetSite {
4
+ id: string;
5
+ label: string;
6
+ longitude: number;
7
+ latitude: number;
8
+ status?: EquipmentStatus;
9
+ quality?: DataQuality;
10
+ }
11
+ export type MapBounds = readonly [
12
+ west: number,
13
+ south: number,
14
+ east: number,
15
+ north: number
16
+ ];
17
+ export interface PlantFleetMapProps<T extends FleetSite = FleetSite> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, MotionProps {
18
+ sites: readonly T[];
19
+ density?: Density;
20
+ bounds?: MapBounds;
21
+ selectedId?: string | null;
22
+ defaultSelectedId?: string | null;
23
+ onSelectionChange?: (site: T) => void;
24
+ children?: (site: T, selected: boolean) => React.ReactNode;
25
+ background?: React.ReactNode;
26
+ empty?: React.ReactNode;
27
+ }
28
+ export declare const PlantFleetMap: {
29
+ Root: <T extends FleetSite>(props: PlantFleetMapProps<T> & RefAttributes<HTMLDivElement>) => ReactElement;
30
+ Legend: import("react").ForwardRefExoticComponent<import("../types.js").PartProps & RefAttributes<HTMLElement>>;
31
+ };
32
+ //# sourceMappingURL=plant-fleet-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plant-fleet-map.d.ts","sourceRoot":"","sources":["../../src/components/plant-fleet-map.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,OAAO,EACP,eAAe,EACf,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAgB,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AACD,MAAM,MAAM,SAAS,GAAG,SAAS;IAC/B,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;CACd,CAAC;AACF,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CACjE,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,EAAE,WAAW;IAC3E,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IAC3D,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AA+HD,eAAO,MAAM,aAAa;UACE,CAAC,CAAC,SAAS,SAAS,EAC5C,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,cAAc,CAAC,KACzD,YAAY;;CAKlB,CAAC"}
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useMemo, useState } from "react";
4
+ import { cx, part } from "../internal.js";
5
+ import { motionStyle } from "../motion.js";
6
+ import { landPath } from "../map/land.js";
7
+ const WORLD = [-180, -75, 180, 85];
8
+ function Root({ sites, bounds = WORLD, selectedId, defaultSelectedId = null, onSelectionChange, children, background, empty, density = "comfortable", motion, style, className, ...props }, ref) {
9
+ const [internal, setInternal] = useState(defaultSelectedId);
10
+ const selected = selectedId === undefined ? internal : selectedId;
11
+ const visible = useMemo(() => {
12
+ const [west, south, east, north] = bounds;
13
+ if (!bounds.every(Number.isFinite) ||
14
+ west < -180 ||
15
+ east > 180 ||
16
+ south < -90 ||
17
+ north > 90 ||
18
+ west >= east ||
19
+ south >= north)
20
+ throw new Error("Map bounds must be finite west < east and south < north within longitude/latitude limits");
21
+ const ids = new Set();
22
+ for (const site of sites) {
23
+ if (!site.id ||
24
+ ids.has(site.id) ||
25
+ !Number.isFinite(site.longitude) ||
26
+ Math.abs(site.longitude) > 180 ||
27
+ !Number.isFinite(site.latitude) ||
28
+ Math.abs(site.latitude) > 90)
29
+ throw new Error("Map sites need unique IDs and valid longitude/latitude");
30
+ ids.add(site.id);
31
+ }
32
+ return sites.filter((site) => site.longitude >= west &&
33
+ site.longitude <= east &&
34
+ site.latitude >= south &&
35
+ site.latitude <= north);
36
+ }, [sites, bounds]);
37
+ return (_jsxs("div", { ...props, ref: ref, "data-slot": "plant-fleet-map", "data-density": density, className: cx("watt-root relative isolate overflow-hidden rounded-sm bg-[var(--watt-subtle)]", className), style: {
38
+ aspectRatio: (bounds[2] - bounds[0]) / (bounds[3] - bounds[1]),
39
+ ...style,
40
+ ...motionStyle(motion),
41
+ }, children: [background ?? (_jsx("svg", { "aria-hidden": "true", className: "absolute inset-0 h-full w-full", preserveAspectRatio: "none", viewBox: `${(bounds[0] + 180) * 2} ${(90 - bounds[3]) * 2} ${(bounds[2] - bounds[0]) * 2} ${(bounds[3] - bounds[1]) * 2}`, children: _jsx("path", { d: landPath, fill: "var(--watt-surface)", stroke: "var(--watt-border)", strokeWidth: ".7", vectorEffect: "non-scaling-stroke" }) })), !visible.length && _jsx("div", { className: "relative p-6 text-sm", children: empty }), visible.map((site) => (_jsx("button", { type: "button", "data-slot": "plant-fleet-map-site", "data-selected": selected === site.id || undefined, "data-status": site.status, "data-quality": site.quality, "aria-label": [site.label, site.status, site.quality]
42
+ .filter(Boolean)
43
+ .join(", "), "aria-pressed": selected === site.id, title: site.label, className: "watt-motion watt-choice absolute z-10 inline-flex min-h-9 min-w-9 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full focus-visible:outline-2 focus-visible:outline-[var(--watt-accent)] data-[selected]:outline-2 data-[selected]:outline-[var(--watt-accent)]", style: {
44
+ left: `${((site.longitude - bounds[0]) / (bounds[2] - bounds[0])) * 100}%`,
45
+ top: `${((bounds[3] - site.latitude) / (bounds[3] - bounds[1])) * 100}%`,
46
+ }, onClick: () => {
47
+ if (selectedId === undefined)
48
+ setInternal(site.id);
49
+ onSelectionChange?.(site);
50
+ }, children: children ? (children(site, selected === site.id)) : (_jsx("span", { className: "watt-status", "data-status": site.status, children: _jsx("span", { className: "watt-status-dot" }) })) }, site.id)))] }));
51
+ }
52
+ export const PlantFleetMap = {
53
+ Root: forwardRef(Root),
54
+ Legend: part("plant-fleet-map-legend", "flex flex-wrap gap-4 text-xs text-[var(--watt-muted)]"),
55
+ };
56
+ //# sourceMappingURL=plant-fleet-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plant-fleet-map.js","sourceRoot":"","sources":["../../src/components/plant-fleet-map.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { RootProps, MotionProps, PartProps } from "../types.js";
2
+ export interface ThresholdGaugeProps extends RootProps, MotionProps {
3
+ value: number | null;
4
+ min?: number;
5
+ max: number;
6
+ valueText?: string;
7
+ tone?: "neutral" | "positive" | "warning" | "critical";
8
+ }
9
+ export declare const ThresholdGauge: {
10
+ Root: import("react").ForwardRefExoticComponent<ThresholdGaugeProps & import("react").RefAttributes<HTMLElement>>;
11
+ Track: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
12
+ Fill: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
13
+ Marker: import("react").ForwardRefExoticComponent<PartProps & {
14
+ value: number;
15
+ } & import("react").RefAttributes<HTMLElement>>;
16
+ Label: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
17
+ Description: import("react").ForwardRefExoticComponent<PartProps & import("react").RefAttributes<HTMLElement>>;
18
+ };
19
+ //# sourceMappingURL=threshold-gauge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threshold-gauge.d.ts","sourceRoot":"","sources":["../../src/components/threshold-gauge.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrE,MAAM,WAAW,mBAAoB,SAAQ,SAAS,EAAE,WAAW;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;CACxD;AAeD,eAAO,MAAM,cAAc;;;;;eAqG4B,MAAM;;;;CAuB5D,CAAC"}
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, forwardRef, useContext } from "react";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { cx, part } from "../internal.js";
6
+ import { MotionProvider, motionStyle } from "../motion.js";
7
+ const Context = createContext(null);
8
+ function useGauge() {
9
+ const context = useContext(Context);
10
+ if (!context)
11
+ throw new Error("ThresholdGauge parts require ThresholdGauge.Root");
12
+ return context;
13
+ }
14
+ export const ThresholdGauge = {
15
+ Root: forwardRef(function GaugeRoot({ value, min = 0, max, valueText, tone = "neutral", density = "comfortable", motion, style, asChild, className, ...props }, ref) {
16
+ if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min)
17
+ throw new Error("ThresholdGauge requires finite min < max");
18
+ const valid = value !== null && Number.isFinite(value) && value >= min && value <= max;
19
+ const Component = asChild ? Slot : "div";
20
+ return (_jsx(MotionProvider, { motion: motion, children: _jsx(Context.Provider, { value: {
21
+ min,
22
+ max,
23
+ value: valid ? value : null,
24
+ valueText,
25
+ percent: valid ? ((value - min) / (max - min)) * 100 : 0,
26
+ }, children: _jsx(Component, { ...props, ref: ref, "data-slot": "threshold-gauge", "data-density": density, "data-tone": tone, "data-invalid": !valid || undefined, style: { ...style, ...motionStyle(motion) }, className: cx("watt-root", className) }) }) }));
27
+ }),
28
+ Track: forwardRef(function GaugeTrack({ asChild, className, ...props }, ref) {
29
+ const { value, min, max, valueText } = useGauge();
30
+ const Component = asChild ? Slot : "div";
31
+ return (_jsx(Component, { ...props, ref: ref, "data-slot": "threshold-gauge-track", role: value === null ? "img" : "meter", "aria-valuemin": value === null ? undefined : min, "aria-valuemax": value === null ? undefined : max, "aria-valuenow": value ?? undefined, "aria-valuetext": value === null ? undefined : (props["aria-valuetext"] ?? valueText), "aria-description": value === null
32
+ ? (props["aria-valuetext"] ?? valueText ?? "Unavailable")
33
+ : props["aria-description"], className: cx("relative h-2.5 rounded-sm bg-[var(--watt-subtle)]", className) }));
34
+ }),
35
+ Fill: forwardRef(function GaugeFill({ asChild, className, style, ...props }, ref) {
36
+ const { percent, value } = useGauge();
37
+ const Component = asChild ? Slot : "div";
38
+ return (_jsx(Component, { ...props, ref: ref, "data-slot": "threshold-gauge-fill", "aria-hidden": "true", className: cx("watt-motion watt-gauge-fill h-full rounded-sm bg-[var(--watt-accent)]", className), style: {
39
+ width: `${percent}%`,
40
+ ...(value === null ? { transitionDuration: "0ms" } : {}),
41
+ ...style,
42
+ } }));
43
+ }),
44
+ Marker: forwardRef(function GaugeMarker({ value, asChild, style, className, ...props }, ref) {
45
+ const { min, max } = useGauge();
46
+ if (!Number.isFinite(value) || value < min || value > max)
47
+ throw new Error("Gauge marker must be within min and max");
48
+ const Component = asChild ? Slot : "span";
49
+ return (_jsx(Component, { ...props, ref: ref, "data-slot": "threshold-gauge-marker", className: cx("absolute inset-y-0 w-px bg-current", className), style: { left: `${((value - min) / (max - min)) * 100}%`, ...style } }));
50
+ }),
51
+ Label: part("threshold-gauge-label", "text-sm", "span"),
52
+ Description: part("threshold-gauge-description", "text-sm text-[var(--watt-muted)]", "span"),
53
+ };
54
+ //# sourceMappingURL=threshold-gauge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threshold-gauge.js","sourceRoot":"","sources":["../../src/components/threshold-gauge.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { MotionProps, TimeRange, Density } from "../types.js";
2
+ export interface TimeRangeSelectorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "defaultValue">, MotionProps {
3
+ value?: TimeRange | null;
4
+ defaultValue?: TimeRange | null;
5
+ onValueChange?: (range: TimeRange | null) => void;
6
+ orientation?: "horizontal" | "vertical";
7
+ density?: Density;
8
+ }
9
+ export interface TimeRangeOptionProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "type" | "checked" | "defaultChecked" | "name"> {
10
+ range: TimeRange | null;
11
+ }
12
+ export declare const TimeRangeSelector: {
13
+ Root: import("react").ForwardRefExoticComponent<TimeRangeSelectorProps & import("react").RefAttributes<HTMLDivElement>>;
14
+ Option: import("react").ForwardRefExoticComponent<TimeRangeOptionProps & import("react").RefAttributes<HTMLInputElement>>;
15
+ };
16
+ //# sourceMappingURL=time-range-selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-range-selector.d.ts","sourceRoot":"","sources":["../../src/components/time-range-selector.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAgBnE,MAAM,WAAW,sBACf,SACE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,EAC1D,WAAW;IACb,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACD,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,MAAM,CACzD;IACC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB;AACD,eAAO,MAAM,iBAAiB;;;CAyF7B,CAAC"}