feat(animation-sources): add content-driven guide system
This commit is contained in:
+1
-45
@@ -70,33 +70,6 @@ export const SOCIAL_LINKS = [
|
||||
},
|
||||
] as const;
|
||||
|
||||
export const ANIMATION_RESOURCE_LINKS = [
|
||||
{
|
||||
id: "motion",
|
||||
label: "Motion",
|
||||
href: "https://motion.dev/",
|
||||
icon: "mdi:motion-play-outline",
|
||||
},
|
||||
{
|
||||
id: "gsap",
|
||||
label: "GSAP",
|
||||
href: "https://gsap.com/resources/",
|
||||
icon: "mdi:lightning-bolt-outline",
|
||||
},
|
||||
{
|
||||
id: "lottiefiles",
|
||||
label: "LottieFiles",
|
||||
href: "https://lottiefiles.com/",
|
||||
icon: "mdi:movie-open-play-outline",
|
||||
},
|
||||
{
|
||||
id: "rive",
|
||||
label: "Rive",
|
||||
href: "https://rive.app/",
|
||||
icon: "mdi:vector-curve",
|
||||
},
|
||||
] as const;
|
||||
|
||||
export const NAV_DROPDOWN_GROUPS = [
|
||||
{
|
||||
id: "others",
|
||||
@@ -107,7 +80,7 @@ export const NAV_DROPDOWN_GROUPS = [
|
||||
{
|
||||
id: "animationResources",
|
||||
label: "Animasyon Kaynakları",
|
||||
href: "/links?category=resources&query=animation",
|
||||
href: "/animation-sources",
|
||||
icon: "mdi:motion-play-outline",
|
||||
external: false,
|
||||
keywords: ["animasyon", "animation", "kaynak", "resource", "motion"],
|
||||
@@ -191,23 +164,6 @@ export const LINK_DIRECTORY: LinkDirectoryItem[] = [
|
||||
category: "social" as const,
|
||||
keywords: [item.label, item.href, "sosyal", "profile", "platform"],
|
||||
})),
|
||||
...ANIMATION_RESOURCE_LINKS.map((item) => ({
|
||||
id: item.id,
|
||||
label: item.label,
|
||||
href: item.href,
|
||||
icon: item.icon,
|
||||
external: true,
|
||||
category: "resources" as const,
|
||||
keywords: [
|
||||
item.label,
|
||||
item.href,
|
||||
"animasyon",
|
||||
"animation",
|
||||
"kaynak",
|
||||
"resource",
|
||||
"motion",
|
||||
],
|
||||
})),
|
||||
...TOP_ICON_LINKS.map((item) => ({
|
||||
id: item.id,
|
||||
label: item.label,
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
export type MarkdownHeading = {
|
||||
id: string;
|
||||
text: string;
|
||||
level: 2 | 3;
|
||||
};
|
||||
|
||||
export function cleanMarkdownHeading(text: string) {
|
||||
return text
|
||||
.replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1")
|
||||
.replace(/[*_~`]/g, "")
|
||||
.trim();
|
||||
}
|
||||
|
||||
export function slugifyMarkdownHeading(text: string) {
|
||||
return cleanMarkdownHeading(text)
|
||||
.toLocaleLowerCase("tr-TR")
|
||||
.normalize("NFKD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/ı/g, "i")
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
export function parseMarkdownHeadings(markdown: string): MarkdownHeading[] {
|
||||
const headings: MarkdownHeading[] = [];
|
||||
|
||||
for (const line of markdown.split("\n")) {
|
||||
const match = /^(#{2,3})\s+(.+)$/.exec(line.trim());
|
||||
if (!match) continue;
|
||||
|
||||
const text = cleanMarkdownHeading(match[2]);
|
||||
const id = slugifyMarkdownHeading(text);
|
||||
if (!id || !text) continue;
|
||||
|
||||
headings.push({
|
||||
id,
|
||||
text,
|
||||
level: match[1].length as 2 | 3,
|
||||
});
|
||||
}
|
||||
|
||||
return headings;
|
||||
}
|
||||
Reference in New Issue
Block a user