diff --git a/app/admin/[character]/[page]/page.tsx b/app/admin/[character]/[page]/page.tsx
index 2f799fb..41f159a 100644
--- a/app/admin/[character]/[page]/page.tsx
+++ b/app/admin/[character]/[page]/page.tsx
@@ -22,5 +22,5 @@ export default async function StructuredEditorPage({ params }: { params: Promise
const [catalog, content] = await Promise.all([getActiveCatalog(), getAdminGuideContent(guide.slug)]);
if (!catalog || !content) notFound();
const guideCharacter = catalog.characters.find((item) => item.key === guide.characterKey);
- return
} nativeButton={false} aria-label="กลับหน้า Guide">{guide.name}
{guide.sections.find((section) => section.slug === page)?.title ?? page}
section.slug === page)?.note ?? null, weaponGroups: content.weaponGroups, artifactGroups: content.artifactGroups.map((group) => ({ id: group.id, name: group.name, rows: group.rows.map((row) => ({ firstArtifactKey: row.firstArtifactKey, secondArtifactKey: row.secondArtifactKey, percent: row.percent, note: row.note })) })), artifactProfile: content.artifactProfile, constellationGroups: content.constellationGroups.map((group) => ({ id: group.id, note: group.note, rows: group.rows })), teams: content.teams.map((team) => ({ id: team.id, title: team.title, rotationSeconds: team.rotationSeconds, combo: team.combo, members: team.members.map((member) => ({ characterKey: member.characterKey, weaponKey: member.weaponKey, artifactKey: member.artifactKey, secondArtifactKey: member.secondArtifactKey, constellation: member.constellation, refinement: member.refinement, damage: member.damage })) })), extras: content.extras.map((section) => ({ id: section.id, title: section.title, rows: section.rows.map((row) => ({ id: row.id, mediaId: row.mediaId, heading: row.heading, body: row.body, percent: row.percent, backgroundColor: row.backgroundColor, highlights: row.highlights, imageUrl: row.imageUrl, imageWidth: row.imageWidth, imageHeight: row.imageHeight })) })) }} /> ;
+ return } nativeButton={false} aria-label="กลับหน้า Guide">{guide.name}
{guide.sections.find((section) => section.slug === page)?.title ?? page}
section.slug === page)?.note ?? null, weaponGroups: content.weaponGroups, artifactGroups: content.artifactGroups.map((group) => ({ id: group.id, name: group.name, rows: group.rows.map((row) => ({ firstArtifactKey: row.firstArtifactKey, secondArtifactKey: row.secondArtifactKey, percent: row.percent, note: row.note })) })), artifactProfile: content.artifactProfile, constellationGroups: content.constellationGroups.map((group) => ({ id: group.id, note: group.note, rows: group.rows })), teams: content.teams.map((team) => ({ id: team.id, title: team.title, rotationSeconds: team.rotationSeconds, combo: team.combo, members: team.members.map((member) => ({ characterKey: member.characterKey, weaponKey: member.weaponKey, artifactKey: member.artifactKey, secondArtifactKey: member.secondArtifactKey, constellation: member.constellation, refinement: member.refinement, damage: member.damage })) })), extras: content.extras.map((section) => ({ id: section.id, title: section.title, rows: section.rows.map((row) => ({ id: row.id, mediaId: row.mediaId, heading: row.heading, body: row.body, percent: row.percent, backgroundColor: row.backgroundColor, highlights: row.highlights, imageUrl: row.imageUrl, imageWidth: row.imageWidth, imageHeight: row.imageHeight })) })) }} /> ;
}
diff --git a/app/admin/[character]/page.tsx b/app/admin/[character]/page.tsx
index b7f53c6..d20add2 100644
--- a/app/admin/[character]/page.tsx
+++ b/app/admin/[character]/page.tsx
@@ -27,5 +27,5 @@ export default async function GuideOverviewPage({ params }: { params: Promise<{
const { character } = await params;
const guide = await getGuideByCharacterKey(character);
if (!guide) notFound();
- return } nativeButton={false} aria-label="กลับ Dashboard">
เลือกส่วนที่ต้องการแก้ไข
{guide.name}
{sections.map(({ slug, title, description }) =>
{navigationIconPath(slug) ? : null}{title}{description})}
Extra sectionsส่วนเสริมแบบภาพ หัวข้อ ข้อความสั้น และเปอร์เซ็นต์ ;
+ return } nativeButton={false} aria-label="กลับ Dashboard">
เลือกส่วนที่ต้องการแก้ไข
{guide.name}
{sections.map(({ slug, title, description }) =>
{navigationIconPath(slug) ? : null}{title}{description})}
Extra sectionsส่วนเสริมแบบภาพ หัวข้อ ข้อความสั้น และเปอร์เซ็นต์ ;
}
diff --git a/app/globals.css b/app/globals.css
index e9fe78f..3793b8b 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -140,4 +140,21 @@
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
+
+ ::view-transition-old(*),
+ ::view-transition-new(*),
+ ::view-transition-group(*) {
+ animation-delay: 0s !important;
+ animation-duration: 0s !important;
+ }
+}
+
+::view-transition {
+ pointer-events: none;
+}
+
+::view-transition-group(.guide-topic-indicator) {
+ animation-duration: 300ms;
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ z-index: -1;
}
diff --git a/components/admin/guide-section-nav.tsx b/components/admin/guide-section-nav.tsx
index 64ea1fd..b155e5e 100644
--- a/components/admin/guide-section-nav.tsx
+++ b/components/admin/guide-section-nav.tsx
@@ -4,6 +4,7 @@ import Image from "next/image";
import Link from "next/link";
import type { MouseEvent } from "react";
+import { GuideTopicIndicator } from "@/components/guide-topic-indicator";
import { ScrollableNav } from "@/components/public/scrollable-nav";
import { navigationIconPath } from "@/lib/navigation";
import { cn } from "@/lib/utils";
@@ -19,9 +20,11 @@ const sections = [
export function GuideSectionNav({
characterKey,
current,
+ guideId,
}: {
characterKey: string;
current: "overview" | (typeof sections)[number]["slug"];
+ guideId: string;
}) {
const confirmNavigation = (event: MouseEvent) => {
const browserWindow = window as Window & { __guideHasUnsavedChanges?: boolean };
@@ -39,10 +42,11 @@ export function GuideSectionNav({
prefetch
onClick={confirmNavigation}
className={cn(
- "flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
- current === "overview" ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
+ "relative isolate flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
+ current === "overview" ? "text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)}
>
+ {current === "overview" ? : null}
Overview
@@ -55,10 +59,11 @@ export function GuideSectionNav({
prefetch
onClick={confirmNavigation}
className={cn(
- "flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
- current === section.slug ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
+ "relative isolate flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
+ current === section.slug ? "text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)}
>
+ {current === section.slug ? : null}
{iconPath ? : null}
{section.label}
diff --git a/components/guide-topic-indicator.tsx b/components/guide-topic-indicator.tsx
new file mode 100644
index 0000000..cf307bd
--- /dev/null
+++ b/components/guide-topic-indicator.tsx
@@ -0,0 +1,22 @@
+import { ViewTransition } from "react";
+
+export function GuideTopicIndicator({
+ guideId,
+ surface,
+}: {
+ guideId: string;
+ surface: "public" | "admin";
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/components/public/structured-guide.tsx b/components/public/structured-guide.tsx
index 6a62cb8..2d90479 100644
--- a/components/public/structured-guide.tsx
+++ b/components/public/structured-guide.tsx
@@ -21,6 +21,7 @@ import { GuideImageExport } from "@/components/public/guide-image-export";
import { ConstellationImage } from "@/components/public/constellation-image";
import { RichTextContent } from "@/components/rich-text-content";
import { LiveRefresh } from "@/components/live-refresh";
+import { GuideTopicIndicator } from "@/components/guide-topic-indicator";
import { rarityGradientClass, rarityTextClass } from "@/lib/catalog/rarity";
import { elementIconFilter } from "@/lib/catalog/element";
import type { PublicGuide } from "@/lib/guides/queries";
@@ -126,13 +127,14 @@ export function StructuredGuideShell({
+ {!section ? : null}
+ {section === item.slug ? : null}
{navigationIconPath(item.slug) ? (