@gram-ai/elements 1.25.2 → 1.26.1
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/components/Chat/stories/Charts.stories.d.ts +37 -0
- package/dist/components/Chat/stories/GenerativeUI.stories.d.ts +17 -0
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/buttonVariants.d.ts +1 -1
- package/dist/components/ui/charts.stories.d.ts +43 -0
- package/dist/components/ui/generative-ui.stories.d.ts +53 -0
- package/dist/components/ui/tool-ui.d.ts +16 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +6 -6
- package/dist/index-BpJstUh1.cjs +280 -0
- package/dist/index-BpJstUh1.cjs.map +1 -0
- package/dist/index-CUitXazZ.js +30426 -0
- package/dist/index-CUitXazZ.js.map +1 -0
- package/dist/index-DdrZQXwQ.cjs +147 -0
- package/dist/index-DdrZQXwQ.cjs.map +1 -0
- package/dist/index-DfqYP0CD.js +37062 -0
- package/dist/index-DfqYP0CD.js.map +1 -0
- package/dist/plugins/chart/catalog.d.ts +123 -0
- package/dist/plugins/chart/index.d.ts +1 -1
- package/dist/plugins/chart/ui/area-chart.d.ts +16 -0
- package/dist/plugins/chart/ui/bar-chart.d.ts +16 -0
- package/dist/plugins/chart/ui/donut-chart.d.ts +17 -0
- package/dist/plugins/chart/ui/index.d.ts +7 -0
- package/dist/plugins/chart/ui/line-chart.d.ts +17 -0
- package/dist/plugins/chart/ui/pie-chart.d.ts +15 -0
- package/dist/plugins/chart/ui/radar-chart.d.ts +14 -0
- package/dist/plugins/chart/ui/scatter-chart.d.ts +18 -0
- package/dist/plugins/components/MacOSWindowFrame.d.ts +13 -0
- package/dist/plugins/components/PluginLoadingState.d.ts +1 -1
- package/dist/plugins/generative-ui/catalog.d.ts +293 -0
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +18 -0
- package/dist/plugins/generative-ui/ui/accordion.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/action-button.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/alert.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/avatar-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/avatar.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/badge.d.ts +12 -0
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +15 -0
- package/dist/plugins/generative-ui/ui/button.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/card.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/checkbox-wrapper.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/data-table.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/dialog.d.ts +17 -0
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +25 -0
- package/dist/plugins/generative-ui/ui/grid.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/index.d.ts +40 -0
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/input.d.ts +3 -0
- package/dist/plugins/generative-ui/ui/label.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/list.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/metric.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/pagination.d.ts +13 -0
- package/dist/plugins/generative-ui/ui/popover.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/progress.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +5 -0
- package/dist/plugins/generative-ui/ui/select-wrapper.d.ts +13 -0
- package/dist/plugins/generative-ui/ui/select.d.ts +15 -0
- package/dist/plugins/generative-ui/ui/separator.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/skeleton-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +2 -0
- package/dist/plugins/generative-ui/ui/stack.d.ts +8 -0
- package/dist/plugins/generative-ui/ui/switch.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/table.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +21 -0
- package/dist/plugins/generative-ui/ui/tabs.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/text.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/textarea.d.ts +3 -0
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +7 -0
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-BaG0scxd.js → profiler-WoFj2UH8.js} +2 -2
- package/dist/{profiler-BaG0scxd.js.map → profiler-WoFj2UH8.js.map} +1 -1
- package/dist/{profiler-CuqENACf.cjs → profiler-ZLr2-8s7.cjs} +2 -2
- package/dist/{profiler-CuqENACf.cjs.map → profiler-ZLr2-8s7.cjs.map} +1 -1
- package/dist/{startRecording-BiLmoqZa.cjs → startRecording-BGnWDInp.cjs} +2 -2
- package/dist/{startRecording-BiLmoqZa.cjs.map → startRecording-BGnWDInp.cjs.map} +1 -1
- package/dist/{startRecording-86bHmd-l.js → startRecording-DzQo16WK.js} +2 -2
- package/dist/{startRecording-86bHmd-l.js.map → startRecording-DzQo16WK.js.map} +1 -1
- package/package.json +4 -1
- package/src/components/Chat/stories/Charts.stories.tsx +260 -0
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +6 -6
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +113 -0
- package/src/components/Replay.stories.tsx +1 -1
- package/src/components/Replay.tsx +18 -13
- package/src/components/ui/charts.stories.tsx +246 -0
- package/src/components/ui/generative-ui.stories.tsx +557 -0
- package/src/components/ui/generative-ui.tsx +60 -360
- package/src/components/ui/tool-ui.stories.tsx +6 -3
- package/src/components/ui/tool-ui.tsx +31 -2
- package/src/hooks/useAuth.ts +17 -1
- package/src/hooks/useFollowOnSuggestions.ts +6 -1
- package/src/plugins/chart/catalog.ts +141 -0
- package/src/plugins/chart/component.tsx +79 -125
- package/src/plugins/chart/index.ts +141 -89
- package/src/plugins/chart/ui/area-chart.tsx +133 -0
- package/src/plugins/chart/ui/bar-chart.tsx +137 -0
- package/src/plugins/chart/ui/donut-chart.tsx +167 -0
- package/src/plugins/chart/ui/index.ts +7 -0
- package/src/plugins/chart/ui/line-chart.tsx +135 -0
- package/src/plugins/chart/ui/pie-chart.tsx +148 -0
- package/src/plugins/chart/ui/radar-chart.tsx +105 -0
- package/src/plugins/chart/ui/scatter-chart.tsx +132 -0
- package/src/plugins/components/MacOSWindowFrame.tsx +55 -0
- package/src/plugins/components/PluginLoadingState.tsx +9 -13
- package/src/plugins/generative-ui/catalog.ts +277 -0
- package/src/plugins/generative-ui/component.tsx +112 -21
- package/src/plugins/generative-ui/index.ts +20 -141
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +57 -0
- package/src/plugins/generative-ui/ui/accordion.tsx +66 -0
- package/src/plugins/generative-ui/ui/action-button.tsx +68 -0
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +26 -0
- package/src/plugins/generative-ui/ui/alert.tsx +66 -0
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +22 -0
- package/src/plugins/generative-ui/ui/avatar.tsx +109 -0
- package/src/plugins/generative-ui/ui/badge.tsx +65 -0
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +32 -0
- package/src/plugins/generative-ui/ui/button.tsx +65 -0
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +36 -0
- package/src/plugins/generative-ui/ui/card.tsx +92 -0
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +39 -0
- package/src/plugins/generative-ui/ui/checkbox.tsx +32 -0
- package/src/plugins/generative-ui/ui/data-table.tsx +53 -0
- package/src/plugins/generative-ui/ui/dialog.tsx +158 -0
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +257 -0
- package/src/plugins/generative-ui/ui/grid.tsx +29 -0
- package/src/plugins/generative-ui/ui/index.ts +43 -0
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +38 -0
- package/src/plugins/generative-ui/ui/input.tsx +21 -0
- package/src/plugins/generative-ui/ui/label.tsx +24 -0
- package/src/plugins/generative-ui/ui/list.tsx +34 -0
- package/src/plugins/generative-ui/ui/metric.tsx +53 -0
- package/src/plugins/generative-ui/ui/pagination.tsx +127 -0
- package/src/plugins/generative-ui/ui/popover.tsx +89 -0
- package/src/plugins/generative-ui/ui/progress.tsx +57 -0
- package/src/plugins/generative-ui/ui/radio-group.tsx +45 -0
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +41 -0
- package/src/plugins/generative-ui/ui/select.tsx +190 -0
- package/src/plugins/generative-ui/ui/separator.tsx +28 -0
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +30 -0
- package/src/plugins/generative-ui/ui/skeleton.tsx +13 -0
- package/src/plugins/generative-ui/ui/stack.tsx +54 -0
- package/src/plugins/generative-ui/ui/switch.tsx +35 -0
- package/src/plugins/generative-ui/ui/table.tsx +116 -0
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +51 -0
- package/src/plugins/generative-ui/ui/tabs.tsx +92 -0
- package/src/plugins/generative-ui/ui/text.tsx +33 -0
- package/src/plugins/generative-ui/ui/textarea.tsx +18 -0
- package/src/plugins/generative-ui/ui/tooltip.tsx +57 -0
- package/dist/components/Chat/stories/Plugins.stories.d.ts +0 -12
- package/dist/index-B8nSCdu4.cjs +0 -251
- package/dist/index-B8nSCdu4.cjs.map +0 -1
- package/dist/index-CAtaLV1E.cjs +0 -187
- package/dist/index-CAtaLV1E.cjs.map +0 -1
- package/dist/index-CJrwma08.js +0 -27232
- package/dist/index-CJrwma08.js.map +0 -1
- package/dist/index-DLWQ91ow.js +0 -40049
- package/dist/index-DLWQ91ow.js.map +0 -1
- package/src/components/Chat/stories/Plugins.stories.tsx +0 -158
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils'
|
|
4
|
+
import { FC } from 'react'
|
|
5
|
+
import {
|
|
6
|
+
PieChart as RechartsPieChart,
|
|
7
|
+
Pie,
|
|
8
|
+
Cell,
|
|
9
|
+
Tooltip,
|
|
10
|
+
Legend,
|
|
11
|
+
ResponsiveContainer,
|
|
12
|
+
TooltipProps,
|
|
13
|
+
} from 'recharts'
|
|
14
|
+
|
|
15
|
+
const CustomTooltip = ({ active, payload }: TooltipProps<number, string>) => {
|
|
16
|
+
if (!active || !payload || payload.length === 0) return null
|
|
17
|
+
const entry = payload[0]
|
|
18
|
+
return (
|
|
19
|
+
<div className="bg-background text-foreground border-border rounded-md border px-2 py-1 text-xs shadow-sm">
|
|
20
|
+
<span className="font-medium">
|
|
21
|
+
{typeof entry?.value === 'number'
|
|
22
|
+
? entry.value.toLocaleString()
|
|
23
|
+
: entry?.value}
|
|
24
|
+
</span>
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const COLORS = [
|
|
30
|
+
'var(--chart-1)',
|
|
31
|
+
'var(--chart-2)',
|
|
32
|
+
'var(--chart-3)',
|
|
33
|
+
'var(--chart-4)',
|
|
34
|
+
'var(--chart-5)',
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
interface DataPoint {
|
|
38
|
+
label: string
|
|
39
|
+
value: number
|
|
40
|
+
color?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface PieChartProps {
|
|
44
|
+
title?: string
|
|
45
|
+
data: DataPoint[]
|
|
46
|
+
showLabels?: boolean
|
|
47
|
+
showLegend?: boolean
|
|
48
|
+
className?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const PieChart: FC<PieChartProps> = ({
|
|
52
|
+
title,
|
|
53
|
+
data,
|
|
54
|
+
showLabels = true,
|
|
55
|
+
showLegend = true,
|
|
56
|
+
className,
|
|
57
|
+
}) => {
|
|
58
|
+
// Transform data to use 'name' for Recharts
|
|
59
|
+
const chartData = data.map((d) => ({
|
|
60
|
+
name: d.label,
|
|
61
|
+
value: d.value,
|
|
62
|
+
color: d.color,
|
|
63
|
+
}))
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div className={cn('flex flex-col gap-2', className)}>
|
|
67
|
+
{title && (
|
|
68
|
+
<h3 className="text-foreground text-sm font-medium">{title}</h3>
|
|
69
|
+
)}
|
|
70
|
+
<div className="h-[320px] w-full">
|
|
71
|
+
<ResponsiveContainer width="100%" height="100%">
|
|
72
|
+
<RechartsPieChart
|
|
73
|
+
margin={{ top: 20, right: 20, bottom: 20, left: 20 }}
|
|
74
|
+
>
|
|
75
|
+
<Pie
|
|
76
|
+
data={chartData}
|
|
77
|
+
cx="50%"
|
|
78
|
+
cy="45%"
|
|
79
|
+
innerRadius={0}
|
|
80
|
+
outerRadius={80}
|
|
81
|
+
paddingAngle={2}
|
|
82
|
+
dataKey="value"
|
|
83
|
+
label={
|
|
84
|
+
showLabels
|
|
85
|
+
? ({
|
|
86
|
+
name,
|
|
87
|
+
percent,
|
|
88
|
+
cx,
|
|
89
|
+
cy,
|
|
90
|
+
midAngle,
|
|
91
|
+
outerRadius,
|
|
92
|
+
}: {
|
|
93
|
+
name?: string
|
|
94
|
+
percent?: number
|
|
95
|
+
cx?: number
|
|
96
|
+
cy?: number
|
|
97
|
+
midAngle?: number
|
|
98
|
+
outerRadius?: number
|
|
99
|
+
}) => {
|
|
100
|
+
const RADIAN = Math.PI / 180
|
|
101
|
+
const radius = (outerRadius ?? 80) + 25
|
|
102
|
+
const x =
|
|
103
|
+
(cx ?? 0) +
|
|
104
|
+
radius * Math.cos(-((midAngle ?? 0) * RADIAN))
|
|
105
|
+
const y =
|
|
106
|
+
(cy ?? 0) +
|
|
107
|
+
radius * Math.sin(-((midAngle ?? 0) * RADIAN))
|
|
108
|
+
return (
|
|
109
|
+
<text
|
|
110
|
+
x={x}
|
|
111
|
+
y={y}
|
|
112
|
+
fill="var(--foreground)"
|
|
113
|
+
textAnchor={x > (cx ?? 0) ? 'start' : 'end'}
|
|
114
|
+
dominantBaseline="central"
|
|
115
|
+
fontSize={12}
|
|
116
|
+
>
|
|
117
|
+
{`${name ?? ''} (${((percent ?? 0) * 100).toFixed(0)}%)`}
|
|
118
|
+
</text>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
: undefined
|
|
122
|
+
}
|
|
123
|
+
labelLine={showLabels}
|
|
124
|
+
isAnimationActive={false}
|
|
125
|
+
>
|
|
126
|
+
{chartData.map((entry, index) => (
|
|
127
|
+
<Cell
|
|
128
|
+
key={`cell-${index}`}
|
|
129
|
+
fill={entry.color || COLORS[index % COLORS.length]}
|
|
130
|
+
/>
|
|
131
|
+
))}
|
|
132
|
+
</Pie>
|
|
133
|
+
<Tooltip content={<CustomTooltip />} />
|
|
134
|
+
{showLegend && (
|
|
135
|
+
<Legend
|
|
136
|
+
verticalAlign="bottom"
|
|
137
|
+
wrapperStyle={{ color: 'var(--foreground)', paddingTop: 20 }}
|
|
138
|
+
formatter={(value) => (
|
|
139
|
+
<span style={{ color: 'var(--foreground)' }}>{value}</span>
|
|
140
|
+
)}
|
|
141
|
+
/>
|
|
142
|
+
)}
|
|
143
|
+
</RechartsPieChart>
|
|
144
|
+
</ResponsiveContainer>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils'
|
|
4
|
+
import { FC } from 'react'
|
|
5
|
+
import {
|
|
6
|
+
RadarChart as RechartsRadarChart,
|
|
7
|
+
Radar,
|
|
8
|
+
PolarGrid,
|
|
9
|
+
PolarAngleAxis,
|
|
10
|
+
PolarRadiusAxis,
|
|
11
|
+
Tooltip,
|
|
12
|
+
Legend,
|
|
13
|
+
ResponsiveContainer,
|
|
14
|
+
TooltipProps,
|
|
15
|
+
} from 'recharts'
|
|
16
|
+
|
|
17
|
+
const CustomTooltip = ({ active, payload }: TooltipProps<number, string>) => {
|
|
18
|
+
if (!active || !payload || payload.length === 0) return null
|
|
19
|
+
const entry = payload[0]
|
|
20
|
+
return (
|
|
21
|
+
<div className="bg-background text-foreground border-border rounded-md border px-2 py-1 text-xs shadow-sm">
|
|
22
|
+
<span className="font-medium">
|
|
23
|
+
{typeof entry?.value === 'number'
|
|
24
|
+
? entry.value.toLocaleString()
|
|
25
|
+
: entry?.value}
|
|
26
|
+
</span>
|
|
27
|
+
</div>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const COLORS = [
|
|
32
|
+
'var(--chart-1)',
|
|
33
|
+
'var(--chart-2)',
|
|
34
|
+
'var(--chart-3)',
|
|
35
|
+
'var(--chart-4)',
|
|
36
|
+
'var(--chart-5)',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
interface DataPoint {
|
|
40
|
+
label: string
|
|
41
|
+
value: number
|
|
42
|
+
color?: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface RadarChartProps {
|
|
46
|
+
title?: string
|
|
47
|
+
data: DataPoint[]
|
|
48
|
+
showLegend?: boolean
|
|
49
|
+
className?: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const RadarChart: FC<RadarChartProps> = ({
|
|
53
|
+
title,
|
|
54
|
+
data,
|
|
55
|
+
showLegend = false,
|
|
56
|
+
className,
|
|
57
|
+
}) => {
|
|
58
|
+
// Transform data for Recharts (uses 'subject' for labels)
|
|
59
|
+
const chartData = data.map((d) => ({ subject: d.label, value: d.value }))
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className={cn('flex flex-col gap-2', className)}>
|
|
63
|
+
{title && (
|
|
64
|
+
<h3 className="text-foreground text-sm font-medium">{title}</h3>
|
|
65
|
+
)}
|
|
66
|
+
<div className="h-[250px] w-full">
|
|
67
|
+
<ResponsiveContainer width="100%" height="100%">
|
|
68
|
+
<RechartsRadarChart
|
|
69
|
+
data={chartData}
|
|
70
|
+
cx="50%"
|
|
71
|
+
cy="50%"
|
|
72
|
+
outerRadius="80%"
|
|
73
|
+
>
|
|
74
|
+
<PolarGrid stroke="var(--border)" />
|
|
75
|
+
<PolarAngleAxis
|
|
76
|
+
dataKey="subject"
|
|
77
|
+
tick={{ fill: 'var(--foreground)', fontSize: 12 }}
|
|
78
|
+
/>
|
|
79
|
+
<PolarRadiusAxis
|
|
80
|
+
tick={{ fill: 'var(--foreground)', fontSize: 10 }}
|
|
81
|
+
axisLine={{ stroke: 'var(--border)' }}
|
|
82
|
+
/>
|
|
83
|
+
<Tooltip content={<CustomTooltip />} />
|
|
84
|
+
{showLegend && (
|
|
85
|
+
<Legend
|
|
86
|
+
wrapperStyle={{ color: 'var(--foreground)' }}
|
|
87
|
+
formatter={(value) => (
|
|
88
|
+
<span style={{ color: 'var(--foreground)' }}>{value}</span>
|
|
89
|
+
)}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
<Radar
|
|
93
|
+
name="Value"
|
|
94
|
+
dataKey="value"
|
|
95
|
+
stroke={COLORS[0]}
|
|
96
|
+
fill={COLORS[0]}
|
|
97
|
+
fillOpacity={0.3}
|
|
98
|
+
isAnimationActive={false}
|
|
99
|
+
/>
|
|
100
|
+
</RechartsRadarChart>
|
|
101
|
+
</ResponsiveContainer>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils'
|
|
4
|
+
import { FC } from 'react'
|
|
5
|
+
import {
|
|
6
|
+
ScatterChart as RechartsScatterChart,
|
|
7
|
+
Scatter,
|
|
8
|
+
XAxis,
|
|
9
|
+
YAxis,
|
|
10
|
+
CartesianGrid,
|
|
11
|
+
Tooltip,
|
|
12
|
+
ResponsiveContainer,
|
|
13
|
+
ZAxis,
|
|
14
|
+
Cell,
|
|
15
|
+
TooltipProps,
|
|
16
|
+
} from 'recharts'
|
|
17
|
+
|
|
18
|
+
interface ScatterDataPoint {
|
|
19
|
+
x: number
|
|
20
|
+
y: number
|
|
21
|
+
label?: string
|
|
22
|
+
size?: number
|
|
23
|
+
color?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const CustomTooltip = ({ active, payload }: TooltipProps<number, string>) => {
|
|
27
|
+
if (!active || !payload || payload.length === 0) return null
|
|
28
|
+
const point = payload[0]?.payload as ScatterDataPoint | undefined
|
|
29
|
+
return (
|
|
30
|
+
<div className="bg-background text-foreground border-border rounded-md border px-2 py-1.5 text-xs shadow-sm">
|
|
31
|
+
{point?.label && <div className="font-medium">{point.label}</div>}
|
|
32
|
+
<div>x: {point?.x?.toLocaleString()}</div>
|
|
33
|
+
<div>y: {point?.y?.toLocaleString()}</div>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const COLORS = [
|
|
39
|
+
'var(--chart-1)',
|
|
40
|
+
'var(--chart-2)',
|
|
41
|
+
'var(--chart-3)',
|
|
42
|
+
'var(--chart-4)',
|
|
43
|
+
'var(--chart-5)',
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
export interface ScatterChartProps {
|
|
47
|
+
title?: string
|
|
48
|
+
data: ScatterDataPoint[]
|
|
49
|
+
xLabel?: string
|
|
50
|
+
yLabel?: string
|
|
51
|
+
showGrid?: boolean
|
|
52
|
+
className?: string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const ScatterChart: FC<ScatterChartProps> = ({
|
|
56
|
+
title,
|
|
57
|
+
data,
|
|
58
|
+
xLabel,
|
|
59
|
+
yLabel,
|
|
60
|
+
showGrid = true,
|
|
61
|
+
className,
|
|
62
|
+
}) => {
|
|
63
|
+
// Check if we have size data for bubble chart effect
|
|
64
|
+
const hasSizeData = data.some((d) => d.size !== undefined)
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div className={cn('flex flex-col gap-2', className)}>
|
|
68
|
+
{title && (
|
|
69
|
+
<h3 className="text-foreground text-sm font-medium">{title}</h3>
|
|
70
|
+
)}
|
|
71
|
+
<div className="h-[250px] w-full">
|
|
72
|
+
<ResponsiveContainer width="100%" height="100%">
|
|
73
|
+
<RechartsScatterChart
|
|
74
|
+
margin={{ top: 10, right: 10, left: 10, bottom: 10 }}
|
|
75
|
+
>
|
|
76
|
+
{showGrid && (
|
|
77
|
+
<CartesianGrid
|
|
78
|
+
strokeDasharray="3 3"
|
|
79
|
+
className="stroke-muted/30"
|
|
80
|
+
/>
|
|
81
|
+
)}
|
|
82
|
+
<XAxis
|
|
83
|
+
type="number"
|
|
84
|
+
dataKey="x"
|
|
85
|
+
name={xLabel || 'x'}
|
|
86
|
+
tick={{ fill: 'var(--foreground)', fontSize: 12 }}
|
|
87
|
+
axisLine={{ stroke: 'var(--border)' }}
|
|
88
|
+
tickLine={{ stroke: 'var(--border)' }}
|
|
89
|
+
label={
|
|
90
|
+
xLabel
|
|
91
|
+
? {
|
|
92
|
+
value: xLabel,
|
|
93
|
+
position: 'bottom',
|
|
94
|
+
offset: -5,
|
|
95
|
+
fill: 'var(--foreground)',
|
|
96
|
+
}
|
|
97
|
+
: undefined
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
<YAxis
|
|
101
|
+
type="number"
|
|
102
|
+
dataKey="y"
|
|
103
|
+
name={yLabel || 'y'}
|
|
104
|
+
tick={{ fill: 'var(--foreground)', fontSize: 12 }}
|
|
105
|
+
axisLine={{ stroke: 'var(--border)' }}
|
|
106
|
+
tickLine={{ stroke: 'var(--border)' }}
|
|
107
|
+
label={
|
|
108
|
+
yLabel
|
|
109
|
+
? {
|
|
110
|
+
value: yLabel,
|
|
111
|
+
angle: -90,
|
|
112
|
+
position: 'left',
|
|
113
|
+
fill: 'var(--foreground)',
|
|
114
|
+
}
|
|
115
|
+
: undefined
|
|
116
|
+
}
|
|
117
|
+
/>
|
|
118
|
+
{hasSizeData && (
|
|
119
|
+
<ZAxis type="number" dataKey="size" range={[50, 400]} />
|
|
120
|
+
)}
|
|
121
|
+
<Tooltip content={<CustomTooltip />} />
|
|
122
|
+
<Scatter data={data} fill={COLORS[0]} isAnimationActive={false}>
|
|
123
|
+
{data.map((entry, index) => (
|
|
124
|
+
<Cell key={`cell-${index}`} fill={entry.color || COLORS[0]} />
|
|
125
|
+
))}
|
|
126
|
+
</Scatter>
|
|
127
|
+
</RechartsScatterChart>
|
|
128
|
+
</ResponsiveContainer>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useRadius } from '@/hooks/useRadius'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
import { FC, ReactNode } from 'react'
|
|
6
|
+
|
|
7
|
+
interface MacOSWindowFrameProps {
|
|
8
|
+
children: ReactNode
|
|
9
|
+
className?: string
|
|
10
|
+
/** Optional title to display in the title bar */
|
|
11
|
+
title?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A macOS-style window frame with traffic light buttons.
|
|
16
|
+
* Wraps content in a bordered container with a title bar.
|
|
17
|
+
*/
|
|
18
|
+
export const MacOSWindowFrame: FC<MacOSWindowFrameProps> = ({
|
|
19
|
+
children,
|
|
20
|
+
className,
|
|
21
|
+
title,
|
|
22
|
+
}) => {
|
|
23
|
+
const r = useRadius()
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="@container my-4 w-full first:mt-0">
|
|
27
|
+
<div
|
|
28
|
+
className={cn(
|
|
29
|
+
// after:hidden prevents assistant-ui from showing its default code block loading indicator
|
|
30
|
+
'border-border w-full overflow-hidden border after:hidden @sm:max-w-md @md:max-w-lg @lg:max-w-xl @xl:max-w-2xl',
|
|
31
|
+
r('lg'),
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{/* Title bar */}
|
|
36
|
+
<div className="border-border bg-muted/50 flex h-8 items-center gap-2 border-b px-3">
|
|
37
|
+
{/* Traffic lights */}
|
|
38
|
+
<div className="flex items-center gap-1.5">
|
|
39
|
+
<div className="size-3 rounded-full bg-[#FF5F57]" />
|
|
40
|
+
<div className="size-3 rounded-full bg-[#FEBC2E]" />
|
|
41
|
+
<div className="size-3 rounded-full bg-[#28C840]" />
|
|
42
|
+
</div>
|
|
43
|
+
{/* Title */}
|
|
44
|
+
{title && (
|
|
45
|
+
<span className="text-muted-foreground flex-1 text-center text-xs font-medium">
|
|
46
|
+
{title}
|
|
47
|
+
</span>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
{/* Content */}
|
|
51
|
+
{children}
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useRadius } from '@/hooks/useRadius'
|
|
4
3
|
import { cn } from '@/lib/utils'
|
|
5
4
|
import { FC } from 'react'
|
|
5
|
+
import { MacOSWindowFrame } from './MacOSWindowFrame'
|
|
6
6
|
|
|
7
7
|
interface PluginLoadingStateProps {
|
|
8
8
|
text: string
|
|
@@ -11,25 +11,21 @@ interface PluginLoadingStateProps {
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Shared loading state component for plugins.
|
|
14
|
-
* Displays a shimmer effect with loading text.
|
|
14
|
+
* Displays a shimmer effect with loading text inside a macOS-style window.
|
|
15
15
|
*/
|
|
16
16
|
export const PluginLoadingState: FC<PluginLoadingStateProps> = ({
|
|
17
17
|
text,
|
|
18
18
|
className,
|
|
19
19
|
}) => {
|
|
20
|
-
const r = useRadius()
|
|
21
|
-
|
|
22
20
|
return (
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
>
|
|
30
|
-
<div className="bg-muted absolute inset-0 flex items-center justify-center">
|
|
21
|
+
<MacOSWindowFrame className={className}>
|
|
22
|
+
<div
|
|
23
|
+
className={cn(
|
|
24
|
+
'bg-background relative flex min-h-[400px] items-center justify-center'
|
|
25
|
+
)}
|
|
26
|
+
>
|
|
31
27
|
<span className="shimmer text-muted-foreground text-sm">{text}</span>
|
|
32
28
|
</div>
|
|
33
|
-
</
|
|
29
|
+
</MacOSWindowFrame>
|
|
34
30
|
)
|
|
35
31
|
}
|