@a4ui/core 0.32.0 → 0.34.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.
- package/dist/charts/BarList.d.ts +33 -0
- package/dist/charts/CategoryBar.d.ts +23 -0
- package/dist/charts/StatusTracker.d.ts +27 -0
- package/dist/charts/index.d.ts +3 -0
- package/dist/charts.js +446 -316
- package/dist/elements.css +278 -0
- package/dist/full.css +278 -0
- package/dist/index.d.ts +25 -1
- package/dist/index.js +6423 -4195
- package/dist/ui/AudioWaveform.d.ts +22 -0
- package/dist/ui/Callout.d.ts +27 -0
- package/dist/ui/Confetti.d.ts +46 -0
- package/dist/ui/CouponField.d.ts +33 -0
- package/dist/ui/CursorTrail.d.ts +25 -0
- package/dist/ui/DiffViewer.d.ts +33 -0
- package/dist/ui/FollowingPointer.d.ts +24 -0
- package/dist/ui/GanttChart.d.ts +37 -0
- package/dist/ui/Globe.d.ts +44 -0
- package/dist/ui/Kanban.d.ts +49 -0
- package/dist/ui/Lamp.d.ts +22 -0
- package/dist/ui/Lightbox.d.ts +41 -0
- package/dist/ui/ModelPicker.d.ts +38 -0
- package/dist/ui/OnboardingChecklist.d.ts +51 -0
- package/dist/ui/PivotTable.d.ts +37 -0
- package/dist/ui/ReasoningTrace.d.ts +28 -0
- package/dist/ui/SheetSnap.d.ts +28 -0
- package/dist/ui/Snippet.d.ts +19 -0
- package/dist/ui/SuggestionChips.d.ts +25 -0
- package/dist/ui/ToolCallTimeline.d.ts +34 -0
- package/dist/ui/TreeTable.d.ts +52 -0
- package/dist/ui/UsageMeter.d.ts +26 -0
- package/dist/ui/VideoPlayerShell.d.ts +19 -0
- package/dist/ui/WorldMap.d.ts +36 -0
- package/package.json +1 -1
- package/src/charts/BarList.tsx +83 -0
- package/src/charts/CategoryBar.tsx +95 -0
- package/src/charts/StatusTracker.tsx +81 -0
- package/src/charts/index.ts +3 -0
- package/src/index.ts +48 -1
- package/src/ui/AudioWaveform.tsx +190 -0
- package/src/ui/Callout.tsx +66 -0
- package/src/ui/Confetti.tsx +131 -0
- package/src/ui/CouponField.tsx +120 -0
- package/src/ui/CursorTrail.tsx +88 -0
- package/src/ui/DiffViewer.tsx +166 -0
- package/src/ui/FollowingPointer.tsx +112 -0
- package/src/ui/GanttChart.tsx +283 -0
- package/src/ui/Globe.tsx +317 -0
- package/src/ui/Kanban.tsx +250 -0
- package/src/ui/Lamp.tsx +88 -0
- package/src/ui/Lightbox.tsx +261 -0
- package/src/ui/ModelPicker.tsx +119 -0
- package/src/ui/OnboardingChecklist.tsx +163 -0
- package/src/ui/PivotTable.tsx +0 -0
- package/src/ui/ReasoningTrace.tsx +83 -0
- package/src/ui/SheetSnap.tsx +264 -0
- package/src/ui/Snippet.tsx +64 -0
- package/src/ui/SuggestionChips.tsx +65 -0
- package/src/ui/ToolCallTimeline.tsx +137 -0
- package/src/ui/TreeTable.tsx +172 -0
- package/src/ui/UsageMeter.tsx +71 -0
- package/src/ui/VideoPlayerShell.tsx +282 -0
- package/src/ui/WorldMap.tsx +191 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// WorldMap — a lightweight, self-contained SVG "map": a dotted-grid backdrop
|
|
2
|
+
// (no coastlines, no geojson/asset) with connection arcs projected from
|
|
3
|
+
// lat/lng via simple equirectangular mapping. Each arc bulges upward and
|
|
4
|
+
// carries a traveling primary→accent gradient segment, reusing
|
|
5
|
+
// AnimatedBeam's "moving gradient stops along a quadratic curve" technique.
|
|
6
|
+
// Arcs render static (no travel) under reduced motion.
|
|
7
|
+
import { createUniqueId, For, onCleanup, type JSX } from 'solid-js'
|
|
8
|
+
|
|
9
|
+
import { cn } from '../lib/cn'
|
|
10
|
+
import { animate, motionReduced } from '../lib/motion'
|
|
11
|
+
|
|
12
|
+
export interface WorldMapPoint {
|
|
13
|
+
lat: number
|
|
14
|
+
lng: number
|
|
15
|
+
label?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface WorldMapConnection {
|
|
19
|
+
from: WorldMapPoint
|
|
20
|
+
to: WorldMapPoint
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface WorldMapProps {
|
|
24
|
+
/** Arcs to draw between projected points. @default [] */
|
|
25
|
+
connections?: WorldMapConnection[]
|
|
26
|
+
class?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const WIDTH = 800
|
|
30
|
+
const HEIGHT = 400
|
|
31
|
+
/** Px spacing between backdrop grid dots. */
|
|
32
|
+
const GRID_GAP = 16
|
|
33
|
+
|
|
34
|
+
interface Point {
|
|
35
|
+
x: number
|
|
36
|
+
y: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Equirectangular projection: lat/lng -> SVG coordinates in the WIDTH x HEIGHT viewBox. */
|
|
40
|
+
function project(point: WorldMapPoint): Point {
|
|
41
|
+
return {
|
|
42
|
+
x: ((point.lng + 180) / 360) * WIDTH,
|
|
43
|
+
y: ((90 - point.lat) / 180) * HEIGHT,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Point at parameter `t` (0..1) along a quadratic Bezier curve. */
|
|
48
|
+
function pointAt(start: Point, control: Point, end: Point, t: number): Point {
|
|
49
|
+
const it = 1 - t
|
|
50
|
+
return {
|
|
51
|
+
x: it * it * start.x + 2 * it * t * control.x + t * t * end.x,
|
|
52
|
+
y: it * it * start.y + 2 * it * t * control.y + t * t * end.y,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Centers of an evenly spaced dot grid covering the WIDTH x HEIGHT viewBox. */
|
|
57
|
+
function gridDots(): Point[] {
|
|
58
|
+
const dots: Point[] = []
|
|
59
|
+
for (let y = GRID_GAP / 2; y < HEIGHT; y += GRID_GAP) {
|
|
60
|
+
for (let x = GRID_GAP / 2; x < WIDTH; x += GRID_GAP) {
|
|
61
|
+
dots.push({ x, y })
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return dots
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface ConnectionArcProps {
|
|
68
|
+
connection: WorldMapConnection
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** One arc: a faint static base stroke plus (unless reduced motion) a traveling gradient segment. */
|
|
72
|
+
function ConnectionArc(props: ConnectionArcProps): JSX.Element {
|
|
73
|
+
const gradientId = `world-map-beam-${createUniqueId()}`
|
|
74
|
+
const start = project(props.connection.from)
|
|
75
|
+
const end = project(props.connection.to)
|
|
76
|
+
const mx = (start.x + end.x) / 2
|
|
77
|
+
const my = (start.y + end.y) / 2
|
|
78
|
+
// Bulge upward (smaller y) regardless of endpoint order.
|
|
79
|
+
const bulge = Math.max(20, Math.hypot(end.x - start.x, end.y - start.y) * 0.25)
|
|
80
|
+
const control = { x: mx, y: my - bulge }
|
|
81
|
+
const d = `M ${start.x} ${start.y} Q ${control.x} ${control.y} ${end.x} ${end.y}`
|
|
82
|
+
const reduced = motionReduced()
|
|
83
|
+
|
|
84
|
+
let gradientEl: SVGLinearGradientElement | undefined
|
|
85
|
+
|
|
86
|
+
if (!reduced) {
|
|
87
|
+
const segment = 0.2
|
|
88
|
+
const controls = animate(0, 1, {
|
|
89
|
+
duration: 3,
|
|
90
|
+
repeat: Infinity,
|
|
91
|
+
ease: 'linear',
|
|
92
|
+
onUpdate: (p: number) => {
|
|
93
|
+
const from = pointAt(start, control, end, Math.max(0, p - segment))
|
|
94
|
+
const to = pointAt(start, control, end, p)
|
|
95
|
+
gradientEl?.setAttribute('x1', String(from.x))
|
|
96
|
+
gradientEl?.setAttribute('y1', String(from.y))
|
|
97
|
+
gradientEl?.setAttribute('x2', String(to.x))
|
|
98
|
+
gradientEl?.setAttribute('y2', String(to.y))
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
onCleanup(() => controls.stop())
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<>
|
|
106
|
+
<path d={d} stroke="hsl(var(--muted-foreground))" stroke-width="1" stroke-opacity="0.3" fill="none" />
|
|
107
|
+
{!reduced && (
|
|
108
|
+
<>
|
|
109
|
+
<defs>
|
|
110
|
+
<linearGradient
|
|
111
|
+
ref={(el) => {
|
|
112
|
+
gradientEl = el
|
|
113
|
+
}}
|
|
114
|
+
id={gradientId}
|
|
115
|
+
gradientUnits="userSpaceOnUse"
|
|
116
|
+
>
|
|
117
|
+
<stop offset="0%" stop-color="hsl(var(--primary))" stop-opacity="0" />
|
|
118
|
+
<stop offset="50%" stop-color="hsl(var(--primary))" />
|
|
119
|
+
<stop offset="50%" stop-color="hsl(var(--accent))" />
|
|
120
|
+
<stop offset="100%" stop-color="hsl(var(--accent))" stop-opacity="0" />
|
|
121
|
+
</linearGradient>
|
|
122
|
+
</defs>
|
|
123
|
+
<path d={d} stroke={`url(#${gradientId})`} stroke-width="1.5" stroke-linecap="round" fill="none" />
|
|
124
|
+
</>
|
|
125
|
+
)}
|
|
126
|
+
<circle
|
|
127
|
+
cx={start.x}
|
|
128
|
+
cy={start.y}
|
|
129
|
+
r="2.5"
|
|
130
|
+
fill="hsl(var(--primary))"
|
|
131
|
+
class={reduced ? undefined : 'animate-pulse'}
|
|
132
|
+
/>
|
|
133
|
+
<circle
|
|
134
|
+
cx={end.x}
|
|
135
|
+
cy={end.y}
|
|
136
|
+
r="2.5"
|
|
137
|
+
fill="hsl(var(--primary))"
|
|
138
|
+
class={reduced ? undefined : 'animate-pulse'}
|
|
139
|
+
/>
|
|
140
|
+
</>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* A decorative, dependency-free SVG "world map": an evenly spaced dotted-grid
|
|
146
|
+
* backdrop (a stylized map, not accurate coastlines) with connection arcs
|
|
147
|
+
* projected from lat/lng via equirectangular mapping. Each arc bulges upward
|
|
148
|
+
* and carries a traveling primary→accent gradient segment (reusing
|
|
149
|
+
* {@link AnimatedBeam}'s technique); arcs render static under reduced motion.
|
|
150
|
+
* Responsive — scales to its container via the 2:1 `viewBox`.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```tsx
|
|
154
|
+
* <WorldMap
|
|
155
|
+
* class="w-full"
|
|
156
|
+
* connections={[
|
|
157
|
+
* { from: { lat: 40.7128, lng: -74.006, label: 'New York' }, to: { lat: 51.5074, lng: -0.1278, label: 'London' } },
|
|
158
|
+
* { from: { lat: 51.5074, lng: -0.1278 }, to: { lat: 35.6762, lng: 139.6503, label: 'Tokyo' } },
|
|
159
|
+
* { from: { lat: 40.7128, lng: -74.006 }, to: { lat: -23.5505, lng: -46.6333, label: 'São Paulo' } },
|
|
160
|
+
* ]}
|
|
161
|
+
* />
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function WorldMap(props: WorldMapProps): JSX.Element {
|
|
165
|
+
const connections = () => props.connections ?? []
|
|
166
|
+
const label = () =>
|
|
167
|
+
connections()
|
|
168
|
+
.map(
|
|
169
|
+
(c) =>
|
|
170
|
+
`${c.from.label ?? `${c.from.lat},${c.from.lng}`} to ${c.to.label ?? `${c.to.lat},${c.to.lng}`}`,
|
|
171
|
+
)
|
|
172
|
+
.join('; ')
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<svg
|
|
176
|
+
role={connections().length > 0 ? 'img' : undefined}
|
|
177
|
+
aria-label={connections().length > 0 ? `World map with connections: ${label()}` : undefined}
|
|
178
|
+
aria-hidden={connections().length > 0 ? undefined : 'true'}
|
|
179
|
+
class={cn('w-full', props.class)}
|
|
180
|
+
viewBox={`0 0 ${WIDTH} ${HEIGHT}`}
|
|
181
|
+
fill="none"
|
|
182
|
+
>
|
|
183
|
+
<For each={gridDots()}>
|
|
184
|
+
{(dot) => (
|
|
185
|
+
<circle cx={dot.x} cy={dot.y} r="0.8" fill="hsl(var(--muted-foreground))" fill-opacity="0.25" />
|
|
186
|
+
)}
|
|
187
|
+
</For>
|
|
188
|
+
<For each={connections()}>{(connection) => <ConnectionArc connection={connection} />}</For>
|
|
189
|
+
</svg>
|
|
190
|
+
)
|
|
191
|
+
}
|