@agent-native/core 0.76.10 → 0.76.12
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/docs/content/locales/ar-SA/actions.md +7 -7
- package/corpus/core/docs/content/locales/ar-SA/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/de-DE/actions.md +9 -9
- package/corpus/core/docs/content/locales/de-DE/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/es-ES/actions.md +9 -9
- package/corpus/core/docs/content/locales/es-ES/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/fr-FR/actions.md +9 -9
- package/corpus/core/docs/content/locales/fr-FR/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/hi-IN/actions.md +9 -9
- package/corpus/core/docs/content/locales/hi-IN/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/ja-JP/actions.md +9 -9
- package/corpus/core/docs/content/locales/ja-JP/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/ko-KR/actions.md +9 -9
- package/corpus/core/docs/content/locales/ko-KR/template-plan.md +4 -4
- package/corpus/core/docs/content/locales/pt-BR/actions.md +9 -9
- package/corpus/core/docs/content/locales/pt-BR/template-plan.md +6 -4
- package/corpus/core/docs/content/locales/zh-CN/actions.md +9 -9
- package/corpus/core/docs/content/locales/zh-CN/template-plan.md +4 -4
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/ErrorBoundary.tsx +151 -10
- package/corpus/core/src/client/FeedbackButton.tsx +162 -18
- package/corpus/core/src/client/blocks/library/AnnotatedCodeBlock.tsx +11 -2
- package/corpus/core/src/client/blocks/library/ApiEndpointBlock.tsx +46 -19
- package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +7 -5
- package/corpus/core/src/client/blocks/library/block-copy.ts +367 -0
- package/corpus/core/src/client/blocks/library/diagram.tsx +8 -6
- package/corpus/core/src/client/blocks/library/wireframe.tsx +7 -2
- package/corpus/core/src/client/i18n.tsx +4 -0
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +51 -31
- package/corpus/templates/analytics/app/components/layout/DashboardHeader.tsx +26 -16
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -2
- package/corpus/templates/analytics/app/components/layout/HeaderActions.tsx +8 -1
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -5
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +172 -107
- package/corpus/templates/analytics/app/i18n-data.ts +1076 -5
- package/corpus/templates/analytics/app/pages/Settings.tsx +2 -2
- package/corpus/templates/analytics/changelog/2026-06-24-analytics-navigation-command-palette-and-settings-now-honor-.md +6 -0
- package/corpus/templates/assets/app/components/layout/Header.tsx +0 -2
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +0 -2
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -2
- package/corpus/templates/chat/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/clips/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/clips/app/hooks/use-library.ts +2 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +3 -1
- package/corpus/templates/clips/changelog/2026-06-24-archive-and-spaces-navigation-is-more-resilient-when-sidebar.md +6 -0
- package/corpus/templates/content/app/components/layout/Header.tsx +0 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/forms/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/macros/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/mail/app/components/email/CodeBlockLangPicker.tsx +4 -2
- package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +18 -12
- package/corpus/templates/mail/app/components/email/ComposeEditor.tsx +9 -5
- package/corpus/templates/mail/app/components/email/ComposeModal.tsx +36 -19
- package/corpus/templates/mail/app/components/email/EmailList.tsx +59 -55
- package/corpus/templates/mail/app/components/email/EmailListItem.tsx +7 -3
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +25 -16
- package/corpus/templates/mail/app/components/email/InlineReplyComposer.tsx +25 -19
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +32 -17
- package/corpus/templates/mail/app/components/email/RecipientInput.tsx +26 -10
- package/corpus/templates/mail/app/components/email/SendLaterButton.tsx +5 -3
- package/corpus/templates/mail/app/components/email/SnoozeModal.tsx +4 -2
- package/corpus/templates/mail/app/components/email/SnoozePopover.tsx +9 -5
- package/corpus/templates/mail/app/components/email/extensions/ComposeImageBlock.tsx +4 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +168 -86
- package/corpus/templates/mail/app/components/layout/SearchBar.tsx +4 -2
- package/corpus/templates/mail/app/i18n/ar-SA.ts +212 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +212 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +212 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +212 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +212 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +212 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +212 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +212 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +212 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +211 -0
- package/corpus/templates/mail/app/root.tsx +90 -6
- package/corpus/templates/mail/changelog/2026-06-24-interface-language-support-now-covers-more-mail-controls-and.md +6 -0
- package/corpus/templates/plan/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/slides/app/components/layout/Header.tsx +1 -6
- package/corpus/templates/videos/app/components/layout/Header.tsx +1 -6
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +128 -7
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +142 -14
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +6 -2
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
- package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/ApiEndpointBlock.js +14 -6
- package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +6 -4
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/block-copy.d.ts +33 -0
- package/dist/client/blocks/library/block-copy.d.ts.map +1 -0
- package/dist/client/blocks/library/block-copy.js +329 -0
- package/dist/client/blocks/library/block-copy.js.map +1 -0
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +7 -5
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +4 -2
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/i18n.d.ts +1 -0
- package/dist/client/i18n.d.ts.map +1 -1
- package/dist/client/i18n.js +3 -0
- package/dist/client/i18n.js.map +1 -1
- package/docs/content/locales/ar-SA/actions.md +7 -7
- package/docs/content/locales/ar-SA/template-plan.md +6 -4
- package/docs/content/locales/de-DE/actions.md +9 -9
- package/docs/content/locales/de-DE/template-plan.md +6 -4
- package/docs/content/locales/es-ES/actions.md +9 -9
- package/docs/content/locales/es-ES/template-plan.md +6 -4
- package/docs/content/locales/fr-FR/actions.md +9 -9
- package/docs/content/locales/fr-FR/template-plan.md +6 -4
- package/docs/content/locales/hi-IN/actions.md +9 -9
- package/docs/content/locales/hi-IN/template-plan.md +4 -4
- package/docs/content/locales/ja-JP/actions.md +9 -9
- package/docs/content/locales/ja-JP/template-plan.md +4 -4
- package/docs/content/locales/ko-KR/actions.md +9 -9
- package/docs/content/locales/ko-KR/template-plan.md +4 -4
- package/docs/content/locales/pt-BR/actions.md +9 -9
- package/docs/content/locales/pt-BR/template-plan.md +6 -4
- package/docs/content/locales/zh-CN/actions.md +9 -9
- package/docs/content/locales/zh-CN/template-plan.md +4 -4
- package/package.json +1 -1
|
@@ -13,6 +13,8 @@ import { IconMessage2, IconCheck } from "@tabler/icons-react";
|
|
|
13
13
|
import { cn } from "./utils.js";
|
|
14
14
|
import { useSession } from "./use-session.js";
|
|
15
15
|
import { getFeedbackClientContext } from "./feedback-context.js";
|
|
16
|
+
import { useLocale } from "./i18n.js";
|
|
17
|
+
import { DEFAULT_LOCALE, type LocaleCode } from "../localization/shared.js";
|
|
16
18
|
|
|
17
19
|
const DEFAULT_FEEDBACK_URL =
|
|
18
20
|
"https://forms.agent-native.com/f/agent-native-feedback/_16ewV";
|
|
@@ -27,10 +29,142 @@ interface FormSchema {
|
|
|
27
29
|
fieldId: string;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const FEEDBACK_COPY: Record<
|
|
33
|
+
LocaleCode,
|
|
34
|
+
{
|
|
35
|
+
label: string;
|
|
36
|
+
placeholder: string;
|
|
37
|
+
submit: string;
|
|
38
|
+
submitting: string;
|
|
39
|
+
success: string;
|
|
40
|
+
loadError: string;
|
|
41
|
+
invalidUrl: string;
|
|
42
|
+
emptyError: string;
|
|
43
|
+
sendError: string;
|
|
44
|
+
keyboardHint: string;
|
|
45
|
+
}
|
|
46
|
+
> = {
|
|
47
|
+
"en-US": {
|
|
48
|
+
label: "Feedback",
|
|
49
|
+
placeholder: "What's working, what's broken, or what would you change?",
|
|
50
|
+
submit: "Send feedback",
|
|
51
|
+
submitting: "Sending...",
|
|
52
|
+
success: "Thanks for the feedback!",
|
|
53
|
+
loadError: "Couldn't load feedback form",
|
|
54
|
+
invalidUrl: "Invalid feedback URL",
|
|
55
|
+
emptyError: "Please write something first",
|
|
56
|
+
sendError: "Couldn't send feedback",
|
|
57
|
+
keyboardHint: "{{shortcut}}+Enter to send",
|
|
58
|
+
},
|
|
59
|
+
"zh-CN": {
|
|
60
|
+
label: "反馈",
|
|
61
|
+
placeholder: "哪些地方好用、哪里坏了,或你想改什么?",
|
|
62
|
+
submit: "发送反馈",
|
|
63
|
+
submitting: "正在发送...",
|
|
64
|
+
success: "感谢你的反馈!",
|
|
65
|
+
loadError: "无法加载反馈表单",
|
|
66
|
+
invalidUrl: "反馈 URL 无效",
|
|
67
|
+
emptyError: "请先写点内容",
|
|
68
|
+
sendError: "无法发送反馈",
|
|
69
|
+
keyboardHint: "{{shortcut}}+Enter 发送",
|
|
70
|
+
},
|
|
71
|
+
"es-ES": {
|
|
72
|
+
label: "Comentarios",
|
|
73
|
+
placeholder: "¿Qué funciona, qué falla o qué cambiarías?",
|
|
74
|
+
submit: "Enviar comentarios",
|
|
75
|
+
submitting: "Enviando...",
|
|
76
|
+
success: "Gracias por tus comentarios.",
|
|
77
|
+
loadError: "No se pudo cargar el formulario",
|
|
78
|
+
invalidUrl: "URL de comentarios no válida",
|
|
79
|
+
emptyError: "Escribe algo primero",
|
|
80
|
+
sendError: "No se pudieron enviar los comentarios",
|
|
81
|
+
keyboardHint: "{{shortcut}}+Enter para enviar",
|
|
82
|
+
},
|
|
83
|
+
"fr-FR": {
|
|
84
|
+
label: "Retour",
|
|
85
|
+
placeholder: "Qu'est-ce qui marche, casse ou devrait changer ?",
|
|
86
|
+
submit: "Envoyer",
|
|
87
|
+
submitting: "Envoi...",
|
|
88
|
+
success: "Merci pour votre retour.",
|
|
89
|
+
loadError: "Impossible de charger le formulaire",
|
|
90
|
+
invalidUrl: "URL de retour invalide",
|
|
91
|
+
emptyError: "Écrivez quelque chose d'abord",
|
|
92
|
+
sendError: "Impossible d'envoyer le retour",
|
|
93
|
+
keyboardHint: "{{shortcut}}+Entrée pour envoyer",
|
|
94
|
+
},
|
|
95
|
+
"de-DE": {
|
|
96
|
+
label: "Feedback",
|
|
97
|
+
placeholder: "Was funktioniert, was ist kaputt, was würdest du ändern?",
|
|
98
|
+
submit: "Feedback senden",
|
|
99
|
+
submitting: "Wird gesendet...",
|
|
100
|
+
success: "Danke für dein Feedback!",
|
|
101
|
+
loadError: "Feedback-Formular konnte nicht geladen werden",
|
|
102
|
+
invalidUrl: "Ungültige Feedback-URL",
|
|
103
|
+
emptyError: "Bitte zuerst etwas schreiben",
|
|
104
|
+
sendError: "Feedback konnte nicht gesendet werden",
|
|
105
|
+
keyboardHint: "{{shortcut}}+Enter zum Senden",
|
|
106
|
+
},
|
|
107
|
+
"ja-JP": {
|
|
108
|
+
label: "フィードバック",
|
|
109
|
+
placeholder: "良い点、問題点、変更したい点を教えてください。",
|
|
110
|
+
submit: "送信",
|
|
111
|
+
submitting: "送信中...",
|
|
112
|
+
success: "フィードバックありがとうございます。",
|
|
113
|
+
loadError: "フォームを読み込めませんでした",
|
|
114
|
+
invalidUrl: "フィードバック URL が無効です",
|
|
115
|
+
emptyError: "先に内容を入力してください",
|
|
116
|
+
sendError: "送信できませんでした",
|
|
117
|
+
keyboardHint: "{{shortcut}}+Enter で送信",
|
|
118
|
+
},
|
|
119
|
+
"ko-KR": {
|
|
120
|
+
label: "피드백",
|
|
121
|
+
placeholder: "잘 되는 점, 깨진 점, 바꾸고 싶은 점을 알려주세요.",
|
|
122
|
+
submit: "피드백 보내기",
|
|
123
|
+
submitting: "보내는 중...",
|
|
124
|
+
success: "피드백 감사합니다.",
|
|
125
|
+
loadError: "피드백 양식을 불러올 수 없습니다",
|
|
126
|
+
invalidUrl: "피드백 URL이 올바르지 않습니다",
|
|
127
|
+
emptyError: "먼저 내용을 입력해 주세요",
|
|
128
|
+
sendError: "피드백을 보낼 수 없습니다",
|
|
129
|
+
keyboardHint: "{{shortcut}}+Enter로 보내기",
|
|
130
|
+
},
|
|
131
|
+
"pt-BR": {
|
|
132
|
+
label: "Feedback",
|
|
133
|
+
placeholder: "O que funciona, quebrou ou você mudaria?",
|
|
134
|
+
submit: "Enviar feedback",
|
|
135
|
+
submitting: "Enviando...",
|
|
136
|
+
success: "Obrigado pelo feedback!",
|
|
137
|
+
loadError: "Não foi possível carregar o formulário",
|
|
138
|
+
invalidUrl: "URL de feedback inválida",
|
|
139
|
+
emptyError: "Escreva algo primeiro",
|
|
140
|
+
sendError: "Não foi possível enviar o feedback",
|
|
141
|
+
keyboardHint: "{{shortcut}}+Enter para enviar",
|
|
142
|
+
},
|
|
143
|
+
"hi-IN": {
|
|
144
|
+
label: "फ़ीडबैक",
|
|
145
|
+
placeholder: "क्या काम कर रहा है, क्या टूटा है, या आप क्या बदलना चाहेंगे?",
|
|
146
|
+
submit: "फ़ीडबैक भेजें",
|
|
147
|
+
submitting: "भेजा जा रहा है...",
|
|
148
|
+
success: "फ़ीडबैक के लिए धन्यवाद!",
|
|
149
|
+
loadError: "फ़ीडबैक फ़ॉर्म लोड नहीं हुआ",
|
|
150
|
+
invalidUrl: "फ़ीडबैक URL अमान्य है",
|
|
151
|
+
emptyError: "पहले कुछ लिखें",
|
|
152
|
+
sendError: "फ़ीडबैक भेजा नहीं जा सका",
|
|
153
|
+
keyboardHint: "भेजने के लिए {{shortcut}}+Enter",
|
|
154
|
+
},
|
|
155
|
+
"ar-SA": {
|
|
156
|
+
label: "ملاحظات",
|
|
157
|
+
placeholder: "ما الذي يعمل، وما المعطل، وما الذي تريد تغييره؟",
|
|
158
|
+
submit: "إرسال الملاحظات",
|
|
159
|
+
submitting: "جار الإرسال...",
|
|
160
|
+
success: "شكرا لملاحظاتك!",
|
|
161
|
+
loadError: "تعذر تحميل نموذج الملاحظات",
|
|
162
|
+
invalidUrl: "رابط الملاحظات غير صالح",
|
|
163
|
+
emptyError: "اكتب شيئا أولا",
|
|
164
|
+
sendError: "تعذر إرسال الملاحظات",
|
|
165
|
+
keyboardHint: "{{shortcut}}+Enter للإرسال",
|
|
166
|
+
},
|
|
167
|
+
};
|
|
34
168
|
|
|
35
169
|
function parseTarget(url: string): ParsedTarget | null {
|
|
36
170
|
try {
|
|
@@ -114,7 +248,7 @@ const honeypotStyle: CSSProperties = {
|
|
|
114
248
|
|
|
115
249
|
export function FeedbackButton({
|
|
116
250
|
variant = "sidebar",
|
|
117
|
-
label
|
|
251
|
+
label,
|
|
118
252
|
url = DEFAULT_FEEDBACK_URL,
|
|
119
253
|
className,
|
|
120
254
|
side,
|
|
@@ -128,6 +262,9 @@ export function FeedbackButton({
|
|
|
128
262
|
}: FeedbackButtonProps) {
|
|
129
263
|
const target = parseTarget(url);
|
|
130
264
|
const { session } = useSession();
|
|
265
|
+
const { locale } = useLocale();
|
|
266
|
+
const copy = FEEDBACK_COPY[locale] ?? FEEDBACK_COPY[DEFAULT_LOCALE];
|
|
267
|
+
const resolvedLabel = label ?? copy.label;
|
|
131
268
|
|
|
132
269
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
133
270
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
@@ -163,10 +300,10 @@ export function FeedbackButton({
|
|
|
163
300
|
.then((s) => setSchema(s))
|
|
164
301
|
.catch((err) => {
|
|
165
302
|
console.error("[FeedbackButton] schema load failed", err);
|
|
166
|
-
setError(
|
|
303
|
+
setError(copy.loadError);
|
|
167
304
|
});
|
|
168
305
|
} else {
|
|
169
|
-
setError(
|
|
306
|
+
setError(copy.invalidUrl);
|
|
170
307
|
}
|
|
171
308
|
const t = setTimeout(() => textareaRef.current?.focus(), 30);
|
|
172
309
|
return () => {
|
|
@@ -184,7 +321,7 @@ export function FeedbackButton({
|
|
|
184
321
|
if (!target || submitting) return;
|
|
185
322
|
const trimmed = value.trim();
|
|
186
323
|
if (!trimmed) {
|
|
187
|
-
setError(
|
|
324
|
+
setError(copy.emptyError);
|
|
188
325
|
return;
|
|
189
326
|
}
|
|
190
327
|
setSubmitting(true);
|
|
@@ -223,7 +360,7 @@ export function FeedbackButton({
|
|
|
223
360
|
closeTimerRef.current = setTimeout(() => setOpen(false), 1400);
|
|
224
361
|
} catch (err) {
|
|
225
362
|
setSubmitting(false);
|
|
226
|
-
setError(err instanceof Error ? err.message :
|
|
363
|
+
setError(err instanceof Error ? err.message : copy.sendError);
|
|
227
364
|
}
|
|
228
365
|
},
|
|
229
366
|
[
|
|
@@ -236,6 +373,8 @@ export function FeedbackButton({
|
|
|
236
373
|
chatSessionId,
|
|
237
374
|
chatStorageKey,
|
|
238
375
|
setOpen,
|
|
376
|
+
copy.emptyError,
|
|
377
|
+
copy.sendError,
|
|
239
378
|
],
|
|
240
379
|
);
|
|
241
380
|
|
|
@@ -254,7 +393,7 @@ export function FeedbackButton({
|
|
|
254
393
|
<PopoverPrimitive.Trigger asChild>
|
|
255
394
|
<button
|
|
256
395
|
type="button"
|
|
257
|
-
aria-label={
|
|
396
|
+
aria-label={resolvedLabel}
|
|
258
397
|
className={cn(
|
|
259
398
|
"flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50",
|
|
260
399
|
className,
|
|
@@ -269,7 +408,7 @@ export function FeedbackButton({
|
|
|
269
408
|
sideOffset={6}
|
|
270
409
|
className="z-[300] overflow-hidden rounded-md border border-border bg-popover px-2 py-1 text-[11px] text-foreground shadow-md animate-in fade-in-0 zoom-in-95"
|
|
271
410
|
>
|
|
272
|
-
{
|
|
411
|
+
{resolvedLabel}
|
|
273
412
|
</TooltipPrimitive.Content>
|
|
274
413
|
</TooltipPrimitive.Portal>
|
|
275
414
|
</TooltipPrimitive.Root>
|
|
@@ -280,14 +419,14 @@ export function FeedbackButton({
|
|
|
280
419
|
<PopoverPrimitive.Trigger asChild>
|
|
281
420
|
<button
|
|
282
421
|
type="button"
|
|
283
|
-
aria-label={
|
|
422
|
+
aria-label={resolvedLabel}
|
|
284
423
|
className={cn(
|
|
285
424
|
"flex h-8 items-center gap-2 rounded-md border border-border bg-transparent px-3 text-sm text-muted-foreground transition hover:border-foreground/40 hover:text-foreground",
|
|
286
425
|
className,
|
|
287
426
|
)}
|
|
288
427
|
>
|
|
289
428
|
<IconMessage2 size={14} stroke={1.5} />
|
|
290
|
-
<span>{
|
|
429
|
+
<span>{resolvedLabel}</span>
|
|
291
430
|
</button>
|
|
292
431
|
</PopoverPrimitive.Trigger>
|
|
293
432
|
);
|
|
@@ -302,14 +441,14 @@ export function FeedbackButton({
|
|
|
302
441
|
)}
|
|
303
442
|
>
|
|
304
443
|
<IconMessage2 className="h-4 w-4" />
|
|
305
|
-
<span>{
|
|
444
|
+
<span>{resolvedLabel}</span>
|
|
306
445
|
</button>
|
|
307
446
|
</PopoverPrimitive.Trigger>
|
|
308
447
|
);
|
|
309
448
|
}
|
|
310
449
|
|
|
311
450
|
const resolvedSide = side ?? (variant === "sidebar" ? "top" : "bottom");
|
|
312
|
-
const resolvedPlaceholder = placeholder ??
|
|
451
|
+
const resolvedPlaceholder = placeholder ?? copy.placeholder;
|
|
313
452
|
|
|
314
453
|
return (
|
|
315
454
|
<PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
|
|
@@ -329,7 +468,7 @@ export function FeedbackButton({
|
|
|
329
468
|
<IconCheck size={20} stroke={2.5} />
|
|
330
469
|
</div>
|
|
331
470
|
<div className="text-sm font-medium text-foreground">
|
|
332
|
-
{
|
|
471
|
+
{copy.success}
|
|
333
472
|
</div>
|
|
334
473
|
</div>
|
|
335
474
|
) : (
|
|
@@ -363,14 +502,19 @@ export function FeedbackButton({
|
|
|
363
502
|
)}
|
|
364
503
|
>
|
|
365
504
|
{error ??
|
|
366
|
-
|
|
505
|
+
copy.keyboardHint.replace(
|
|
506
|
+
"{{shortcut}}",
|
|
507
|
+
/Mac|iPhone|iPad/.test(navigator.userAgent)
|
|
508
|
+
? "⌘"
|
|
509
|
+
: "Ctrl",
|
|
510
|
+
)}
|
|
367
511
|
</div>
|
|
368
512
|
<button
|
|
369
513
|
type="submit"
|
|
370
514
|
disabled={submitting || !value.trim()}
|
|
371
515
|
className="inline-flex h-8 items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
|
|
372
516
|
>
|
|
373
|
-
{submitting ?
|
|
517
|
+
{submitting ? copy.submitting : copy.submit}
|
|
374
518
|
</button>
|
|
375
519
|
</div>
|
|
376
520
|
</form>
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "./annotation-rail.js";
|
|
28
28
|
import { CodeFilenameLabel } from "./code-filename-label.js";
|
|
29
29
|
import { DevInput, DevLabel, DevTextarea } from "./dev-doc-ui.js";
|
|
30
|
+
import { useBlockCopy } from "./block-copy.js";
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* "Explain this code" walkthrough block: a standard syntax-highlighted code
|
|
@@ -158,6 +159,7 @@ function AnnotatedCodeRead({
|
|
|
158
159
|
summary,
|
|
159
160
|
ctx,
|
|
160
161
|
}: BlockReadProps<AnnotatedCodeData>) {
|
|
162
|
+
const copy = useBlockCopy();
|
|
161
163
|
// On-hover popover (anchored to the right of the code) replaces the old
|
|
162
164
|
// persistent rail: nothing is visible when idle. `codeRef` measures the code
|
|
163
165
|
// block's right edge; `hover` carries the active index + captured geometry.
|
|
@@ -312,7 +314,11 @@ function AnnotatedCodeRead({
|
|
|
312
314
|
tabIndex={isAnnotated ? 0 : undefined}
|
|
313
315
|
role={isAnnotated ? "button" : undefined}
|
|
314
316
|
aria-expanded={isAnnotated ? isActive : undefined}
|
|
315
|
-
aria-label={
|
|
317
|
+
aria-label={
|
|
318
|
+
isAnnotated
|
|
319
|
+
? copy.lineAnnotation.replace("{{line}}", String(lineNo))
|
|
320
|
+
: undefined
|
|
321
|
+
}
|
|
316
322
|
className={cn(
|
|
317
323
|
"relative flex w-full",
|
|
318
324
|
isAnnotated && "cursor-pointer",
|
|
@@ -494,7 +500,10 @@ function AnnotatedCodeRead({
|
|
|
494
500
|
···
|
|
495
501
|
</span>
|
|
496
502
|
<span className="flex-1 text-[11px] text-plan-muted/70">
|
|
497
|
-
{
|
|
503
|
+
{copy.hiddenLinesExpand.replace(
|
|
504
|
+
"{{count}}",
|
|
505
|
+
String(hiddenCount),
|
|
506
|
+
)}
|
|
498
507
|
</span>
|
|
499
508
|
</button>
|
|
500
509
|
);
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
API_ENDPOINT_METHODS,
|
|
23
23
|
API_PARAM_LOCATIONS,
|
|
24
24
|
} from "./api-endpoint.config.js";
|
|
25
|
+
import { useBlockCopy } from "./block-copy.js";
|
|
25
26
|
import { JsonExplorerSurface } from "./JsonExplorerBlock.js";
|
|
26
27
|
import {
|
|
27
28
|
DevBadge,
|
|
@@ -127,31 +128,33 @@ const CHANGE_INK: Record<ApiEndpointChange, string> = {
|
|
|
127
128
|
*/
|
|
128
129
|
function ChangeChip({
|
|
129
130
|
change,
|
|
131
|
+
label = CHANGE_LABEL[change],
|
|
130
132
|
variant = "glyph",
|
|
131
133
|
className,
|
|
132
134
|
}: {
|
|
133
135
|
change: ApiEndpointChange;
|
|
136
|
+
label?: string;
|
|
134
137
|
variant?: "glyph" | "label";
|
|
135
138
|
className?: string;
|
|
136
139
|
}) {
|
|
137
140
|
if (variant === "label") {
|
|
138
141
|
return (
|
|
139
142
|
<span
|
|
140
|
-
title={
|
|
143
|
+
title={label}
|
|
141
144
|
className={cn(
|
|
142
145
|
"shrink-0 rounded px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide",
|
|
143
146
|
CHANGE_BADGE[change],
|
|
144
147
|
className,
|
|
145
148
|
)}
|
|
146
149
|
>
|
|
147
|
-
{
|
|
150
|
+
{label}
|
|
148
151
|
</span>
|
|
149
152
|
);
|
|
150
153
|
}
|
|
151
154
|
return (
|
|
152
155
|
<span
|
|
153
|
-
title={
|
|
154
|
-
aria-label={
|
|
156
|
+
title={label}
|
|
157
|
+
aria-label={label}
|
|
155
158
|
className={cn(
|
|
156
159
|
"flex size-4 shrink-0 items-center justify-center rounded text-[10px] font-bold leading-none",
|
|
157
160
|
CHANGE_BADGE[change],
|
|
@@ -402,6 +405,13 @@ export function ApiEndpointRead({
|
|
|
402
405
|
ctx,
|
|
403
406
|
}: BlockReadProps<ApiEndpointData>) {
|
|
404
407
|
const [open, setOpen] = useState(false);
|
|
408
|
+
const copy = useBlockCopy();
|
|
409
|
+
const changeLabel: Record<ApiEndpointChange, string> = {
|
|
410
|
+
added: copy.added,
|
|
411
|
+
modified: copy.modified,
|
|
412
|
+
removed: copy.removed,
|
|
413
|
+
renamed: copy.renamed,
|
|
414
|
+
};
|
|
405
415
|
|
|
406
416
|
const params = data.params ?? [];
|
|
407
417
|
const responses = data.responses ?? [];
|
|
@@ -467,10 +477,16 @@ export function ApiEndpointRead({
|
|
|
467
477
|
>
|
|
468
478
|
{data.path}
|
|
469
479
|
</span>
|
|
470
|
-
{data.change &&
|
|
480
|
+
{data.change && (
|
|
481
|
+
<ChangeChip
|
|
482
|
+
change={data.change}
|
|
483
|
+
label={changeLabel[data.change]}
|
|
484
|
+
variant="label"
|
|
485
|
+
/>
|
|
486
|
+
)}
|
|
471
487
|
{data.deprecated && (
|
|
472
488
|
<DevBadge className="shrink-0 border-amber-500/40 text-amber-600 dark:text-amber-300">
|
|
473
|
-
|
|
489
|
+
{copy.deprecated}
|
|
474
490
|
</DevBadge>
|
|
475
491
|
)}
|
|
476
492
|
{(data.summary || summary) && (
|
|
@@ -481,7 +497,7 @@ export function ApiEndpointRead({
|
|
|
481
497
|
{data.auth && (
|
|
482
498
|
<IconLock
|
|
483
499
|
className="size-3.5 shrink-0 text-plan-muted"
|
|
484
|
-
aria-label=
|
|
500
|
+
aria-label={copy.requiresAuthentication}
|
|
485
501
|
/>
|
|
486
502
|
)}
|
|
487
503
|
</button>
|
|
@@ -495,7 +511,9 @@ export function ApiEndpointRead({
|
|
|
495
511
|
<div className="mb-4 flex items-center gap-2 text-xs text-plan-muted">
|
|
496
512
|
<IconLock className="size-3.5 shrink-0" />
|
|
497
513
|
<span>
|
|
498
|
-
<span className="font-medium text-plan-text">
|
|
514
|
+
<span className="font-medium text-plan-text">
|
|
515
|
+
{copy.auth}:
|
|
516
|
+
</span>{" "}
|
|
499
517
|
{data.auth}
|
|
500
518
|
</span>
|
|
501
519
|
</div>
|
|
@@ -510,17 +528,21 @@ export function ApiEndpointRead({
|
|
|
510
528
|
{params.length > 0 && (
|
|
511
529
|
<div className="mt-5">
|
|
512
530
|
<div className="text-xs font-semibold uppercase tracking-wide text-plan-muted">
|
|
513
|
-
|
|
531
|
+
{copy.parameters}
|
|
514
532
|
</div>
|
|
515
533
|
<div className="mt-2 overflow-hidden rounded-lg border border-plan-line">
|
|
516
534
|
<table className="w-full border-collapse text-sm">
|
|
517
535
|
<thead>
|
|
518
536
|
<tr className="bg-accent/30 text-left text-xs uppercase tracking-wide text-plan-muted">
|
|
519
|
-
<th className="px-3 py-2 font-medium">
|
|
520
|
-
<th className="px-3 py-2 font-medium">
|
|
521
|
-
<th className="px-3 py-2 font-medium">
|
|
522
|
-
<th className="px-3 py-2 font-medium">
|
|
523
|
-
|
|
537
|
+
<th className="px-3 py-2 font-medium">{copy.name}</th>
|
|
538
|
+
<th className="px-3 py-2 font-medium">{copy.in}</th>
|
|
539
|
+
<th className="px-3 py-2 font-medium">{copy.type}</th>
|
|
540
|
+
<th className="px-3 py-2 font-medium">
|
|
541
|
+
{copy.requiredColumn}
|
|
542
|
+
</th>
|
|
543
|
+
<th className="px-3 py-2 font-medium">
|
|
544
|
+
{copy.description}
|
|
545
|
+
</th>
|
|
524
546
|
</tr>
|
|
525
547
|
</thead>
|
|
526
548
|
<tbody>
|
|
@@ -556,7 +578,12 @@ export function ApiEndpointRead({
|
|
|
556
578
|
>
|
|
557
579
|
{param.name}
|
|
558
580
|
</span>
|
|
559
|
-
{change &&
|
|
581
|
+
{change && (
|
|
582
|
+
<ChangeChip
|
|
583
|
+
change={change}
|
|
584
|
+
label={changeLabel[change]}
|
|
585
|
+
/>
|
|
586
|
+
)}
|
|
560
587
|
</span>
|
|
561
588
|
</td>
|
|
562
589
|
<td className="px-3 py-2">
|
|
@@ -589,11 +616,11 @@ export function ApiEndpointRead({
|
|
|
589
616
|
current={
|
|
590
617
|
param.required ? (
|
|
591
618
|
<span className="font-medium text-red-600 dark:text-red-300">
|
|
592
|
-
required
|
|
619
|
+
{copy.required}
|
|
593
620
|
</span>
|
|
594
621
|
) : (
|
|
595
622
|
<span className="text-plan-muted">
|
|
596
|
-
optional
|
|
623
|
+
{copy.optional}
|
|
597
624
|
</span>
|
|
598
625
|
)
|
|
599
626
|
}
|
|
@@ -615,7 +642,7 @@ export function ApiEndpointRead({
|
|
|
615
642
|
<div className="mt-5">
|
|
616
643
|
<div className="flex items-center gap-2">
|
|
617
644
|
<span className="text-xs font-semibold uppercase tracking-wide text-plan-muted">
|
|
618
|
-
|
|
645
|
+
{copy.requestBody}
|
|
619
646
|
</span>
|
|
620
647
|
{data.request?.contentType && (
|
|
621
648
|
<span className="rounded bg-accent/40 px-1.5 py-0.5 font-mono text-[11px] text-plan-muted">
|
|
@@ -636,7 +663,7 @@ export function ApiEndpointRead({
|
|
|
636
663
|
{responses.length > 0 && (
|
|
637
664
|
<div className="mt-5">
|
|
638
665
|
<div className="text-xs font-semibold uppercase tracking-wide text-plan-muted">
|
|
639
|
-
|
|
666
|
+
{copy.responses}
|
|
640
667
|
</div>
|
|
641
668
|
<div className="mt-2 flex flex-col gap-3">
|
|
642
669
|
{responses.map((response, index) => (
|
|
@@ -5,6 +5,7 @@ import type { BlockEditProps, BlockReadProps } from "../types.js";
|
|
|
5
5
|
import type { MermaidData } from "./mermaid.config.js";
|
|
6
6
|
import { DevInput, DevLabel } from "./dev-doc-ui.js";
|
|
7
7
|
import { DiagramLightbox } from "./diagram.js";
|
|
8
|
+
import { useBlockCopy } from "./block-copy.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Read + Edit renderers for a `mermaid` block — a Mermaid diagram definition
|
|
@@ -163,6 +164,7 @@ function MermaidDiagram({
|
|
|
163
164
|
idSeed: string;
|
|
164
165
|
}) {
|
|
165
166
|
const isDark = useIsDark();
|
|
167
|
+
const copy = useBlockCopy();
|
|
166
168
|
// Only render the diagram after mount: `mermaid` is client-only and SSR has no
|
|
167
169
|
// DOM for it to measure against.
|
|
168
170
|
const [mounted, setMounted] = useState(false);
|
|
@@ -225,7 +227,7 @@ function MermaidDiagram({
|
|
|
225
227
|
if (!mounted) {
|
|
226
228
|
return (
|
|
227
229
|
<div className="mt-2 flex min-h-24 items-center justify-center rounded-lg border border-plan-line bg-plan-code text-sm text-plan-muted">
|
|
228
|
-
|
|
230
|
+
{copy.loadingDiagram}
|
|
229
231
|
</div>
|
|
230
232
|
);
|
|
231
233
|
}
|
|
@@ -237,7 +239,7 @@ function MermaidDiagram({
|
|
|
237
239
|
{source}
|
|
238
240
|
</pre>
|
|
239
241
|
<p className="text-sm text-plan-muted">
|
|
240
|
-
|
|
242
|
+
{copy.couldNotRenderDiagram}: {state.error}
|
|
241
243
|
</p>
|
|
242
244
|
</div>
|
|
243
245
|
);
|
|
@@ -246,7 +248,7 @@ function MermaidDiagram({
|
|
|
246
248
|
if (!state.svg) {
|
|
247
249
|
return (
|
|
248
250
|
<div className="mt-2 flex min-h-24 items-center justify-center rounded-lg border border-plan-line bg-plan-code text-sm text-plan-muted">
|
|
249
|
-
|
|
251
|
+
{copy.addDiagramDefinition}
|
|
250
252
|
</div>
|
|
251
253
|
);
|
|
252
254
|
}
|
|
@@ -263,8 +265,8 @@ function MermaidDiagram({
|
|
|
263
265
|
type="button"
|
|
264
266
|
data-plan-interactive
|
|
265
267
|
onClick={() => setExpanded(true)}
|
|
266
|
-
aria-label=
|
|
267
|
-
title=
|
|
268
|
+
aria-label={copy.expandDiagram}
|
|
269
|
+
title={copy.expandDiagram}
|
|
268
270
|
className="an-diagram-expand-trigger absolute right-2 top-2 z-10 flex size-7 items-center justify-center rounded-md border border-border/60 bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/mermaid:opacity-100"
|
|
269
271
|
>
|
|
270
272
|
<IconArrowsMaximize className="size-4" />
|