@agent-native/toolkit 0.217.0 → 0.219.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/agent-native.eject.json +21 -0
- package/dist/app/agent-page/AgentContextTab.d.ts.map +1 -1
- package/dist/app/agent-page/AgentContextTab.js +1 -0
- package/dist/app/agent-page/AgentContextTab.js.map +1 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +1 -1
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +4 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +3 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/data-chart-layout.d.ts +30 -0
- package/dist/app/agentkit/react/data-chart-layout.d.ts.map +1 -0
- package/dist/app/agentkit/react/data-chart-layout.js +2 -0
- package/dist/app/agentkit/react/data-chart-layout.js.map +1 -0
- package/dist/app/agentkit/react/index.d.ts +1 -0
- package/dist/app/agentkit/react/index.d.ts.map +1 -1
- package/dist/app/agentkit/react/index.js +1 -0
- package/dist/app/agentkit/react/index.js.map +1 -1
- package/dist/app/agentkit/react/root.d.ts +3 -1
- package/dist/app/agentkit/react/root.d.ts.map +1 -1
- package/dist/app/agentkit/react/root.js +2 -2
- package/dist/app/agentkit/react/root.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +31 -6
- package/dist/app/agentkit/react/transcript-layout.d.ts +2 -0
- package/dist/app/agentkit/react/transcript-layout.d.ts.map +1 -1
- package/dist/app/agentkit/react/transcript-layout.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +2 -2
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.js +6 -6
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +53 -95
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/action-widget.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/action-widget.js +4 -1
- package/dist/app/chat/agentkit-chat/action-widget.js.map +1 -1
- package/dist/app/chat/agentkit-chat/rail.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/rail.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/rail.js +1 -1
- package/dist/app/chat/agentkit-chat/rail.js.map +1 -1
- package/dist/app/chat/chat/index.d.ts +2 -1
- package/dist/app/chat/chat/index.d.ts.map +1 -1
- package/dist/app/chat/chat/index.js +1 -1
- package/dist/app/chat/chat/index.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +3 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/chat/surface-types.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts +5 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +6 -4
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat/tool-render-registry.d.ts +4 -0
- package/dist/app/chat/chat/tool-render-registry.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-render-registry.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.js +116 -26
- package/dist/app/chat/chat/widgets/DataChartRenderer.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js +21 -2
- package/dist/app/chat/chat/widgets/DataChartWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js +2 -2
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js +3 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js.map +1 -1
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js +2 -2
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/app/chat/chat-first/chat-history.d.ts +13 -2
- package/dist/app/chat/chat-first/chat-history.d.ts.map +1 -1
- package/dist/app/chat/chat-first/chat-history.js +24 -3
- package/dist/app/chat/chat-first/chat-history.js.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.js +6 -1
- package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.d.ts +6 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.js +9 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.js.map +1 -0
- package/dist/app/chat/ownership-history/index.d.ts +11 -0
- package/dist/app/chat/ownership-history/index.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/index.js +22 -0
- package/dist/app/chat/ownership-history/index.js.map +1 -0
- package/dist/app/chat/ownership-history/rows.d.ts +27 -0
- package/dist/app/chat/ownership-history/rows.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/rows.js +101 -0
- package/dist/app/chat/ownership-history/rows.js.map +1 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.d.ts +52 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.js +497 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +3 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +3 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +3 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +3 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +3 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +3 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +3 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +3 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +3 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +3 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +3 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +3 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/shared/CommandMenu.d.ts +2 -0
- package/dist/app/shared/CommandMenu.d.ts.map +1 -1
- package/dist/app/shared/CommandMenu.js +11 -6
- package/dist/app/shared/CommandMenu.js.map +1 -1
- package/dist/app/sharing/ShareButton.d.ts.map +1 -1
- package/dist/app/sharing/ShareButton.js +9 -8
- package/dist/app/sharing/ShareButton.js.map +1 -1
- package/dist/chat-history/ChatHistoryList.d.ts +16 -3
- package/dist/chat-history/ChatHistoryList.d.ts.map +1 -1
- package/dist/chat-history/ChatHistoryList.js +25 -15
- package/dist/chat-history/ChatHistoryList.js.map +1 -1
- package/dist/chat-history.css +109 -9
- package/dist/composer/TiptapComposer.js +1 -1
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/package.json +10 -3
- package/src/app/agent-page/AgentContextTab.spec.ts +50 -2
- package/src/app/agent-page/AgentContextTab.tsx +1 -0
- package/src/app/agentkit/react/components.interaction.spec.tsx +2 -0
- package/src/app/agentkit/react/components.spec.tsx +11 -6
- package/src/app/agentkit/react/components.tsx +3 -0
- package/src/app/agentkit/react/context.tsx +6 -0
- package/src/app/agentkit/react/data-chart-layout.ts +25 -0
- package/src/app/agentkit/react/index.ts +1 -0
- package/src/app/agentkit/react/root.tsx +4 -0
- package/src/app/agentkit/react/styles.css +31 -6
- package/src/app/agentkit/react/transcript-layout.ts +2 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +201 -27
- package/src/app/chat/AgentKitAssistantChat.tsx +3 -0
- package/src/app/chat/AgentPanel.tsx +8 -8
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +270 -3
- package/src/app/chat/MultiTabAssistantChat.tsx +81 -158
- package/src/app/chat/agentkit-chat/action-widget.spec.tsx +62 -0
- package/src/app/chat/agentkit-chat/action-widget.tsx +4 -0
- package/src/app/chat/agentkit-chat/rail.ts +11 -0
- package/src/app/chat/chat/index.ts +10 -0
- package/src/app/chat/chat/surface-types.ts +3 -0
- package/src/app/chat/chat/tool-call-display.spec.tsx +29 -0
- package/src/app/chat/chat/tool-call-display.tsx +17 -1
- package/src/app/chat/chat/tool-render-registry.tsx +5 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.spec.tsx +377 -17
- package/src/app/chat/chat/widgets/DataChartRenderer.tsx +232 -63
- package/src/app/chat/chat/widgets/DataChartWidget.spec.tsx +67 -0
- package/src/app/chat/chat/widgets/DataChartWidget.tsx +39 -5
- package/src/app/chat/chat/widgets/DataInsightsWidget.tsx +13 -2
- package/src/app/chat/chat/widgets/DataWidgetDisplayControls.tsx +6 -4
- package/src/app/chat/chat/widgets/builtin-tool-renderers.tsx +5 -1
- package/src/app/chat/chat-first/chat-history.spec.tsx +79 -0
- package/src/app/chat/chat-first/chat-history.tsx +75 -22
- package/src/app/chat/conversation/AgentConversation.spec.tsx +51 -1
- package/src/app/chat/conversation/AgentConversation.tsx +11 -2
- package/src/app/chat/ownership-history/ChatOwnerAvatar.tsx +27 -0
- package/src/app/chat/ownership-history/index.tsx +67 -0
- package/src/app/chat/ownership-history/ownership-history.spec.tsx +3146 -0
- package/src/app/chat/ownership-history/rows.ts +156 -0
- package/src/app/chat/ownership-history/useOwnershipChatHistory.ts +709 -0
- package/src/app/i18n/catalogs/ar-SA.ts +3 -0
- package/src/app/i18n/catalogs/de-DE.ts +3 -0
- package/src/app/i18n/catalogs/en-US.ts +3 -0
- package/src/app/i18n/catalogs/es-ES.ts +3 -0
- package/src/app/i18n/catalogs/fr-FR.ts +3 -0
- package/src/app/i18n/catalogs/hi-IN.ts +3 -0
- package/src/app/i18n/catalogs/ja-JP.ts +3 -0
- package/src/app/i18n/catalogs/ko-KR.ts +3 -0
- package/src/app/i18n/catalogs/pt-BR.ts +3 -0
- package/src/app/i18n/catalogs/zh-CN.ts +3 -0
- package/src/app/i18n/catalogs/zh-TW.ts +3 -0
- package/src/app/shared/CommandMenu.spec.tsx +175 -6
- package/src/app/shared/CommandMenu.tsx +24 -7
- package/src/app/sharing/ShareButton.tsx +12 -10
- package/src/chat-history/ChatHistoryList.spec.tsx +51 -0
- package/src/chat-history/ChatHistoryList.tsx +87 -26
- package/src/chat-history/ChatHistoryRailSections.spec.tsx +12 -4
- package/src/chat-history.css +109 -9
- package/src/composer/TiptapComposer.tsx +1 -1
|
@@ -59,6 +59,302 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
59
59
|
expect(markup).toContain('stroke="hsl(var(--chart-grid, var(--border)))"');
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
+
it("applies app chart sizing, plot insets, typography, and integer tick labels", () => {
|
|
63
|
+
const markup = renderToStaticMarkup(
|
|
64
|
+
<DataChartRenderer
|
|
65
|
+
chart={{
|
|
66
|
+
type: "line",
|
|
67
|
+
xKey: "day",
|
|
68
|
+
series: [{ key: "value", label: "Value" }],
|
|
69
|
+
data: [
|
|
70
|
+
{ day: "First", value: 0 },
|
|
71
|
+
{ day: "Last", value: 1 },
|
|
72
|
+
],
|
|
73
|
+
valueAxisTickInterval: 0.1,
|
|
74
|
+
}}
|
|
75
|
+
layout={{
|
|
76
|
+
plotInsets: { top: 6, right: 8, bottom: 29 },
|
|
77
|
+
labelFontFamily: "IBM Plex Sans",
|
|
78
|
+
labelFontSize: 14,
|
|
79
|
+
labelTone: "foreground",
|
|
80
|
+
}}
|
|
81
|
+
/>,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(markup).toContain('font-family="IBM Plex Sans"');
|
|
85
|
+
expect(markup).toContain('font-size="14"');
|
|
86
|
+
expect(markup).toMatch(
|
|
87
|
+
/<text[^>]*fill="hsl\(var\(--foreground\)\)"[^>]*>First<\/text>/,
|
|
88
|
+
);
|
|
89
|
+
expect(markup).toMatch(/<line x1="[^"]+" x2="632" y1="6" y2="6"/);
|
|
90
|
+
expect(markup).toMatch(/<line x1="[^"]+" x2="632" y1="331" y2="331"/);
|
|
91
|
+
expect(markup).toContain(">1</text>");
|
|
92
|
+
expect(markup).not.toContain(">1.0</text>");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("preserves one-decimal ticks without an app layout override", () => {
|
|
96
|
+
const markup = renderToStaticMarkup(
|
|
97
|
+
<DataChartRenderer
|
|
98
|
+
chart={{
|
|
99
|
+
type: "line",
|
|
100
|
+
xKey: "day",
|
|
101
|
+
series: [{ key: "value", label: "Value" }],
|
|
102
|
+
data: [
|
|
103
|
+
{ day: "First", value: 0 },
|
|
104
|
+
{ day: "Last", value: 1 },
|
|
105
|
+
],
|
|
106
|
+
valueAxisTickInterval: 0.1,
|
|
107
|
+
}}
|
|
108
|
+
/>,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(markup).toContain(">0.0</text>");
|
|
112
|
+
expect(markup).toContain(">1.0</text>");
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("keeps positive value labels outside horizontal bars with a right inset", () => {
|
|
116
|
+
const markup = renderToStaticMarkup(
|
|
117
|
+
<DataChartRenderer
|
|
118
|
+
chart={{
|
|
119
|
+
type: "bar",
|
|
120
|
+
layout: "horizontal",
|
|
121
|
+
xKey: "day",
|
|
122
|
+
series: [{ key: "value", label: "Value" }],
|
|
123
|
+
data: [{ day: "Monday", value: 3 }],
|
|
124
|
+
showValueLabels: true,
|
|
125
|
+
valueAxisTickInterval: 0.2,
|
|
126
|
+
}}
|
|
127
|
+
layout={{ plotInsets: { right: 8 } }}
|
|
128
|
+
/>,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const plotRightEdge = Number(
|
|
132
|
+
markup.match(/<line x1="[\d.]+" x2="([\d.]+)" y1="14" y2="326"/)?.[1],
|
|
133
|
+
);
|
|
134
|
+
expect(plotRightEdge).toBeLessThanOrEqual(632);
|
|
135
|
+
expect(markup).toContain('fill="hsl(var(--muted-foreground))"');
|
|
136
|
+
const maximumBarValueLabel = markup.match(
|
|
137
|
+
/<text[^>]*x="([\d.]+)" y="[^"]+" fill="hsl\(var\(--muted-foreground\)\)" font-size="11" font-weight="400" text-anchor="start">3<\/text>/,
|
|
138
|
+
);
|
|
139
|
+
expect(maximumBarValueLabel).not.toBeNull();
|
|
140
|
+
expect(Number(maximumBarValueLabel?.[1])).toBeGreaterThan(plotRightEdge);
|
|
141
|
+
expect(Number(maximumBarValueLabel?.[1]) + 8).toBeLessThanOrEqual(640);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("rejects inset combinations that leave no positive plot area", () => {
|
|
145
|
+
const renderWithInsets = (plotInsets: { right?: number; top?: number }) =>
|
|
146
|
+
renderToStaticMarkup(
|
|
147
|
+
<DataChartRenderer
|
|
148
|
+
chart={{
|
|
149
|
+
type: "line",
|
|
150
|
+
xKey: "day",
|
|
151
|
+
series: [{ key: "value", label: "Value" }],
|
|
152
|
+
data: [{ day: "Monday", value: 1 }],
|
|
153
|
+
}}
|
|
154
|
+
layout={{ plotInsets }}
|
|
155
|
+
/>,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
expect(() => renderWithInsets({ right: 600 })).toThrow(
|
|
159
|
+
"positive chart plot area",
|
|
160
|
+
);
|
|
161
|
+
expect(() => renderWithInsets({ top: 400 })).toThrow(
|
|
162
|
+
"positive chart plot area",
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("keeps a vertical bar chart's final category label inside the SVG", () => {
|
|
167
|
+
const markup = renderToStaticMarkup(
|
|
168
|
+
<DataChartRenderer
|
|
169
|
+
chart={{
|
|
170
|
+
type: "bar",
|
|
171
|
+
xKey: "day",
|
|
172
|
+
series: [{ key: "value", label: "Value" }],
|
|
173
|
+
data: Array.from({ length: 10 }, (_, index) => ({
|
|
174
|
+
day: index === 9 ? "Last category label" : `Day ${index}`,
|
|
175
|
+
value: index,
|
|
176
|
+
})),
|
|
177
|
+
}}
|
|
178
|
+
layout={{ plotInsets: { right: 8 } }}
|
|
179
|
+
/>,
|
|
180
|
+
);
|
|
181
|
+
const finalCategory = markup.match(
|
|
182
|
+
/<text[^>]*x="([\d.]+)" y="348"[^>]*text-anchor="end">Last category\.\.\.<\/text>/,
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(finalCategory).not.toBeNull();
|
|
186
|
+
expect(Number(finalCategory?.[1])).toBeLessThanOrEqual(632);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("keeps a long first category label inside the SVG", () => {
|
|
190
|
+
const markup = renderToStaticMarkup(
|
|
191
|
+
<DataChartRenderer
|
|
192
|
+
chart={{
|
|
193
|
+
type: "line",
|
|
194
|
+
xKey: "day",
|
|
195
|
+
series: [{ key: "value", label: "Value" }],
|
|
196
|
+
data: [
|
|
197
|
+
{ day: "First category label", value: 0 },
|
|
198
|
+
{ day: "Last", value: 1 },
|
|
199
|
+
],
|
|
200
|
+
}}
|
|
201
|
+
/>,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
expect(markup).toMatch(
|
|
205
|
+
/<text[^>]*x="46" y="348"[^>]*text-anchor="start">First categor\.\.\.<\/text>/,
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("keeps top vertical-bar value labels above the bar at a zero inset", () => {
|
|
210
|
+
const markup = renderToStaticMarkup(
|
|
211
|
+
<DataChartRenderer
|
|
212
|
+
chart={{
|
|
213
|
+
type: "bar",
|
|
214
|
+
xKey: "day",
|
|
215
|
+
series: [{ key: "value", label: "Value" }],
|
|
216
|
+
data: [{ day: "Monday", value: 1 }],
|
|
217
|
+
showValueLabels: true,
|
|
218
|
+
}}
|
|
219
|
+
layout={{ plotInsets: { top: 0 } }}
|
|
220
|
+
/>,
|
|
221
|
+
);
|
|
222
|
+
const valueLabel = markup.match(
|
|
223
|
+
/<text(?=[^>]*data-value-label="true")(?=[^>]*>1<\/text>)[^>]*y="([\d.]+)"[^>]*>/,
|
|
224
|
+
);
|
|
225
|
+
const bar = markup.match(/<rect[^>]*y="([\d.]+)"/);
|
|
226
|
+
|
|
227
|
+
expect(valueLabel).not.toBeNull();
|
|
228
|
+
expect(Number(valueLabel?.[1])).toBeGreaterThanOrEqual(11);
|
|
229
|
+
expect(bar).not.toBeNull();
|
|
230
|
+
expect(Number(bar?.[1]) - Number(valueLabel?.[1])).toBeGreaterThanOrEqual(
|
|
231
|
+
5,
|
|
232
|
+
);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("keeps final vertical-bar value labels inside the SVG at a small right inset", () => {
|
|
236
|
+
const markup = renderToStaticMarkup(
|
|
237
|
+
<DataChartRenderer
|
|
238
|
+
chart={{
|
|
239
|
+
type: "bar",
|
|
240
|
+
xKey: "day",
|
|
241
|
+
series: [{ key: "value", label: "Value" }],
|
|
242
|
+
data: Array.from({ length: 60 }, (_, index) => ({
|
|
243
|
+
day: `Day ${index}`,
|
|
244
|
+
value: index === 59 ? 1_234_567 : 0,
|
|
245
|
+
})),
|
|
246
|
+
showValueLabels: true,
|
|
247
|
+
}}
|
|
248
|
+
layout={{ plotInsets: { right: 8 } }}
|
|
249
|
+
/>,
|
|
250
|
+
);
|
|
251
|
+
const valueLabels = Array.from(
|
|
252
|
+
markup.matchAll(
|
|
253
|
+
/<text(?=[^>]*data-value-label="true")([^>]*)>([^<]+)<\/text>/g,
|
|
254
|
+
),
|
|
255
|
+
);
|
|
256
|
+
const finalValueLabel = valueLabels.at(-1);
|
|
257
|
+
const finalLabelX = Number(
|
|
258
|
+
finalValueLabel?.[1].match(/\bx="([\d.]+)"/)?.[1],
|
|
259
|
+
);
|
|
260
|
+
const finalLabelWidth =
|
|
261
|
+
Array.from(finalValueLabel?.[2] ?? "").length * 11 * 0.65;
|
|
262
|
+
|
|
263
|
+
expect(finalValueLabel).toBeDefined();
|
|
264
|
+
expect(finalLabelX + finalLabelWidth / 2).toBeLessThanOrEqual(640);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("preserves the top value-axis label when the configured top inset is zero", () => {
|
|
268
|
+
const markup = renderToStaticMarkup(
|
|
269
|
+
<DataChartRenderer
|
|
270
|
+
chart={{
|
|
271
|
+
type: "line",
|
|
272
|
+
xKey: "day",
|
|
273
|
+
series: [{ key: "value", label: "Value" }],
|
|
274
|
+
data: [
|
|
275
|
+
{ day: "Monday", value: 0 },
|
|
276
|
+
{ day: "Tuesday", value: 1 },
|
|
277
|
+
],
|
|
278
|
+
valueAxisTickInterval: 0.5,
|
|
279
|
+
}}
|
|
280
|
+
layout={{ labelFontSize: 12, plotInsets: { top: 0 } }}
|
|
281
|
+
/>,
|
|
282
|
+
);
|
|
283
|
+
const topTick = markup.match(
|
|
284
|
+
/<text(?=[^>]*data-value-axis-tick="true")[^>]*y="([\d.]+)"[^>]*>1<\/text>/,
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
expect(topTick).not.toBeNull();
|
|
288
|
+
expect(Number(topTick?.[1])).toBeGreaterThanOrEqual(12);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("keeps horizontal axis tick labels inside the chart at zero edge insets", () => {
|
|
292
|
+
const markup = renderToStaticMarkup(
|
|
293
|
+
<DataChartRenderer
|
|
294
|
+
chart={{
|
|
295
|
+
type: "bar",
|
|
296
|
+
layout: "horizontal",
|
|
297
|
+
xKey: "day",
|
|
298
|
+
series: [{ key: "value", label: "Value" }],
|
|
299
|
+
data: [{ day: "Monday", value: 3 }],
|
|
300
|
+
valueAxisTickInterval: 1,
|
|
301
|
+
xAxisTitle: "Value",
|
|
302
|
+
}}
|
|
303
|
+
layout={{ plotInsets: { right: 0, bottom: 0 } }}
|
|
304
|
+
/>,
|
|
305
|
+
);
|
|
306
|
+
const finalTick = Array.from(
|
|
307
|
+
markup.matchAll(
|
|
308
|
+
/<text[^>]*x="([\d.]+)" y="([\d.]+)"[^>]*>([^<]+)<\/text>/g,
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
.filter((match) => match[3] === "3")
|
|
312
|
+
.slice(-1)[0];
|
|
313
|
+
|
|
314
|
+
expect(finalTick).toBeDefined();
|
|
315
|
+
expect(Number(finalTick?.[1])).toBeLessThan(640);
|
|
316
|
+
expect(Number(finalTick?.[1]) + 4).toBeLessThanOrEqual(640);
|
|
317
|
+
expect(Number(finalTick?.[2])).toBeLessThan(340);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("keeps vertical axis ticks and category labels clear at a zero bottom inset", () => {
|
|
321
|
+
const markup = renderToStaticMarkup(
|
|
322
|
+
<DataChartRenderer
|
|
323
|
+
chart={{
|
|
324
|
+
type: "line",
|
|
325
|
+
xKey: "day",
|
|
326
|
+
series: [{ key: "value", label: "Value" }],
|
|
327
|
+
data: [
|
|
328
|
+
{ day: "Monday", value: 0 },
|
|
329
|
+
{ day: "Tuesday", value: 1 },
|
|
330
|
+
],
|
|
331
|
+
valueAxisTickInterval: 0.5,
|
|
332
|
+
}}
|
|
333
|
+
layout={{ labelFontSize: 12, plotInsets: { bottom: 0 } }}
|
|
334
|
+
/>,
|
|
335
|
+
);
|
|
336
|
+
const minimumTick = markup.match(
|
|
337
|
+
/<text(?=[^>]*data-value-axis-tick="true")(?=[^>]*>0<\/text>)[^>]*y="([\d.]+)"/,
|
|
338
|
+
);
|
|
339
|
+
const categoryLabel = markup.match(
|
|
340
|
+
/<text[^>]*y="([\d.]+)"[^>]*>Tuesday<\/text>/,
|
|
341
|
+
);
|
|
342
|
+
const plotBaseline = Math.max(
|
|
343
|
+
...Array.from(
|
|
344
|
+
markup.matchAll(/<line[^>]*y1="([\d.]+)" y2="([\d.]+)"/g),
|
|
345
|
+
(match) =>
|
|
346
|
+
match[1] === match[2] ? Number(match[1]) : Number.NEGATIVE_INFINITY,
|
|
347
|
+
),
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
expect(minimumTick).not.toBeNull();
|
|
351
|
+
expect(Number(minimumTick?.[1]) + 3).toBeLessThanOrEqual(360);
|
|
352
|
+
expect(categoryLabel).not.toBeNull();
|
|
353
|
+
expect(Number(categoryLabel?.[1]) - plotBaseline).toBeGreaterThanOrEqual(
|
|
354
|
+
12,
|
|
355
|
+
);
|
|
356
|
+
});
|
|
357
|
+
|
|
62
358
|
it("uses the requested chart content height", () => {
|
|
63
359
|
const markup = renderToStaticMarkup(
|
|
64
360
|
<DataChartRenderer chart={{ ...chart, contentHeight: 400 }} />,
|
|
@@ -217,7 +513,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
217
513
|
expect(numericLabels.at(-1)).toBe("99");
|
|
218
514
|
const tickLabelPositions = Array.from(
|
|
219
515
|
markup.matchAll(
|
|
220
|
-
/<text
|
|
516
|
+
/<text[^>]*x="([\d.]+)"[^>]*text-anchor="middle">\d+<\/text>/g,
|
|
221
517
|
),
|
|
222
518
|
(match) => Number(match[1]),
|
|
223
519
|
);
|
|
@@ -290,7 +586,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
290
586
|
);
|
|
291
587
|
const valueTickLabels = Array.from(
|
|
292
588
|
markup.matchAll(
|
|
293
|
-
/<text
|
|
589
|
+
/<text[^>]*x="([\d.]+)" y="340"[^>]*text-anchor="middle">([^<]+)<\/text>/g,
|
|
294
590
|
),
|
|
295
591
|
(match) => ({ x: Number(match[1]), label: match[2] ?? "" }),
|
|
296
592
|
);
|
|
@@ -321,7 +617,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
321
617
|
);
|
|
322
618
|
const valueTickLabels = Array.from(
|
|
323
619
|
markup.matchAll(
|
|
324
|
-
/<text
|
|
620
|
+
/<text[^>]*x="([\d.]+)" y="340"[^>]*text-anchor="middle">([^<]+)<\/text>/g,
|
|
325
621
|
),
|
|
326
622
|
(match) => ({ x: Number(match[1]), label: match[2] ?? "" }),
|
|
327
623
|
);
|
|
@@ -344,7 +640,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
344
640
|
);
|
|
345
641
|
const valueTickLabels = Array.from(
|
|
346
642
|
markup.matchAll(
|
|
347
|
-
/<text
|
|
643
|
+
/<text[^>]*x="([\d.]+)" y="340"[^>]*text-anchor="middle">([^<]+)<\/text>/g,
|
|
348
644
|
),
|
|
349
645
|
(match) => ({ x: Number(match[1]), label: match[2] ?? "" }),
|
|
350
646
|
);
|
|
@@ -379,7 +675,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
379
675
|
);
|
|
380
676
|
const valueLabels = Array.from(
|
|
381
677
|
markup.matchAll(
|
|
382
|
-
/<text
|
|
678
|
+
/<text[^>]*x="([\d.-]+)" y="([\d.]+)"[^>]*font-size="24"[^>]*text-anchor="(start|end)">([^<]+)<\/text>/g,
|
|
383
679
|
),
|
|
384
680
|
(match) => ({
|
|
385
681
|
x: Number(match[1]),
|
|
@@ -426,7 +722,9 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
426
722
|
/>,
|
|
427
723
|
);
|
|
428
724
|
const tickLabels = Array.from(
|
|
429
|
-
markup.matchAll(
|
|
725
|
+
markup.matchAll(
|
|
726
|
+
/<text(?=[^>]*data-value-axis-tick="true")[^>]*>([^<]+)<\/text>/g,
|
|
727
|
+
),
|
|
430
728
|
(match) => match[1],
|
|
431
729
|
);
|
|
432
730
|
|
|
@@ -454,7 +752,9 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
454
752
|
/>,
|
|
455
753
|
);
|
|
456
754
|
const tickLabels = Array.from(
|
|
457
|
-
markup.matchAll(
|
|
755
|
+
markup.matchAll(
|
|
756
|
+
/<text(?=[^>]*data-value-axis-tick="true")[^>]*>([^<]+)<\/text>/g,
|
|
757
|
+
),
|
|
458
758
|
(match) => match[1],
|
|
459
759
|
);
|
|
460
760
|
|
|
@@ -466,6 +766,40 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
466
766
|
]);
|
|
467
767
|
});
|
|
468
768
|
|
|
769
|
+
it("keeps integer data labels compact while axis ticks retain interval precision", () => {
|
|
770
|
+
const markup = renderToStaticMarkup(
|
|
771
|
+
<DataChartRenderer
|
|
772
|
+
chart={{
|
|
773
|
+
type: "line",
|
|
774
|
+
xKey: "day",
|
|
775
|
+
series: [{ key: "value", label: "Value" }],
|
|
776
|
+
data: [
|
|
777
|
+
{ day: "Monday", value: 0 },
|
|
778
|
+
{ day: "Tuesday", value: 7 },
|
|
779
|
+
],
|
|
780
|
+
showValueLabels: true,
|
|
781
|
+
valueAxisTickInterval: 0.5,
|
|
782
|
+
}}
|
|
783
|
+
/>,
|
|
784
|
+
);
|
|
785
|
+
const axisLabels = Array.from(
|
|
786
|
+
markup.matchAll(
|
|
787
|
+
/<text(?=[^>]*data-value-axis-tick="true")[^>]*>([^<]+)<\/text>/g,
|
|
788
|
+
),
|
|
789
|
+
(match) => match[1],
|
|
790
|
+
);
|
|
791
|
+
const valueLabels = Array.from(
|
|
792
|
+
markup.matchAll(
|
|
793
|
+
/<text(?=[^>]*data-value-label="true")[^>]*>([^<]+)<\/text>/g,
|
|
794
|
+
),
|
|
795
|
+
(match) => match[1],
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
expect(axisLabels).toContain("7.0");
|
|
799
|
+
expect(valueLabels).toContain("7");
|
|
800
|
+
expect(valueLabels).not.toContain("7.0");
|
|
801
|
+
});
|
|
802
|
+
|
|
469
803
|
it("compacts wide vertical ticks while keeping them clear of the axis title", () => {
|
|
470
804
|
const markup = renderToStaticMarkup(
|
|
471
805
|
<DataChartRenderer
|
|
@@ -484,7 +818,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
484
818
|
);
|
|
485
819
|
const tickLabels = Array.from(
|
|
486
820
|
markup.matchAll(
|
|
487
|
-
/<text
|
|
821
|
+
/<text[^>]*x="([\d.]+)" y="([\d.]+)"[^>]*text-anchor="end">([^<]+)<\/text>/g,
|
|
488
822
|
),
|
|
489
823
|
(match) => ({
|
|
490
824
|
x: Number(match[1]),
|
|
@@ -503,7 +837,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
503
837
|
Number(plotBounds?.[2]) - Number(plotBounds?.[1]),
|
|
504
838
|
).toBeGreaterThanOrEqual(32);
|
|
505
839
|
const title = markup.match(
|
|
506
|
-
/<text
|
|
840
|
+
/<text[^>]*x="([\d.]+)" y="[\d.]+" transform="rotate\(-90 [\d.]+ [\d.]+\)"[^>]*font-size="([\d.]+)"[^>]*>Revenue<\/text>/,
|
|
507
841
|
);
|
|
508
842
|
expect(title).not.toBeNull();
|
|
509
843
|
const titleRight = Number(title?.[1]) + Number(title?.[2]) / 2;
|
|
@@ -563,7 +897,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
563
897
|
);
|
|
564
898
|
const horizontalLabels = Array.from(
|
|
565
899
|
horizontalMarkup.matchAll(
|
|
566
|
-
/<text
|
|
900
|
+
/<text[^>]*x="([\d.]+)" y="340"[^>]*text-anchor="middle">([^<]+)<\/text>/g,
|
|
567
901
|
),
|
|
568
902
|
(match) => ({ x: Number(match[1]), label: match[2] ?? "" }),
|
|
569
903
|
);
|
|
@@ -602,7 +936,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
602
936
|
);
|
|
603
937
|
const verticalLabels = Array.from(
|
|
604
938
|
verticalMarkup.matchAll(
|
|
605
|
-
/<text
|
|
939
|
+
/<text[^>]*x="[\d.]+" y="([\d.]+)"[^>]*text-anchor="end">([^<]+)<\/text>/g,
|
|
606
940
|
),
|
|
607
941
|
(match) => ({ y: Number(match[1]), label: match[2] ?? "" }),
|
|
608
942
|
).sort((first, second) => first.y - second.y);
|
|
@@ -619,6 +953,32 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
619
953
|
).toBe(true);
|
|
620
954
|
});
|
|
621
955
|
|
|
956
|
+
it("keeps line value labels inside the canvas with no bottom inset", () => {
|
|
957
|
+
const markup = renderToStaticMarkup(
|
|
958
|
+
<DataChartRenderer
|
|
959
|
+
chart={{
|
|
960
|
+
type: "line",
|
|
961
|
+
xKey: "day",
|
|
962
|
+
series: [{ key: "value", label: "Value" }],
|
|
963
|
+
data: [
|
|
964
|
+
{ day: "First", value: 0 },
|
|
965
|
+
{ day: "Last", value: 1 },
|
|
966
|
+
],
|
|
967
|
+
showValueLabels: true,
|
|
968
|
+
}}
|
|
969
|
+
layout={{ plotInsets: { bottom: 0 } }}
|
|
970
|
+
/>,
|
|
971
|
+
);
|
|
972
|
+
const minimumValueLabelY = Array.from(
|
|
973
|
+
markup.matchAll(
|
|
974
|
+
/<text(?=[^>]*data-value-label="true")(?=[^>]*>0<\/text>)[^>]*y="([\d.]+)"[^>]*>/g,
|
|
975
|
+
),
|
|
976
|
+
(match) => Number(match[1]),
|
|
977
|
+
).filter((y) => y < 360);
|
|
978
|
+
|
|
979
|
+
expect(minimumValueLabelY.some((y) => y <= 356)).toBe(true);
|
|
980
|
+
});
|
|
981
|
+
|
|
622
982
|
it("reserves room for custom decimal value-axis labels", () => {
|
|
623
983
|
const markup = renderToStaticMarkup(
|
|
624
984
|
<DataChartRenderer
|
|
@@ -632,7 +992,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
632
992
|
/>,
|
|
633
993
|
);
|
|
634
994
|
const tickLabels = Array.from(
|
|
635
|
-
markup.matchAll(/<text
|
|
995
|
+
markup.matchAll(/<text[^>]*x="([\d.]+)"[^>]*>(0\.000[123])<\/text>/g),
|
|
636
996
|
(match) => ({ x: Number(match[1]), label: match[2] }),
|
|
637
997
|
);
|
|
638
998
|
|
|
@@ -752,10 +1112,10 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
752
1112
|
/>,
|
|
753
1113
|
);
|
|
754
1114
|
const categoryLabel = markup.match(
|
|
755
|
-
/<text
|
|
1115
|
+
/<text[^>]*x="([\d.]+)" y="[^"]+" fill="hsl\(var\(--muted-foreground\)\)" font-size="10" text-anchor="end">A very long c\.\.\.<\/text>/,
|
|
756
1116
|
);
|
|
757
1117
|
const largestValueLabel = markup.match(
|
|
758
|
-
/<text
|
|
1118
|
+
/<text[^>]*x="([\d.]+)" y="[^"]+" fill="hsl\(var\(--muted-foreground\)\)" font-size="11" font-weight="400" text-anchor="start">123,456<\/text>/,
|
|
759
1119
|
);
|
|
760
1120
|
|
|
761
1121
|
expect(categoryLabel).not.toBeNull();
|
|
@@ -779,10 +1139,10 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
779
1139
|
);
|
|
780
1140
|
const negativeBarX = markup.match(/<rect x="([\d.]+)"/);
|
|
781
1141
|
const negativeBarLabel = markup.match(
|
|
782
|
-
/<text
|
|
1142
|
+
/<text[^>]*x="([\d.]+)"[^>]*text-anchor="end">-123,456<\/text>/,
|
|
783
1143
|
);
|
|
784
1144
|
const categoryLabel = markup.match(
|
|
785
|
-
/<text
|
|
1145
|
+
/<text[^>]*x="([\d.]+)" y="[^"]+" fill="hsl\(var\(--muted-foreground\)\)" font-size="11" text-anchor="end">Monday<\/text>/,
|
|
786
1146
|
);
|
|
787
1147
|
|
|
788
1148
|
expect(negativeBarX).not.toBeNull();
|
|
@@ -839,7 +1199,7 @@ describe("DataChartRenderer theme colors", () => {
|
|
|
839
1199
|
/>,
|
|
840
1200
|
);
|
|
841
1201
|
const finalValueLabel = markup.match(
|
|
842
|
-
/<text
|
|
1202
|
+
/<text[^>]*x="([\d.]+)" y="[\d.]+" fill="hsl\(var\(--muted-foreground\)\)" font-size="11" font-weight="400" text-anchor="end">123,456,789<\/text>/,
|
|
843
1203
|
);
|
|
844
1204
|
|
|
845
1205
|
expect(finalValueLabel).not.toBeNull();
|