@agent-native/core 0.98.3 → 0.98.5
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 +29 -0
- package/corpus/core/docs/content/durable-background-runs.mdx +37 -0
- package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/de-DE/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/es-ES/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +4 -2
- package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +2 -0
- package/corpus/core/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
- package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +2 -0
- package/corpus/core/docs/content/tracking.mdx +2 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +16 -16
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +25 -8
- package/corpus/core/src/agent/engine/anthropic-engine.ts +17 -3
- package/corpus/core/src/agent/engine/output-tokens.ts +6 -6
- package/corpus/core/src/agent/production-agent.ts +200 -27
- package/corpus/core/src/agent/run-manager.ts +81 -1
- package/corpus/core/src/agent/run-store.ts +301 -41
- package/corpus/core/src/client/AgentPanel.tsx +6 -2
- package/corpus/core/src/client/AssistantChat.tsx +364 -69
- package/corpus/core/src/client/agent-chat-adapter.ts +169 -1
- package/corpus/core/src/client/analytics.ts +12 -0
- package/corpus/core/src/client/chat/message-components.tsx +3 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +20 -36
- package/corpus/core/src/client/conversation/use-near-bottom-autoscroll.ts +7 -0
- package/corpus/core/src/client/extensions/AgentNativeExtensionFrame.tsx +2 -0
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +2 -0
- package/corpus/core/src/client/extensions/ExtensionEditor.tsx +9 -2
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +2 -0
- package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +2 -0
- package/corpus/core/src/client/extensions/portable-extension.ts +2 -0
- package/corpus/core/src/client/session-replay.ts +971 -53
- package/corpus/core/src/client/settings/DemoModeSection.tsx +3 -3
- package/corpus/core/src/client/sse-event-processor.ts +43 -1
- package/corpus/core/src/demo/actions/toggle-demo-mode.ts +2 -2
- package/corpus/core/src/demo/config.ts +6 -6
- package/corpus/core/src/demo/fetch-interceptor.ts +34 -2
- package/corpus/core/src/demo/redact.ts +71 -158
- package/corpus/core/src/extensions/html-shell.ts +3 -0
- package/corpus/core/src/extensions/session-replay-iframe.ts +131 -0
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -20
- package/corpus/core/src/session-replay-iframe-protocol.ts +58 -0
- package/corpus/core/src/shared/reasoning-effort.ts +35 -0
- package/corpus/core/src/styles/agent-conversation.css +26 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +67 -16
- package/corpus/templates/analytics/AGENTS.md +12 -0
- package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-events.ts +1 -0
- package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +1 -0
- package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -1
- package/corpus/templates/analytics/app/global.css +6 -64
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +41 -4
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +143 -121
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +34 -12
- package/corpus/templates/analytics/changelog/2026-07-12-analytics-chat-retries-before-showing-a-generic-no-data-mess.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-analytics-sessions-search-no-longer-loses-fast-keystrokes-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-chart-selection-respects-chat-state.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-demo-mode-anonymizes-error-reporting-emails.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-fixed-session-replays-that-appeared-ultra-wide-hid-recorded-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-session-replays-load-faster-in-demo-mode-while-visitor-email.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-session-replays-show-iframe-content.md +6 -0
- package/corpus/templates/analytics/netlify.toml +0 -3
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +14 -0
- package/corpus/templates/analytics/server/lib/error-capture.ts +59 -2
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +24 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +2 -9
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +39 -6
- package/corpus/templates/assets/app/global.css +1 -1
- package/corpus/templates/brain/app/global.css +2 -2
- package/corpus/templates/brain/changelog/2026-07-12-fix-long-response-progress.md +6 -0
- package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +11 -2
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +14 -2
- package/corpus/templates/calendar/changelog/2026-07-12-calendar-responses-can-now-be-saved-with-command-enter-or-ct.md +6 -0
- package/corpus/templates/forms/app/components/CloudUpgrade.tsx +1 -1
- package/corpus/templates/forms/app/components/ThemeToggle.tsx +22 -6
- package/corpus/templates/forms/app/components/builder/FieldPropertiesPanel.tsx +5 -5
- package/corpus/templates/forms/app/components/builder/FieldRenderer.tsx +3 -3
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +16 -16
- package/corpus/templates/forms/app/global.css +110 -5
- package/corpus/templates/forms/app/pages/AskPage.tsx +3 -3
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +134 -52
- package/corpus/templates/forms/app/pages/FormFillPage.tsx +44 -11
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +42 -24
- package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +28 -15
- package/corpus/templates/forms/app/pages/ResponsesPage.tsx +38 -15
- package/corpus/templates/forms/app/routes/_app.settings.tsx +1 -1
- package/corpus/templates/forms/changelog/2026-07-12-form-builder-surfaces-are-calmer-fields-stay-stable-on-hover.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-smoother-more-tactile-controls-throughout-animated-icon-and-.md +6 -0
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +21 -13
- package/corpus/templates/mail/app/components/email/email-iframe-document.ts +18 -0
- package/dist/agent/durable-background.d.ts +10 -10
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +16 -16
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +19 -8
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +11 -3
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/output-tokens.js +6 -6
- package/dist/agent/engine/output-tokens.js.map +1 -1
- package/dist/agent/production-agent.d.ts +52 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +154 -26
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +9 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +71 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +9 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +243 -48
- package/dist/agent/run-store.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +21 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +298 -67
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +146 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +11 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +2 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +13 -37
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +1 -0
- package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
- package/dist/client/conversation/use-near-bottom-autoscroll.js +6 -0
- package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.js +2 -1
- package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +2 -1
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionEditor.js +5 -2
- package/dist/client/extensions/ExtensionEditor.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +2 -1
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.js +2 -1
- package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
- package/dist/client/extensions/portable-extension.d.ts.map +1 -1
- package/dist/client/extensions/portable-extension.js +2 -0
- package/dist/client/extensions/portable-extension.js.map +1 -1
- package/dist/client/session-replay.d.ts +12 -3
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +793 -49
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/DemoModeSection.js +1 -1
- package/dist/client/settings/DemoModeSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +5 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +37 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/demo/actions/toggle-demo-mode.js +2 -2
- package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
- package/dist/demo/config.js +6 -6
- package/dist/demo/config.js.map +1 -1
- package/dist/demo/fetch-interceptor.d.ts +1 -0
- package/dist/demo/fetch-interceptor.d.ts.map +1 -1
- package/dist/demo/fetch-interceptor.js +28 -2
- package/dist/demo/fetch-interceptor.js.map +1 -1
- package/dist/demo/redact.d.ts +14 -7
- package/dist/demo/redact.d.ts.map +1 -1
- package/dist/demo/redact.js +27 -155
- package/dist/demo/redact.js.map +1 -1
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js +2 -0
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/extensions/session-replay-iframe.d.ts +10 -0
- package/dist/extensions/session-replay-iframe.d.ts.map +1 -0
- package/dist/extensions/session-replay-iframe.js +121 -0
- package/dist/extensions/session-replay-iframe.js.map +1 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +1 -19
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/session-replay-iframe-protocol.d.ts +36 -0
- package/dist/session-replay-iframe-protocol.d.ts.map +1 -0
- package/dist/session-replay-iframe-protocol.js +24 -0
- package/dist/session-replay-iframe-protocol.js.map +1 -0
- package/dist/shared/reasoning-effort.d.ts +11 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +36 -0
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/styles/agent-conversation.css +26 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/docs/content/durable-background-runs.mdx +37 -0
- package/docs/content/locales/ar-SA/tracking.mdx +2 -0
- package/docs/content/locales/de-DE/tracking.mdx +2 -0
- package/docs/content/locales/es-ES/tracking.mdx +2 -0
- package/docs/content/locales/fr-FR/tracking.mdx +4 -2
- package/docs/content/locales/hi-IN/tracking.mdx +2 -0
- package/docs/content/locales/ja-JP/tracking.mdx +2 -0
- package/docs/content/locales/ko-KR/tracking.mdx +2 -0
- package/docs/content/locales/pt-BR/tracking.mdx +2 -0
- package/docs/content/locales/zh-CN/tracking.mdx +2 -0
- package/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
- package/docs/content/locales/zh-TW/tracking.mdx +2 -0
- package/docs/content/tracking.mdx +2 -0
- package/package.json +2 -2
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
- package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
- package/dist/observability/hosted-model-experiment.d.ts +0 -39
- package/dist/observability/hosted-model-experiment.d.ts.map +0 -1
- package/dist/observability/hosted-model-experiment.js +0 -90
- package/dist/observability/hosted-model-experiment.js.map +0 -1
|
@@ -187,8 +187,8 @@ export function FormFillPage() {
|
|
|
187
187
|
|
|
188
188
|
if (isLoading) {
|
|
189
189
|
return (
|
|
190
|
-
<div className="min-h-screen bg-
|
|
191
|
-
<div className="max-w-xl
|
|
190
|
+
<div className="min-h-screen bg-muted/30 px-4 py-10">
|
|
191
|
+
<div className="mx-auto max-w-xl space-y-6 rounded-2xl border border-border/80 bg-background p-5 shadow-sm sm:p-8">
|
|
192
192
|
<div className="space-y-3">
|
|
193
193
|
<Skeleton className="h-8 w-2/3" />
|
|
194
194
|
<Skeleton className="h-4 w-full" />
|
|
@@ -210,8 +210,19 @@ export function FormFillPage() {
|
|
|
210
210
|
|
|
211
211
|
if (error || !form) {
|
|
212
212
|
return (
|
|
213
|
-
<div
|
|
214
|
-
|
|
213
|
+
<div
|
|
214
|
+
className={cn(
|
|
215
|
+
"flex min-h-screen items-center justify-center p-4",
|
|
216
|
+
embedded ? "bg-background" : "bg-muted/30",
|
|
217
|
+
)}
|
|
218
|
+
>
|
|
219
|
+
<div
|
|
220
|
+
className={cn(
|
|
221
|
+
"text-center",
|
|
222
|
+
!embedded &&
|
|
223
|
+
"max-w-md rounded-2xl border border-border/80 bg-background p-8 shadow-sm sm:p-10",
|
|
224
|
+
)}
|
|
225
|
+
>
|
|
215
226
|
<h1 className="text-2xl font-semibold mb-2">
|
|
216
227
|
{t("publicForm.formNotFound")}
|
|
217
228
|
</h1>
|
|
@@ -222,7 +233,7 @@ export function FormFillPage() {
|
|
|
222
233
|
variant="outline"
|
|
223
234
|
size="sm"
|
|
224
235
|
onClick={() => window.location.reload()}
|
|
225
|
-
className="gap-2"
|
|
236
|
+
className="min-h-10 gap-2 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
226
237
|
>
|
|
227
238
|
<IconRefresh className="h-3.5 w-3.5" />
|
|
228
239
|
{t("publicForm.tryAgain")}
|
|
@@ -235,8 +246,19 @@ export function FormFillPage() {
|
|
|
235
246
|
|
|
236
247
|
if (submitted) {
|
|
237
248
|
return (
|
|
238
|
-
<div
|
|
239
|
-
|
|
249
|
+
<div
|
|
250
|
+
className={cn(
|
|
251
|
+
"flex min-h-screen items-center justify-center p-4",
|
|
252
|
+
embedded ? "bg-background" : "bg-muted/30",
|
|
253
|
+
)}
|
|
254
|
+
>
|
|
255
|
+
<div
|
|
256
|
+
className={cn(
|
|
257
|
+
"max-w-md text-center",
|
|
258
|
+
!embedded &&
|
|
259
|
+
"rounded-2xl border border-border/80 bg-background p-8 shadow-sm sm:p-10",
|
|
260
|
+
)}
|
|
261
|
+
>
|
|
240
262
|
<div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-emerald-600/10">
|
|
241
263
|
<IconCircleCheck className="h-7 w-7 text-emerald-600 dark:text-emerald-400" />
|
|
242
264
|
</div>
|
|
@@ -254,11 +276,22 @@ export function FormFillPage() {
|
|
|
254
276
|
}
|
|
255
277
|
|
|
256
278
|
return (
|
|
257
|
-
<div
|
|
258
|
-
|
|
279
|
+
<div
|
|
280
|
+
className={cn(
|
|
281
|
+
"flex min-h-screen items-center justify-center p-3 sm:p-4 py-8 sm:py-12",
|
|
282
|
+
embedded ? "bg-background" : "bg-muted/30",
|
|
283
|
+
)}
|
|
284
|
+
>
|
|
285
|
+
<div
|
|
286
|
+
className={cn(
|
|
287
|
+
"w-full max-w-2xl",
|
|
288
|
+
!embedded &&
|
|
289
|
+
"rounded-2xl border border-border/80 bg-background p-5 shadow-sm sm:p-8",
|
|
290
|
+
)}
|
|
291
|
+
>
|
|
259
292
|
{!embedded && (
|
|
260
293
|
<div className="mb-3 flex justify-end">
|
|
261
|
-
<ThemeToggle className="h-
|
|
294
|
+
<ThemeToggle className="h-10 w-10 transition-[scale,background-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none" />
|
|
262
295
|
</div>
|
|
263
296
|
)}
|
|
264
297
|
{/* Form header */}
|
|
@@ -320,7 +353,7 @@ export function FormFillPage() {
|
|
|
320
353
|
|
|
321
354
|
<Button
|
|
322
355
|
type="submit"
|
|
323
|
-
className="mt-4 w-full sm:w-auto"
|
|
356
|
+
className="mt-4 min-h-11 w-full transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none sm:w-auto"
|
|
324
357
|
size="lg"
|
|
325
358
|
disabled={submitForm.isPending}
|
|
326
359
|
>
|
|
@@ -118,7 +118,7 @@ export function FormsListPage() {
|
|
|
118
118
|
<Button
|
|
119
119
|
onClick={handleCreate}
|
|
120
120
|
size="sm"
|
|
121
|
-
className="shrink-0 cursor-pointer"
|
|
121
|
+
className="min-h-10 shrink-0 cursor-pointer active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
122
122
|
>
|
|
123
123
|
<IconPlus className="h-3.5 w-3.5" />
|
|
124
124
|
<span className="hidden sm:inline">{t("forms.newForm")}</span>
|
|
@@ -269,7 +269,7 @@ export function FormsListPage() {
|
|
|
269
269
|
if (isLoading) {
|
|
270
270
|
return (
|
|
271
271
|
<div className="p-3 sm:p-6 max-w-5xl mx-auto">
|
|
272
|
-
<div className="
|
|
272
|
+
<div className="forms-list-shell overflow-hidden bg-card">
|
|
273
273
|
{Array.from({ length: 6 }).map((_, i) => (
|
|
274
274
|
<div
|
|
275
275
|
key={i}
|
|
@@ -280,8 +280,10 @@ export function FormsListPage() {
|
|
|
280
280
|
<Skeleton className="h-3 w-1/2" />
|
|
281
281
|
</div>
|
|
282
282
|
<Skeleton className="h-5 w-20 rounded-full" />
|
|
283
|
+
<Skeleton className="h-5 w-20 rounded-full" />
|
|
284
|
+
<Skeleton className="h-4 w-24" />
|
|
283
285
|
<Skeleton className="h-4 w-24" />
|
|
284
|
-
<Skeleton className="h-
|
|
286
|
+
<Skeleton className="h-10 w-10 rounded-lg md:ms-auto" />
|
|
285
287
|
</div>
|
|
286
288
|
))}
|
|
287
289
|
</div>
|
|
@@ -300,6 +302,7 @@ export function FormsListPage() {
|
|
|
300
302
|
<Button
|
|
301
303
|
variant="outline"
|
|
302
304
|
size="sm"
|
|
305
|
+
className="min-h-10 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
303
306
|
onClick={() => {
|
|
304
307
|
const next = encodeURIComponent(
|
|
305
308
|
window.location.pathname + window.location.search,
|
|
@@ -322,8 +325,8 @@ export function FormsListPage() {
|
|
|
322
325
|
<Button
|
|
323
326
|
variant="outline"
|
|
324
327
|
size="sm"
|
|
328
|
+
className="min-h-10 gap-2 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
325
329
|
onClick={() => refetch()}
|
|
326
|
-
className="gap-2"
|
|
327
330
|
>
|
|
328
331
|
<IconRefresh className="h-3.5 w-3.5" />
|
|
329
332
|
{t("common.retry")}
|
|
@@ -344,11 +347,17 @@ export function FormsListPage() {
|
|
|
344
347
|
value={view}
|
|
345
348
|
onValueChange={(v) => setView(v as "active" | "archive")}
|
|
346
349
|
>
|
|
347
|
-
<TabsList>
|
|
348
|
-
<TabsTrigger
|
|
350
|
+
<TabsList className="h-12">
|
|
351
|
+
<TabsTrigger
|
|
352
|
+
value="active"
|
|
353
|
+
className="min-h-10 gap-1.5 text-xs active:scale-[0.96] transition-[background-color,box-shadow,color,transform]"
|
|
354
|
+
>
|
|
349
355
|
{t("header.forms")}
|
|
350
356
|
</TabsTrigger>
|
|
351
|
-
<TabsTrigger
|
|
357
|
+
<TabsTrigger
|
|
358
|
+
value="archive"
|
|
359
|
+
className="min-h-10 gap-1.5 text-xs active:scale-[0.96] transition-[background-color,box-shadow,color,transform]"
|
|
360
|
+
>
|
|
352
361
|
<IconArchive className="h-3.5 w-3.5" />
|
|
353
362
|
{t("forms.archive")}
|
|
354
363
|
</TabsTrigger>
|
|
@@ -359,7 +368,7 @@ export function FormsListPage() {
|
|
|
359
368
|
<Button
|
|
360
369
|
variant={selectionMode ? "secondary" : "ghost"}
|
|
361
370
|
size="sm"
|
|
362
|
-
className="h-
|
|
371
|
+
className="min-h-10 gap-1.5 text-xs active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
363
372
|
onClick={() => {
|
|
364
373
|
setSelectionMode((current) => {
|
|
365
374
|
if (current) setSelectedIds(new Set());
|
|
@@ -374,7 +383,7 @@ export function FormsListPage() {
|
|
|
374
383
|
</div>
|
|
375
384
|
|
|
376
385
|
{selectionMode && forms.length > 0 && (
|
|
377
|
-
<div className="mb-4 flex flex-wrap items-center gap-2 rounded-
|
|
386
|
+
<div className="forms-selection-toolbar mb-4 flex flex-wrap items-center gap-2 rounded-xl bg-muted/30 px-3 py-2">
|
|
378
387
|
<span className="text-xs font-medium text-foreground">
|
|
379
388
|
{t("forms.selectedCount", {
|
|
380
389
|
count: selectedCount,
|
|
@@ -385,7 +394,7 @@ export function FormsListPage() {
|
|
|
385
394
|
<Button
|
|
386
395
|
variant="ghost"
|
|
387
396
|
size="sm"
|
|
388
|
-
className="h-
|
|
397
|
+
className="min-h-10 text-xs active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
389
398
|
onClick={toggleSelectAll}
|
|
390
399
|
>
|
|
391
400
|
{allFormsSelected ? t("common.clearAll") : t("common.selectAll")}
|
|
@@ -393,7 +402,7 @@ export function FormsListPage() {
|
|
|
393
402
|
<Button
|
|
394
403
|
variant="ghost"
|
|
395
404
|
size="sm"
|
|
396
|
-
className="h-
|
|
405
|
+
className="min-h-10 gap-1.5 text-xs text-destructive hover:text-destructive active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
397
406
|
onClick={() =>
|
|
398
407
|
isArchive ? setBulkPurgeOpen(true) : handleBulkDelete(false)
|
|
399
408
|
}
|
|
@@ -405,7 +414,7 @@ export function FormsListPage() {
|
|
|
405
414
|
<Button
|
|
406
415
|
variant="ghost"
|
|
407
416
|
size="icon"
|
|
408
|
-
className="ms-auto
|
|
417
|
+
className="relative ms-auto size-10 transition-[background-color,box-shadow,transform] active:scale-[0.96] sm:size-8 sm:before:absolute sm:before:-inset-1 sm:before:content-['']"
|
|
409
418
|
onClick={clearSelection}
|
|
410
419
|
aria-label={t("forms.exitSelectionMode")}
|
|
411
420
|
>
|
|
@@ -415,7 +424,7 @@ export function FormsListPage() {
|
|
|
415
424
|
)}
|
|
416
425
|
|
|
417
426
|
{forms.length === 0 ? (
|
|
418
|
-
<div className="flex flex-col items-center justify-center
|
|
427
|
+
<div className="forms-empty-state flex flex-col items-center justify-center rounded-xl border border-dashed border-border bg-card py-20">
|
|
419
428
|
{isArchive ? (
|
|
420
429
|
<>
|
|
421
430
|
<h3 className="font-medium mb-1">
|
|
@@ -431,7 +440,11 @@ export function FormsListPage() {
|
|
|
431
440
|
<p className="text-sm text-muted-foreground mb-4">
|
|
432
441
|
{t("forms.emptyDescription")}
|
|
433
442
|
</p>
|
|
434
|
-
<Button
|
|
443
|
+
<Button
|
|
444
|
+
onClick={handleCreate}
|
|
445
|
+
size="sm"
|
|
446
|
+
className="min-h-10 gap-2 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
447
|
+
>
|
|
435
448
|
<IconPlus className="h-4 w-4" />
|
|
436
449
|
{t("forms.createForm")}
|
|
437
450
|
</Button>
|
|
@@ -439,7 +452,7 @@ export function FormsListPage() {
|
|
|
439
452
|
)}
|
|
440
453
|
</div>
|
|
441
454
|
) : (
|
|
442
|
-
<div className="
|
|
455
|
+
<div className="forms-list-shell overflow-hidden bg-card">
|
|
443
456
|
{forms.map((form: any) => {
|
|
444
457
|
const selected = selectedIds.has(form.id);
|
|
445
458
|
const dateLabel =
|
|
@@ -515,10 +528,6 @@ export function FormsListPage() {
|
|
|
515
528
|
<h3 className="min-w-0 flex-1 truncate text-sm font-medium">
|
|
516
529
|
{form.title}
|
|
517
530
|
</h3>
|
|
518
|
-
<VisibilityBadge
|
|
519
|
-
visibility={(form as any).visibility}
|
|
520
|
-
className="shrink-0"
|
|
521
|
-
/>
|
|
522
531
|
</div>
|
|
523
532
|
{form.description && (
|
|
524
533
|
<p className="mt-0.5 truncate text-xs text-muted-foreground">
|
|
@@ -528,6 +537,10 @@ export function FormsListPage() {
|
|
|
528
537
|
</div>
|
|
529
538
|
</div>
|
|
530
539
|
|
|
540
|
+
<div className="flex min-w-0 items-center">
|
|
541
|
+
<VisibilityBadge visibility={(form as any).visibility} />
|
|
542
|
+
</div>
|
|
543
|
+
|
|
531
544
|
<div className="flex items-center md:justify-start">
|
|
532
545
|
<Badge
|
|
533
546
|
variant="outline"
|
|
@@ -558,7 +571,7 @@ export function FormsListPage() {
|
|
|
558
571
|
<Button
|
|
559
572
|
variant="ghost"
|
|
560
573
|
size="sm"
|
|
561
|
-
className="
|
|
574
|
+
className="relative size-10 rounded-lg p-0 transition-[background-color,opacity,transform] duration-150 ease-out active:scale-[0.96] focus:opacity-100 sm:size-8 sm:opacity-0 sm:before:absolute sm:before:-inset-1 sm:before:content-[''] sm:group-hover:opacity-100"
|
|
562
575
|
aria-label={t("forms.formActions")}
|
|
563
576
|
>
|
|
564
577
|
<IconDots className="h-4 w-4" />
|
|
@@ -695,10 +708,12 @@ export function FormsListPage() {
|
|
|
695
708
|
</AlertDialogDescription>
|
|
696
709
|
</AlertDialogHeader>
|
|
697
710
|
<AlertDialogFooter>
|
|
698
|
-
<AlertDialogCancel
|
|
711
|
+
<AlertDialogCancel className="min-h-10 active:scale-[0.96] transition-[background-color,box-shadow,transform]">
|
|
712
|
+
{t("common.cancel")}
|
|
713
|
+
</AlertDialogCancel>
|
|
699
714
|
<AlertDialogAction
|
|
700
715
|
onClick={handlePurge}
|
|
701
|
-
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
716
|
+
className="min-h-10 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
702
717
|
>
|
|
703
718
|
{t("forms.deleteForever")}
|
|
704
719
|
</AlertDialogAction>
|
|
@@ -718,13 +733,16 @@ export function FormsListPage() {
|
|
|
718
733
|
</AlertDialogDescription>
|
|
719
734
|
</AlertDialogHeader>
|
|
720
735
|
<AlertDialogFooter>
|
|
721
|
-
<AlertDialogCancel
|
|
736
|
+
<AlertDialogCancel
|
|
737
|
+
disabled={bulkDeletePending}
|
|
738
|
+
className="min-h-10 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
739
|
+
>
|
|
722
740
|
{t("common.cancel")}
|
|
723
741
|
</AlertDialogCancel>
|
|
724
742
|
<AlertDialogAction
|
|
725
743
|
onClick={() => handleBulkDelete(true)}
|
|
726
744
|
disabled={bulkDeletePending}
|
|
727
|
-
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
745
|
+
className="min-h-10 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.96] transition-[background-color,box-shadow,transform]"
|
|
728
746
|
>
|
|
729
747
|
{t("forms.deleteForever")}
|
|
730
748
|
</AlertDialogAction>
|
|
@@ -52,7 +52,7 @@ function Metric({
|
|
|
52
52
|
detail?: string;
|
|
53
53
|
}) {
|
|
54
54
|
return (
|
|
55
|
-
<div className="min-w-0 rounded-
|
|
55
|
+
<div className="min-w-0 rounded-xl border border-border/80 bg-background px-3 py-3 shadow-sm">
|
|
56
56
|
<div className="text-[11px] font-medium uppercase tracking-normal text-muted-foreground">
|
|
57
57
|
{label}
|
|
58
58
|
</div>
|
|
@@ -97,7 +97,7 @@ function SubmissionBars({
|
|
|
97
97
|
<div className="flex h-40 w-full items-end rounded-sm bg-muted/40 px-0.5">
|
|
98
98
|
<div
|
|
99
99
|
className={cn(
|
|
100
|
-
"w-full rounded-sm bg-primary/80 transition-
|
|
100
|
+
"w-full rounded-sm bg-primary/80 shadow-sm transition-[height,background-color,box-shadow] duration-300 ease-out hover:bg-primary hover:shadow-md motion-reduce:transition-none",
|
|
101
101
|
point.submissions === 0 && "bg-muted-foreground/30",
|
|
102
102
|
)}
|
|
103
103
|
style={{ height }}
|
|
@@ -121,11 +121,11 @@ function LoadingState() {
|
|
|
121
121
|
<Skeleton className="h-10 w-72" />
|
|
122
122
|
<div className="forms-response-metrics-grid grid gap-3">
|
|
123
123
|
{Array.from({ length: 4 }).map((_, index) => (
|
|
124
|
-
<Skeleton key={index} className="h-20 rounded-
|
|
124
|
+
<Skeleton key={index} className="h-20 rounded-xl" />
|
|
125
125
|
))}
|
|
126
126
|
</div>
|
|
127
|
-
<Skeleton className="h-64 rounded-
|
|
128
|
-
<Skeleton className="h-72 rounded-
|
|
127
|
+
<Skeleton className="h-64 rounded-xl" />
|
|
128
|
+
<Skeleton className="h-72 rounded-xl" />
|
|
129
129
|
</div>
|
|
130
130
|
);
|
|
131
131
|
}
|
|
@@ -160,7 +160,7 @@ export function ResponseInsightsPage() {
|
|
|
160
160
|
type="button"
|
|
161
161
|
variant="outline"
|
|
162
162
|
size="sm"
|
|
163
|
-
className="gap-1.5"
|
|
163
|
+
className="min-h-10 gap-1.5 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
164
164
|
onClick={() => refetch()}
|
|
165
165
|
>
|
|
166
166
|
<IconRefresh className="size-3.5" />
|
|
@@ -176,7 +176,12 @@ export function ResponseInsightsPage() {
|
|
|
176
176
|
<div className="flex min-h-full flex-col bg-background">
|
|
177
177
|
<header className="flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border pl-12 pr-3 sm:px-4 md:pl-4">
|
|
178
178
|
<div className="flex min-w-0 items-center gap-2">
|
|
179
|
-
<Button
|
|
179
|
+
<Button
|
|
180
|
+
variant="ghost"
|
|
181
|
+
size="sm"
|
|
182
|
+
asChild
|
|
183
|
+
className="min-h-10 gap-1.5 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
184
|
+
>
|
|
180
185
|
<Link to="/forms">
|
|
181
186
|
<IconArrowLeft className="size-3.5" />
|
|
182
187
|
Forms
|
|
@@ -196,7 +201,12 @@ export function ResponseInsightsPage() {
|
|
|
196
201
|
</div>
|
|
197
202
|
</div>
|
|
198
203
|
</div>
|
|
199
|
-
<Button
|
|
204
|
+
<Button
|
|
205
|
+
variant="outline"
|
|
206
|
+
size="sm"
|
|
207
|
+
asChild
|
|
208
|
+
className="min-h-10 gap-1.5 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
209
|
+
>
|
|
200
210
|
<Link to={display.primaryAction.href}>
|
|
201
211
|
{display.primaryAction.label}
|
|
202
212
|
<IconExternalLink className="size-3.5" />
|
|
@@ -204,7 +214,7 @@ export function ResponseInsightsPage() {
|
|
|
204
214
|
</Button>
|
|
205
215
|
</header>
|
|
206
216
|
|
|
207
|
-
<main className="forms-response-insights-grid grid gap-4 p-4">
|
|
217
|
+
<main className="forms-response-insights-grid grid gap-4 bg-muted/20 p-4">
|
|
208
218
|
<section className="space-y-4">
|
|
209
219
|
<div className="forms-response-metrics-grid grid gap-3">
|
|
210
220
|
<Metric
|
|
@@ -233,7 +243,7 @@ export function ResponseInsightsPage() {
|
|
|
233
243
|
/>
|
|
234
244
|
</div>
|
|
235
245
|
|
|
236
|
-
<div className="rounded-
|
|
246
|
+
<div className="rounded-xl border border-border/80 bg-background p-4 shadow-sm">
|
|
237
247
|
<div className="mb-3 flex items-center justify-between gap-3">
|
|
238
248
|
<div>
|
|
239
249
|
<h2 className="text-sm font-semibold">{chartSeries.title}</h2>
|
|
@@ -249,7 +259,7 @@ export function ResponseInsightsPage() {
|
|
|
249
259
|
</div>
|
|
250
260
|
</section>
|
|
251
261
|
|
|
252
|
-
<section className="min-w-0 rounded-
|
|
262
|
+
<section className="min-w-0 overflow-hidden rounded-xl border border-border/80 bg-background shadow-sm">
|
|
253
263
|
<div className="flex min-h-12 items-center justify-between gap-3 border-b border-border px-3">
|
|
254
264
|
<div className="min-w-0">
|
|
255
265
|
<h2 className="truncate text-sm font-semibold">{table.title}</h2>
|
|
@@ -268,13 +278,13 @@ export function ResponseInsightsPage() {
|
|
|
268
278
|
) : (
|
|
269
279
|
<div className="max-h-[calc(100vh-15rem)] overflow-auto">
|
|
270
280
|
<Table>
|
|
271
|
-
<TableHeader className="sticky top-0 z-10 bg-background">
|
|
281
|
+
<TableHeader className="sticky top-0 z-10 bg-background shadow-sm">
|
|
272
282
|
<TableRow>
|
|
273
283
|
{table.columns.map((column) => (
|
|
274
284
|
<TableHead
|
|
275
285
|
key={column.key}
|
|
276
286
|
className={cn(
|
|
277
|
-
"h-
|
|
287
|
+
"h-11 whitespace-nowrap px-3 text-xs",
|
|
278
288
|
column.align === "right" && "text-right",
|
|
279
289
|
)}
|
|
280
290
|
>
|
|
@@ -285,12 +295,15 @@ export function ResponseInsightsPage() {
|
|
|
285
295
|
</TableHeader>
|
|
286
296
|
<TableBody>
|
|
287
297
|
{table.rows.map((row) => (
|
|
288
|
-
<TableRow
|
|
298
|
+
<TableRow
|
|
299
|
+
key={String(row.id)}
|
|
300
|
+
className="transition-[background-color] duration-150 hover:bg-muted/30 motion-reduce:transition-none"
|
|
301
|
+
>
|
|
289
302
|
{table.columns.map((column) => (
|
|
290
303
|
<TableCell
|
|
291
304
|
key={column.key}
|
|
292
305
|
className={cn(
|
|
293
|
-
"max-w-56 truncate px-3 py-
|
|
306
|
+
"max-w-56 truncate px-3 py-3 text-xs",
|
|
294
307
|
column.align === "right" && "text-right",
|
|
295
308
|
)}
|
|
296
309
|
title={formatCell(row[column.key])}
|
|
@@ -254,7 +254,7 @@ export function ResponsesPage() {
|
|
|
254
254
|
variant="outline"
|
|
255
255
|
size="sm"
|
|
256
256
|
onClick={() => refetch()}
|
|
257
|
-
className="gap-2"
|
|
257
|
+
className="min-h-10 gap-2 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
258
258
|
>
|
|
259
259
|
<IconRefresh className="h-3.5 w-3.5" />
|
|
260
260
|
{t("common.retry")}
|
|
@@ -272,7 +272,7 @@ export function ResponsesPage() {
|
|
|
272
272
|
variant="ghost"
|
|
273
273
|
size="sm"
|
|
274
274
|
asChild
|
|
275
|
-
className="gap-1.5
|
|
275
|
+
className="min-h-10 shrink-0 gap-1.5 transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
276
276
|
>
|
|
277
277
|
<Link to={`/forms/${id}`}>
|
|
278
278
|
<IconArrowLeft className="h-3.5 w-3.5" />
|
|
@@ -305,14 +305,14 @@ export function ResponsesPage() {
|
|
|
305
305
|
value={search}
|
|
306
306
|
onChange={(e) => setSearch(e.target.value)}
|
|
307
307
|
placeholder={t("responses.filterPlaceholder")}
|
|
308
|
-
className="h-
|
|
308
|
+
className="h-10 w-48 pl-7 text-xs transition-[background-color,border-color,box-shadow] duration-150 motion-reduce:transition-none"
|
|
309
309
|
/>
|
|
310
310
|
</div>
|
|
311
311
|
) : null}
|
|
312
312
|
<Button
|
|
313
313
|
variant="outline"
|
|
314
314
|
size="sm"
|
|
315
|
-
className="gap-1.5 text-xs
|
|
315
|
+
className="min-h-10 shrink-0 gap-1.5 text-xs transition-[scale,background-color,border-color,color,box-shadow] duration-150 active:scale-[0.96] motion-reduce:transition-none"
|
|
316
316
|
onClick={exportCsv}
|
|
317
317
|
disabled={filteredSorted.length === 0}
|
|
318
318
|
>
|
|
@@ -332,7 +332,7 @@ export function ResponsesPage() {
|
|
|
332
332
|
value={search}
|
|
333
333
|
onChange={(e) => setSearch(e.target.value)}
|
|
334
334
|
placeholder={t("responses.filterPlaceholder")}
|
|
335
|
-
className="h-
|
|
335
|
+
className="h-10 pl-7 text-xs transition-[background-color,border-color,box-shadow] duration-150 motion-reduce:transition-none"
|
|
336
336
|
/>
|
|
337
337
|
</div>
|
|
338
338
|
</div>
|
|
@@ -371,10 +371,10 @@ export function ResponsesPage() {
|
|
|
371
371
|
))}
|
|
372
372
|
</colgroup>
|
|
373
373
|
<thead>
|
|
374
|
-
<tr className="border-b border-border bg-muted/
|
|
374
|
+
<tr className="border-b border-border bg-muted/40">
|
|
375
375
|
<th
|
|
376
376
|
scope="col"
|
|
377
|
-
className="min-w-16 px-4 py-
|
|
377
|
+
className="min-w-16 px-4 py-3 text-left text-xs font-medium text-muted-foreground whitespace-nowrap"
|
|
378
378
|
>
|
|
379
379
|
#
|
|
380
380
|
</th>
|
|
@@ -423,7 +423,7 @@ export function ResponsesPage() {
|
|
|
423
423
|
{filteredSorted.map((response, idx) => (
|
|
424
424
|
<tr
|
|
425
425
|
key={response.id}
|
|
426
|
-
className="border-b border-border hover:bg-muted/20"
|
|
426
|
+
className="border-b border-border transition-[background-color] duration-150 hover:bg-muted/20 motion-reduce:transition-none"
|
|
427
427
|
>
|
|
428
428
|
<td className="px-4 py-2.5 text-xs text-muted-foreground">
|
|
429
429
|
{filteredSorted.length - idx}
|
|
@@ -525,27 +525,50 @@ function SortableHeader(props: {
|
|
|
525
525
|
}) {
|
|
526
526
|
const t = useT();
|
|
527
527
|
const { label, active, dir, onClick } = props;
|
|
528
|
-
const
|
|
529
|
-
?
|
|
528
|
+
const sortState: "neutral" | "asc" | "desc" = !active
|
|
529
|
+
? "neutral"
|
|
530
530
|
: dir === "asc"
|
|
531
|
-
?
|
|
532
|
-
:
|
|
531
|
+
? "asc"
|
|
532
|
+
: "desc";
|
|
533
|
+
const iconBase =
|
|
534
|
+
"absolute inset-0 transition-[opacity,scale,filter] duration-200 ease-[cubic-bezier(0.2,0,0,1)]";
|
|
535
|
+
const iconVisible = "scale-100 opacity-60 blur-none";
|
|
536
|
+
const iconHidden = "scale-[0.25] opacity-0 blur-[4px]";
|
|
533
537
|
return (
|
|
534
538
|
<th
|
|
535
539
|
scope="col"
|
|
536
|
-
className="min-w-40 px-4 py-
|
|
540
|
+
className="min-w-40 px-4 py-1 text-left text-xs font-medium text-muted-foreground whitespace-nowrap"
|
|
537
541
|
>
|
|
538
542
|
<button
|
|
539
543
|
type="button"
|
|
540
544
|
onClick={onClick}
|
|
541
545
|
className={cn(
|
|
542
|
-
"inline-flex items-center gap-1
|
|
546
|
+
"relative -mx-2 inline-flex min-h-10 cursor-pointer items-center gap-1 rounded-md px-2 transition-[scale,background-color,color,box-shadow] duration-150 ease-out hover:bg-accent hover:text-foreground active:scale-[0.96] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 motion-reduce:transition-none motion-reduce:active:scale-100 sm:min-h-0 sm:before:absolute sm:before:-inset-2.5 sm:before:content-['']",
|
|
543
547
|
active && "text-foreground",
|
|
544
548
|
)}
|
|
545
549
|
aria-label={t("responses.sortBy", { label })}
|
|
546
550
|
>
|
|
547
551
|
{label}
|
|
548
|
-
<
|
|
552
|
+
<span className="relative inline-block h-3 w-3 shrink-0">
|
|
553
|
+
<IconArrowsSort
|
|
554
|
+
className={cn(
|
|
555
|
+
iconBase,
|
|
556
|
+
sortState === "neutral" ? iconVisible : iconHidden,
|
|
557
|
+
)}
|
|
558
|
+
/>
|
|
559
|
+
<IconArrowUp
|
|
560
|
+
className={cn(
|
|
561
|
+
iconBase,
|
|
562
|
+
sortState === "asc" ? iconVisible : iconHidden,
|
|
563
|
+
)}
|
|
564
|
+
/>
|
|
565
|
+
<IconArrowDown
|
|
566
|
+
className={cn(
|
|
567
|
+
iconBase,
|
|
568
|
+
sortState === "desc" ? iconVisible : iconHidden,
|
|
569
|
+
)}
|
|
570
|
+
/>
|
|
571
|
+
</span>
|
|
549
572
|
</button>
|
|
550
573
|
</th>
|
|
551
574
|
);
|
|
@@ -54,7 +54,7 @@ export default function SettingsRoute() {
|
|
|
54
54
|
{t("settings.description")}
|
|
55
55
|
</p>
|
|
56
56
|
|
|
57
|
-
<Card id="language" className="scroll-mt-16">
|
|
57
|
+
<Card id="language" className="forms-settings-card scroll-mt-16">
|
|
58
58
|
<CardHeader>
|
|
59
59
|
<CardTitle className="text-base">
|
|
60
60
|
{t("settings.languageTitle")}
|