@contractspec/lib.ui-kit-web 3.7.5 → 3.8.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 (234) hide show
  1. package/README.md +33 -88
  2. package/dist/browser/ui/accordion.js +4 -4
  3. package/dist/browser/ui/alert-dialog.js +9 -9
  4. package/dist/browser/ui/alert.js +4 -4
  5. package/dist/browser/ui/atoms/FilterSelect/FilterSelect.js +51 -51
  6. package/dist/browser/ui/atoms/FilterSelect/index.js +51 -51
  7. package/dist/browser/ui/atoms/LoadingSpinner/LoadingSpinner.js +1 -1
  8. package/dist/browser/ui/atoms/Pagination/Pagination.js +13 -13
  9. package/dist/browser/ui/atoms/Pagination/index.js +13 -13
  10. package/dist/browser/ui/atoms/SearchInput/SearchInput.js +8 -8
  11. package/dist/browser/ui/atoms/SearchInput/index.js +8 -8
  12. package/dist/browser/ui/avatar.js +1 -1
  13. package/dist/browser/ui/badge.js +3 -3
  14. package/dist/browser/ui/breadcrumb.js +4 -4
  15. package/dist/browser/ui/button.js +5 -5
  16. package/dist/browser/ui/calendar.js +21 -21
  17. package/dist/browser/ui/card.js +2 -2
  18. package/dist/browser/ui/carousel.js +6 -6
  19. package/dist/browser/ui/checkbox.js +2 -2
  20. package/dist/browser/ui/command.js +14 -14
  21. package/dist/browser/ui/confirm-dialog.js +9 -9
  22. package/dist/browser/ui/context-menu.js +10 -10
  23. package/dist/browser/ui/cta.js +5 -5
  24. package/dist/browser/ui/data-table.js +1005 -0
  25. package/dist/browser/ui/data-table.parts.js +463 -0
  26. package/dist/browser/ui/date-picker.js +26 -26
  27. package/dist/browser/ui/date-range-picker.js +24 -24
  28. package/dist/browser/ui/datetime-picker.js +29 -29
  29. package/dist/browser/ui/dialog.js +5 -5
  30. package/dist/browser/ui/drawer.js +5 -5
  31. package/dist/browser/ui/dropdown-menu.js +10 -10
  32. package/dist/browser/ui/empty-state.js +5 -5
  33. package/dist/browser/ui/empty.js +7 -7
  34. package/dist/browser/ui/field.js +12 -12
  35. package/dist/browser/ui/form.js +4 -4
  36. package/dist/browser/ui/hover-card.js +2 -2
  37. package/dist/browser/ui/input-group.js +16 -16
  38. package/dist/browser/ui/input-otp.js +4 -4
  39. package/dist/browser/ui/input.js +1 -1
  40. package/dist/browser/ui/label.js +2 -2
  41. package/dist/browser/ui/loading-button.js +8 -8
  42. package/dist/browser/ui/marketing/FeatureGrid.js +3 -3
  43. package/dist/browser/ui/marketing/Hero.js +7 -7
  44. package/dist/browser/ui/marketing/PricingTable.js +10 -10
  45. package/dist/browser/ui/menubar.js +12 -12
  46. package/dist/browser/ui/molecules/Autocomplete/index.js +26 -26
  47. package/dist/browser/ui/molecules/SearchAndFilter/SearchAndFilter.js +62 -62
  48. package/dist/browser/ui/molecules/SearchAndFilter/index.js +62 -62
  49. package/dist/browser/ui/molecules/SkeletonList.js +1 -1
  50. package/dist/browser/ui/nav-layout.js +22 -22
  51. package/dist/browser/ui/navigation-menu.js +7 -7
  52. package/dist/browser/ui/organisms/ErrorBoundary/ErrorBoundary.js +11 -11
  53. package/dist/browser/ui/organisms/ListPage/ListPage.js +84 -84
  54. package/dist/browser/ui/page-header.js +4 -4
  55. package/dist/browser/ui/pagination.js +6 -6
  56. package/dist/browser/ui/popover.js +2 -2
  57. package/dist/browser/ui/progress.js +3 -3
  58. package/dist/browser/ui/radio-group.js +3 -3
  59. package/dist/browser/ui/resizable.js +3 -3
  60. package/dist/browser/ui/scroll-area.js +4 -4
  61. package/dist/browser/ui/section.js +1 -1
  62. package/dist/browser/ui/select.js +6 -6
  63. package/dist/browser/ui/separator.js +2 -2
  64. package/dist/browser/ui/sheet.js +5 -5
  65. package/dist/browser/ui/sidebar.js +64 -64
  66. package/dist/browser/ui/skeleton.js +1 -1
  67. package/dist/browser/ui/slider.js +6 -6
  68. package/dist/browser/ui/stack.js +1 -1
  69. package/dist/browser/ui/stat-card-group.js +5 -5
  70. package/dist/browser/ui/stepper.js +2 -2
  71. package/dist/browser/ui/switch.js +3 -3
  72. package/dist/browser/ui/table.js +5 -5
  73. package/dist/browser/ui/tabs.js +3 -3
  74. package/dist/browser/ui/text.js +2 -2
  75. package/dist/browser/ui/textarea.js +1 -1
  76. package/dist/browser/ui/time-picker.js +10 -10
  77. package/dist/browser/ui/toast.js +5 -5
  78. package/dist/browser/ui/toaster.js +5 -5
  79. package/dist/browser/ui/toggle-group.js +7 -7
  80. package/dist/browser/ui/toggle.js +5 -5
  81. package/dist/browser/ui/tooltip.js +3 -3
  82. package/dist/browser/ui/typography.js +14 -14
  83. package/dist/browser/ui/usecases/UseCaseCard.js +8 -8
  84. package/dist/browser/ui/usecases/UserStoryCard.js +3 -3
  85. package/dist/browser/ui/visualization/Visualization.js +439 -0
  86. package/dist/browser/ui/visualization/Visualization.support.js +128 -0
  87. package/dist/browser/ui/visualization/index.js +10 -0
  88. package/dist/ui/accordion.d.ts +2 -2
  89. package/dist/ui/accordion.js +4 -4
  90. package/dist/ui/alert-dialog.d.ts +2 -2
  91. package/dist/ui/alert-dialog.js +9 -9
  92. package/dist/ui/alert.d.ts +2 -2
  93. package/dist/ui/alert.js +4 -4
  94. package/dist/ui/atoms/FilterSelect/FilterSelect.js +51 -51
  95. package/dist/ui/atoms/FilterSelect/index.d.ts +1 -1
  96. package/dist/ui/atoms/FilterSelect/index.js +51 -51
  97. package/dist/ui/atoms/LoadingSpinner/LoadingSpinner.js +1 -1
  98. package/dist/ui/atoms/LoadingSpinner/index.d.ts +1 -1
  99. package/dist/ui/atoms/Pagination/Pagination.js +13 -13
  100. package/dist/ui/atoms/Pagination/index.js +13 -13
  101. package/dist/ui/atoms/SearchInput/SearchInput.js +8 -8
  102. package/dist/ui/atoms/SearchInput/index.js +8 -8
  103. package/dist/ui/avatar.d.ts +2 -2
  104. package/dist/ui/avatar.js +1 -1
  105. package/dist/ui/badge.d.ts +1 -1
  106. package/dist/ui/badge.js +3 -3
  107. package/dist/ui/breadcrumb.d.ts +1 -1
  108. package/dist/ui/breadcrumb.js +4 -4
  109. package/dist/ui/button.d.ts +1 -1
  110. package/dist/ui/button.js +5 -5
  111. package/dist/ui/calendar.js +21 -21
  112. package/dist/ui/card.d.ts +1 -1
  113. package/dist/ui/card.js +2 -2
  114. package/dist/ui/carousel.d.ts +2 -2
  115. package/dist/ui/carousel.js +6 -6
  116. package/dist/ui/checkbox.d.ts +1 -1
  117. package/dist/ui/checkbox.js +2 -2
  118. package/dist/ui/collapsible.d.ts +1 -1
  119. package/dist/ui/command.d.ts +2 -2
  120. package/dist/ui/command.js +14 -14
  121. package/dist/ui/confirm-dialog.js +9 -9
  122. package/dist/ui/context-menu.d.ts +2 -2
  123. package/dist/ui/context-menu.js +10 -10
  124. package/dist/ui/cta.js +5 -5
  125. package/dist/ui/data-table.d.ts +12 -0
  126. package/dist/ui/data-table.js +1000 -0
  127. package/dist/ui/data-table.parts.d.ts +14 -0
  128. package/dist/ui/data-table.parts.js +458 -0
  129. package/dist/ui/date-picker.js +26 -26
  130. package/dist/ui/date-range-picker.js +24 -24
  131. package/dist/ui/datetime-picker.js +29 -29
  132. package/dist/ui/dialog.d.ts +1 -1
  133. package/dist/ui/dialog.js +5 -5
  134. package/dist/ui/drawer.d.ts +1 -1
  135. package/dist/ui/drawer.js +5 -5
  136. package/dist/ui/dropdown-menu.d.ts +2 -2
  137. package/dist/ui/dropdown-menu.js +10 -10
  138. package/dist/ui/empty-state.d.ts +1 -1
  139. package/dist/ui/empty-state.js +5 -5
  140. package/dist/ui/empty.d.ts +2 -2
  141. package/dist/ui/empty.js +7 -7
  142. package/dist/ui/field.d.ts +2 -2
  143. package/dist/ui/field.js +12 -12
  144. package/dist/ui/form.d.ts +3 -3
  145. package/dist/ui/form.js +4 -4
  146. package/dist/ui/hover-card.d.ts +2 -2
  147. package/dist/ui/hover-card.js +2 -2
  148. package/dist/ui/input-group.d.ts +2 -2
  149. package/dist/ui/input-group.js +16 -16
  150. package/dist/ui/input-otp.d.ts +2 -2
  151. package/dist/ui/input-otp.js +4 -4
  152. package/dist/ui/input.js +1 -1
  153. package/dist/ui/label.d.ts +1 -1
  154. package/dist/ui/label.js +2 -2
  155. package/dist/ui/loading-button.js +8 -8
  156. package/dist/ui/map/index.d.ts +1 -1
  157. package/dist/ui/marketing/FeatureGrid.js +3 -3
  158. package/dist/ui/marketing/Hero.js +7 -7
  159. package/dist/ui/marketing/PricingTable.js +10 -10
  160. package/dist/ui/marketing/index.d.ts +1 -1
  161. package/dist/ui/menubar.d.ts +2 -2
  162. package/dist/ui/menubar.js +12 -12
  163. package/dist/ui/molecules/Autocomplete/index.js +26 -26
  164. package/dist/ui/molecules/SearchAndFilter/SearchAndFilter.js +62 -62
  165. package/dist/ui/molecules/SearchAndFilter/index.js +62 -62
  166. package/dist/ui/molecules/SkeletonList.js +1 -1
  167. package/dist/ui/nav-layout.d.ts +1 -1
  168. package/dist/ui/nav-layout.js +22 -22
  169. package/dist/ui/navigation-menu.d.ts +2 -2
  170. package/dist/ui/navigation-menu.js +7 -7
  171. package/dist/ui/organisms/ErrorBoundary/ErrorBoundary.js +11 -11
  172. package/dist/ui/organisms/ErrorBoundary/index.d.ts +1 -1
  173. package/dist/ui/organisms/ListPage/ListPage.js +84 -84
  174. package/dist/ui/organisms/ListPage/index.d.ts +1 -1
  175. package/dist/ui/organisms/ListPage/types.d.ts +1 -1
  176. package/dist/ui/page-header.d.ts +1 -1
  177. package/dist/ui/page-header.js +4 -4
  178. package/dist/ui/pagination.js +6 -6
  179. package/dist/ui/popover.d.ts +2 -2
  180. package/dist/ui/popover.js +2 -2
  181. package/dist/ui/progress.d.ts +1 -1
  182. package/dist/ui/progress.js +3 -3
  183. package/dist/ui/radio-group.d.ts +1 -1
  184. package/dist/ui/radio-group.js +3 -3
  185. package/dist/ui/resizable.d.ts +2 -2
  186. package/dist/ui/resizable.js +3 -3
  187. package/dist/ui/scroll-area.d.ts +1 -1
  188. package/dist/ui/scroll-area.js +4 -4
  189. package/dist/ui/section.d.ts +1 -1
  190. package/dist/ui/section.js +1 -1
  191. package/dist/ui/select.d.ts +1 -1
  192. package/dist/ui/select.js +6 -6
  193. package/dist/ui/separator.d.ts +1 -1
  194. package/dist/ui/separator.js +2 -2
  195. package/dist/ui/sheet.d.ts +2 -2
  196. package/dist/ui/sheet.js +5 -5
  197. package/dist/ui/sidebar.d.ts +1 -1
  198. package/dist/ui/sidebar.js +64 -64
  199. package/dist/ui/skeleton.js +1 -1
  200. package/dist/ui/slider.d.ts +1 -1
  201. package/dist/ui/slider.js +6 -6
  202. package/dist/ui/stack.d.ts +4 -4
  203. package/dist/ui/stack.js +1 -1
  204. package/dist/ui/stat-card-group.js +5 -5
  205. package/dist/ui/stepper.js +2 -2
  206. package/dist/ui/switch.d.ts +1 -1
  207. package/dist/ui/switch.js +3 -3
  208. package/dist/ui/table.d.ts +1 -1
  209. package/dist/ui/table.js +5 -5
  210. package/dist/ui/tabs.d.ts +2 -2
  211. package/dist/ui/tabs.js +3 -3
  212. package/dist/ui/text.js +2 -2
  213. package/dist/ui/textarea.js +1 -1
  214. package/dist/ui/time-picker.js +10 -10
  215. package/dist/ui/toast.d.ts +2 -2
  216. package/dist/ui/toast.js +5 -5
  217. package/dist/ui/toaster.js +5 -5
  218. package/dist/ui/toggle-group.d.ts +1 -1
  219. package/dist/ui/toggle-group.js +7 -7
  220. package/dist/ui/toggle.d.ts +1 -1
  221. package/dist/ui/toggle.js +5 -5
  222. package/dist/ui/tooltip.d.ts +2 -2
  223. package/dist/ui/tooltip.js +3 -3
  224. package/dist/ui/typography.js +14 -14
  225. package/dist/ui/use-toast.d.ts +1 -1
  226. package/dist/ui/usecases/UseCaseCard.js +8 -8
  227. package/dist/ui/usecases/UserStoryCard.js +3 -3
  228. package/dist/ui/visualization/Visualization.d.ts +9 -0
  229. package/dist/ui/visualization/Visualization.js +434 -0
  230. package/dist/ui/visualization/Visualization.support.d.ts +15 -0
  231. package/dist/ui/visualization/Visualization.support.js +123 -0
  232. package/dist/ui/visualization/index.d.ts +1 -0
  233. package/dist/ui/visualization/index.js +5 -0
  234. package/package.json +75 -12
@@ -0,0 +1,434 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // ui/map/MapBase.tsx
5
+ import * as React from "react";
6
+ import Map, {
7
+ NavigationControl,
8
+ ScaleControl
9
+ } from "react-map-gl/maplibre";
10
+ import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
11
+ "use client";
12
+ var DEFAULT_STYLE = "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json";
13
+ function MapBase(props) {
14
+ const {
15
+ initialViewState = { longitude: 2.3522, latitude: 48.8566, zoom: 5 },
16
+ styleUrl = DEFAULT_STYLE,
17
+ style,
18
+ showControls = true,
19
+ showCssLink = true,
20
+ onMapRef,
21
+ children
22
+ } = props;
23
+ const mapRef = React.useRef(null);
24
+ React.useEffect(() => {
25
+ onMapRef?.(mapRef.current);
26
+ }, [mapRef.current]);
27
+ return /* @__PURE__ */ jsxDEV("div", {
28
+ style: {
29
+ position: "relative",
30
+ width: "100%",
31
+ height: "100%",
32
+ ...style || {}
33
+ },
34
+ children: [
35
+ showCssLink && /* @__PURE__ */ jsxDEV("link", {
36
+ href: "https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.css",
37
+ rel: "stylesheet"
38
+ }, undefined, false, undefined, this),
39
+ /* @__PURE__ */ jsxDEV(Map, {
40
+ ref: mapRef,
41
+ mapLib: import("maplibre-gl"),
42
+ initialViewState,
43
+ style: { width: "100%", height: "100%" },
44
+ mapStyle: styleUrl,
45
+ maplibreLogo: false,
46
+ children: [
47
+ showControls && /* @__PURE__ */ jsxDEV(Fragment, {
48
+ children: [
49
+ /* @__PURE__ */ jsxDEV(ScaleControl, {
50
+ position: "bottom-left"
51
+ }, undefined, false, undefined, this),
52
+ /* @__PURE__ */ jsxDEV(NavigationControl, {
53
+ position: "bottom-left"
54
+ }, undefined, false, undefined, this)
55
+ ]
56
+ }, undefined, true, undefined, this),
57
+ children
58
+ ]
59
+ }, undefined, true, undefined, this)
60
+ ]
61
+ }, undefined, true, undefined, this);
62
+ }
63
+
64
+ // ui/map/MapGeoJsonOverlay.tsx
65
+ import { Layer, Source } from "react-map-gl/maplibre";
66
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
67
+ "use client";
68
+ function MapGeoJsonOverlay(props) {
69
+ const {
70
+ id = "geojson-overlay",
71
+ data,
72
+ fillColor = "#2563eb",
73
+ fillOpacity = 0.25,
74
+ lineColor = "#1e40af",
75
+ lineWidth = 1.5,
76
+ lineOpacity = 0.8
77
+ } = props;
78
+ const fillLayer = {
79
+ id: `${id}-fill`,
80
+ type: "fill",
81
+ paint: {
82
+ "fill-color": fillColor,
83
+ "fill-opacity": fillOpacity
84
+ }
85
+ };
86
+ const outlineLayer = {
87
+ id: `${id}-outline`,
88
+ type: "line",
89
+ paint: {
90
+ "line-color": lineColor,
91
+ "line-width": lineWidth,
92
+ "line-opacity": lineOpacity
93
+ }
94
+ };
95
+ return /* @__PURE__ */ jsxDEV2(Source, {
96
+ id,
97
+ type: "geojson",
98
+ data,
99
+ children: [
100
+ /* @__PURE__ */ jsxDEV2(Layer, {
101
+ ...fillLayer
102
+ }, undefined, false, undefined, this),
103
+ /* @__PURE__ */ jsxDEV2(Layer, {
104
+ ...outlineLayer
105
+ }, undefined, false, undefined, this)
106
+ ]
107
+ }, undefined, true, undefined, this);
108
+ }
109
+
110
+ // ui/map/MapMarkers.tsx
111
+ import { Marker } from "react-map-gl/maplibre";
112
+ import { jsxDEV as jsxDEV3, Fragment as Fragment2 } from "react/jsx-dev-runtime";
113
+ "use client";
114
+ function MapMarkers({ points }) {
115
+ return /* @__PURE__ */ jsxDEV3(Fragment2, {
116
+ children: points.map((p) => /* @__PURE__ */ jsxDEV3(Marker, {
117
+ longitude: p.lng,
118
+ latitude: p.lat,
119
+ anchor: "bottom",
120
+ children: /* @__PURE__ */ jsxDEV3("button", {
121
+ role: p.onClick ? "button" : undefined,
122
+ tabIndex: p.onClick ? 0 : -1,
123
+ "aria-label": p.ariaLabel || "marker",
124
+ onClick: p.onClick,
125
+ onKeyDown: (e) => {
126
+ if (e.key === "Enter" || e.key === " ") {
127
+ e.preventDefault();
128
+ p.onClick?.();
129
+ }
130
+ },
131
+ style: {
132
+ width: p.size ?? 14,
133
+ height: p.size ?? 14,
134
+ background: p.color ?? "#2563eb",
135
+ border: "2px solid white",
136
+ borderRadius: 9999,
137
+ boxShadow: "0 1px 3px rgba(0,0,0,0.35)",
138
+ cursor: p.onClick ? "pointer" : "default"
139
+ }
140
+ }, undefined, false, undefined, this)
141
+ }, p.id, false, undefined, this))
142
+ }, undefined, false, undefined, this);
143
+ }
144
+
145
+ // ui/visualization/Visualization.support.tsx
146
+ import {
147
+ formatVisualizationValue
148
+ } from "@contractspec/lib.presentation-runtime-core";
149
+ import { cn } from "@contractspec/lib.ui-kit-core/utils";
150
+ import * as echarts from "echarts/core";
151
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
152
+ "use client";
153
+ function MetricVisualization({
154
+ className,
155
+ model
156
+ }) {
157
+ return /* @__PURE__ */ jsxDEV4("div", {
158
+ className: cn("space-y-2", className),
159
+ children: [
160
+ /* @__PURE__ */ jsxDEV4("div", {
161
+ className: "text-muted-foreground text-sm",
162
+ children: model.metric?.label ?? model.title
163
+ }, undefined, false, undefined, this),
164
+ /* @__PURE__ */ jsxDEV4("div", {
165
+ className: "font-semibold text-3xl",
166
+ children: formatVisualizationValue(model.metric?.value, model.metric?.format)
167
+ }, undefined, false, undefined, this),
168
+ model.metric?.comparisonValue != null ? /* @__PURE__ */ jsxDEV4("div", {
169
+ className: "text-muted-foreground text-sm",
170
+ children: [
171
+ "Comparison:",
172
+ " ",
173
+ formatVisualizationValue(model.metric.comparisonValue, model.metric.format)
174
+ ]
175
+ }, undefined, true, undefined, this) : null,
176
+ /* @__PURE__ */ jsxDEV4(TableAlternative, {
177
+ model
178
+ }, undefined, false, undefined, this)
179
+ ]
180
+ }, undefined, true, undefined, this);
181
+ }
182
+ function TableAlternative({
183
+ model
184
+ }) {
185
+ if (!model.table.columns.length || !model.table.rows.length)
186
+ return null;
187
+ return /* @__PURE__ */ jsxDEV4("details", {
188
+ className: "rounded-md border p-3 text-sm",
189
+ children: [
190
+ /* @__PURE__ */ jsxDEV4("summary", {
191
+ className: "cursor-pointer font-medium",
192
+ children: "Data summary"
193
+ }, undefined, false, undefined, this),
194
+ /* @__PURE__ */ jsxDEV4("div", {
195
+ className: "mt-3 overflow-x-auto",
196
+ children: /* @__PURE__ */ jsxDEV4("table", {
197
+ className: "w-full text-left",
198
+ children: [
199
+ /* @__PURE__ */ jsxDEV4("thead", {
200
+ children: /* @__PURE__ */ jsxDEV4("tr", {
201
+ children: model.table.columns.map((column) => /* @__PURE__ */ jsxDEV4("th", {
202
+ className: "px-2 py-1 font-medium",
203
+ children: column.label
204
+ }, column.key, false, undefined, this))
205
+ }, undefined, false, undefined, this)
206
+ }, undefined, false, undefined, this),
207
+ /* @__PURE__ */ jsxDEV4("tbody", {
208
+ children: model.table.rows.slice(0, 8).map((row, index) => /* @__PURE__ */ jsxDEV4("tr", {
209
+ children: model.table.columns.map((column) => /* @__PURE__ */ jsxDEV4("td", {
210
+ className: "px-2 py-1",
211
+ children: String(row[column.key] ?? "\u2014")
212
+ }, column.key, false, undefined, this))
213
+ }, `summary-row-${index}`, false, undefined, this))
214
+ }, undefined, false, undefined, this)
215
+ ]
216
+ }, undefined, true, undefined, this)
217
+ }, undefined, false, undefined, this)
218
+ ]
219
+ }, undefined, true, undefined, this);
220
+ }
221
+ function FallbackVisualization({
222
+ className,
223
+ model,
224
+ reason
225
+ }) {
226
+ return /* @__PURE__ */ jsxDEV4("div", {
227
+ className: cn("space-y-3", className),
228
+ children: [
229
+ /* @__PURE__ */ jsxDEV4("p", {
230
+ className: "text-muted-foreground text-sm",
231
+ children: reason
232
+ }, undefined, false, undefined, this),
233
+ /* @__PURE__ */ jsxDEV4(TableAlternative, {
234
+ model
235
+ }, undefined, false, undefined, this)
236
+ ]
237
+ }, undefined, true, undefined, this);
238
+ }
239
+ function shouldRenderEChart(model) {
240
+ if (model.kind === "metric")
241
+ return false;
242
+ if (model.kind === "geo" && model.geo?.mode === "slippy-map")
243
+ return false;
244
+ if (model.kind === "geo" && model.geo?.geoJson?.type === "url")
245
+ return false;
246
+ return true;
247
+ }
248
+ function registerGeoMap(model) {
249
+ if (model.kind !== "geo" || model.geo?.geoJson?.type !== "inline")
250
+ return;
251
+ registerInlineMap(model.geo.geoJson);
252
+ }
253
+ function registerInlineMap(geoJson) {
254
+ if (geoJson.type !== "inline")
255
+ return;
256
+ echarts.registerMap("contractspec-visualization-geo", geoJson.data);
257
+ }
258
+
259
+ // ui/visually-hidden.tsx
260
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
261
+ var srOnlyStyle = {
262
+ border: 0,
263
+ clip: "rect(0 0 0 0)",
264
+ height: "1px",
265
+ margin: "-1px",
266
+ overflow: "hidden",
267
+ padding: 0,
268
+ position: "absolute",
269
+ width: "1px",
270
+ whiteSpace: "nowrap"
271
+ };
272
+ function VisuallyHidden({
273
+ as = "span",
274
+ style,
275
+ children,
276
+ ref,
277
+ ...props
278
+ }) {
279
+ const Comp = as;
280
+ return /* @__PURE__ */ jsxDEV5(Comp, {
281
+ ref,
282
+ style: { ...srOnlyStyle, ...style },
283
+ ...props,
284
+ children
285
+ }, undefined, false, undefined, this);
286
+ }
287
+ // ui/visualization/Visualization.tsx
288
+ import {
289
+ buildVisualizationEChartsOption
290
+ } from "@contractspec/lib.presentation-runtime-core";
291
+ import { cn as cn2 } from "@contractspec/lib.ui-kit-core/utils";
292
+ import {
293
+ BarChart,
294
+ FunnelChart,
295
+ HeatmapChart,
296
+ LineChart,
297
+ MapChart,
298
+ PieChart,
299
+ ScatterChart
300
+ } from "echarts/charts";
301
+ import {
302
+ AriaComponent,
303
+ GeoComponent,
304
+ GridComponent,
305
+ LegendComponent,
306
+ TitleComponent,
307
+ TooltipComponent,
308
+ VisualMapComponent
309
+ } from "echarts/components";
310
+ import * as echarts2 from "echarts/core";
311
+ import { CanvasRenderer } from "echarts/renderers";
312
+ import * as React2 from "react";
313
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
314
+ "use client";
315
+ echarts2.use([
316
+ AriaComponent,
317
+ TitleComponent,
318
+ TooltipComponent,
319
+ GridComponent,
320
+ LegendComponent,
321
+ VisualMapComponent,
322
+ GeoComponent,
323
+ CanvasRenderer,
324
+ LineChart,
325
+ BarChart,
326
+ PieChart,
327
+ ScatterChart,
328
+ HeatmapChart,
329
+ FunnelChart,
330
+ MapChart
331
+ ]);
332
+ function Visualization({
333
+ model,
334
+ className,
335
+ height = 280,
336
+ onDataPointPress
337
+ }) {
338
+ const chartRef = React2.useRef(null);
339
+ const option = React2.useMemo(() => buildVisualizationEChartsOption(model), [model]);
340
+ React2.useEffect(() => {
341
+ if (!shouldRenderEChart(model) || !chartRef.current)
342
+ return;
343
+ registerGeoMap(model);
344
+ const chart = echarts2.init(chartRef.current, undefined, {
345
+ renderer: "canvas"
346
+ });
347
+ chart.setOption(option);
348
+ if (onDataPointPress) {
349
+ chart.on("click", onDataPointPress);
350
+ }
351
+ const observer = new ResizeObserver(() => chart.resize());
352
+ observer.observe(chartRef.current);
353
+ return () => {
354
+ observer.disconnect();
355
+ if (onDataPointPress) {
356
+ chart.off("click", onDataPointPress);
357
+ }
358
+ chart.dispose();
359
+ };
360
+ }, [model, onDataPointPress, option]);
361
+ if (model.kind === "metric") {
362
+ return /* @__PURE__ */ jsxDEV6(MetricVisualization, {
363
+ className,
364
+ model
365
+ }, undefined, false, undefined, this);
366
+ }
367
+ if (model.kind === "geo" && model.geo?.mode === "slippy-map") {
368
+ return /* @__PURE__ */ jsxDEV6(MapVisualization, {
369
+ className,
370
+ height,
371
+ model
372
+ }, undefined, false, undefined, this);
373
+ }
374
+ if (model.kind === "geo" && model.geo?.geoJson?.type === "url") {
375
+ return /* @__PURE__ */ jsxDEV6(FallbackVisualization, {
376
+ className,
377
+ model,
378
+ reason: "Geo URL sources currently fall back to the summary table."
379
+ }, undefined, false, undefined, this);
380
+ }
381
+ return /* @__PURE__ */ jsxDEV6("div", {
382
+ className: cn2("space-y-3", className),
383
+ children: [
384
+ /* @__PURE__ */ jsxDEV6(VisuallyHidden, {
385
+ children: model.summary
386
+ }, undefined, false, undefined, this),
387
+ /* @__PURE__ */ jsxDEV6("div", {
388
+ ref: chartRef,
389
+ "aria-label": model.summary,
390
+ className: "w-full rounded-md",
391
+ style: { height }
392
+ }, undefined, false, undefined, this),
393
+ /* @__PURE__ */ jsxDEV6(TableAlternative, {
394
+ model
395
+ }, undefined, false, undefined, this)
396
+ ]
397
+ }, undefined, true, undefined, this);
398
+ }
399
+ function MapVisualization({
400
+ className,
401
+ height,
402
+ model
403
+ }) {
404
+ const markers = model.series.flatMap((series) => series.points.filter((point) => point.latitude != null && point.longitude != null).map((point) => ({
405
+ id: point.id,
406
+ lat: point.latitude,
407
+ lng: point.longitude,
408
+ ariaLabel: point.name
409
+ })));
410
+ return /* @__PURE__ */ jsxDEV6("div", {
411
+ className: cn2("space-y-3", className),
412
+ children: [
413
+ /* @__PURE__ */ jsxDEV6("div", {
414
+ style: { height },
415
+ children: /* @__PURE__ */ jsxDEV6(MapBase, {
416
+ children: [
417
+ markers.length > 0 ? /* @__PURE__ */ jsxDEV6(MapMarkers, {
418
+ points: markers
419
+ }, undefined, false, undefined, this) : null,
420
+ model.geo?.geoJson?.type === "inline" ? /* @__PURE__ */ jsxDEV6(MapGeoJsonOverlay, {
421
+ data: model.geo.geoJson.data
422
+ }, undefined, false, undefined, this) : null
423
+ ]
424
+ }, undefined, true, undefined, this)
425
+ }, undefined, false, undefined, this),
426
+ /* @__PURE__ */ jsxDEV6(TableAlternative, {
427
+ model
428
+ }, undefined, false, undefined, this)
429
+ ]
430
+ }, undefined, true, undefined, this);
431
+ }
432
+ export {
433
+ Visualization
434
+ };
@@ -0,0 +1,15 @@
1
+ import { type ContractVisualizationRenderModel } from '@contractspec/lib.presentation-runtime-core';
2
+ export declare function MetricVisualization({ className, model, }: {
3
+ className?: string;
4
+ model: ContractVisualizationRenderModel;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ export declare function TableAlternative({ model, }: {
7
+ model: ContractVisualizationRenderModel;
8
+ }): import("react/jsx-runtime").JSX.Element | null;
9
+ export declare function FallbackVisualization({ className, model, reason, }: {
10
+ className?: string;
11
+ model: ContractVisualizationRenderModel;
12
+ reason: string;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ export declare function shouldRenderEChart(model: ContractVisualizationRenderModel): boolean;
15
+ export declare function registerGeoMap(model: ContractVisualizationRenderModel): void;
@@ -0,0 +1,123 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // ui/visualization/Visualization.support.tsx
5
+ import {
6
+ formatVisualizationValue
7
+ } from "@contractspec/lib.presentation-runtime-core";
8
+ import { cn } from "@contractspec/lib.ui-kit-core/utils";
9
+ import * as echarts from "echarts/core";
10
+ import { jsxDEV } from "react/jsx-dev-runtime";
11
+ "use client";
12
+ function MetricVisualization({
13
+ className,
14
+ model
15
+ }) {
16
+ return /* @__PURE__ */ jsxDEV("div", {
17
+ className: cn("space-y-2", className),
18
+ children: [
19
+ /* @__PURE__ */ jsxDEV("div", {
20
+ className: "text-muted-foreground text-sm",
21
+ children: model.metric?.label ?? model.title
22
+ }, undefined, false, undefined, this),
23
+ /* @__PURE__ */ jsxDEV("div", {
24
+ className: "font-semibold text-3xl",
25
+ children: formatVisualizationValue(model.metric?.value, model.metric?.format)
26
+ }, undefined, false, undefined, this),
27
+ model.metric?.comparisonValue != null ? /* @__PURE__ */ jsxDEV("div", {
28
+ className: "text-muted-foreground text-sm",
29
+ children: [
30
+ "Comparison:",
31
+ " ",
32
+ formatVisualizationValue(model.metric.comparisonValue, model.metric.format)
33
+ ]
34
+ }, undefined, true, undefined, this) : null,
35
+ /* @__PURE__ */ jsxDEV(TableAlternative, {
36
+ model
37
+ }, undefined, false, undefined, this)
38
+ ]
39
+ }, undefined, true, undefined, this);
40
+ }
41
+ function TableAlternative({
42
+ model
43
+ }) {
44
+ if (!model.table.columns.length || !model.table.rows.length)
45
+ return null;
46
+ return /* @__PURE__ */ jsxDEV("details", {
47
+ className: "rounded-md border p-3 text-sm",
48
+ children: [
49
+ /* @__PURE__ */ jsxDEV("summary", {
50
+ className: "cursor-pointer font-medium",
51
+ children: "Data summary"
52
+ }, undefined, false, undefined, this),
53
+ /* @__PURE__ */ jsxDEV("div", {
54
+ className: "mt-3 overflow-x-auto",
55
+ children: /* @__PURE__ */ jsxDEV("table", {
56
+ className: "w-full text-left",
57
+ children: [
58
+ /* @__PURE__ */ jsxDEV("thead", {
59
+ children: /* @__PURE__ */ jsxDEV("tr", {
60
+ children: model.table.columns.map((column) => /* @__PURE__ */ jsxDEV("th", {
61
+ className: "px-2 py-1 font-medium",
62
+ children: column.label
63
+ }, column.key, false, undefined, this))
64
+ }, undefined, false, undefined, this)
65
+ }, undefined, false, undefined, this),
66
+ /* @__PURE__ */ jsxDEV("tbody", {
67
+ children: model.table.rows.slice(0, 8).map((row, index) => /* @__PURE__ */ jsxDEV("tr", {
68
+ children: model.table.columns.map((column) => /* @__PURE__ */ jsxDEV("td", {
69
+ className: "px-2 py-1",
70
+ children: String(row[column.key] ?? "\u2014")
71
+ }, column.key, false, undefined, this))
72
+ }, `summary-row-${index}`, false, undefined, this))
73
+ }, undefined, false, undefined, this)
74
+ ]
75
+ }, undefined, true, undefined, this)
76
+ }, undefined, false, undefined, this)
77
+ ]
78
+ }, undefined, true, undefined, this);
79
+ }
80
+ function FallbackVisualization({
81
+ className,
82
+ model,
83
+ reason
84
+ }) {
85
+ return /* @__PURE__ */ jsxDEV("div", {
86
+ className: cn("space-y-3", className),
87
+ children: [
88
+ /* @__PURE__ */ jsxDEV("p", {
89
+ className: "text-muted-foreground text-sm",
90
+ children: reason
91
+ }, undefined, false, undefined, this),
92
+ /* @__PURE__ */ jsxDEV(TableAlternative, {
93
+ model
94
+ }, undefined, false, undefined, this)
95
+ ]
96
+ }, undefined, true, undefined, this);
97
+ }
98
+ function shouldRenderEChart(model) {
99
+ if (model.kind === "metric")
100
+ return false;
101
+ if (model.kind === "geo" && model.geo?.mode === "slippy-map")
102
+ return false;
103
+ if (model.kind === "geo" && model.geo?.geoJson?.type === "url")
104
+ return false;
105
+ return true;
106
+ }
107
+ function registerGeoMap(model) {
108
+ if (model.kind !== "geo" || model.geo?.geoJson?.type !== "inline")
109
+ return;
110
+ registerInlineMap(model.geo.geoJson);
111
+ }
112
+ function registerInlineMap(geoJson) {
113
+ if (geoJson.type !== "inline")
114
+ return;
115
+ echarts.registerMap("contractspec-visualization-geo", geoJson.data);
116
+ }
117
+ export {
118
+ shouldRenderEChart,
119
+ registerGeoMap,
120
+ TableAlternative,
121
+ MetricVisualization,
122
+ FallbackVisualization
123
+ };
@@ -0,0 +1 @@
1
+ export { Visualization, type VisualizationInteractionHandler, type VisualizationProps, } from './Visualization';
@@ -0,0 +1,5 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+ export {
4
+ Visualization
5
+ };