feat(markdown): add markdown

This commit is contained in:
Alois 2026-08-09 20:54:00 +02:00
commit 0193880cb0
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
4036 changed files with 25057 additions and 1990 deletions

48
src/markdown/emoji.tsx Normal file
View file

@ -0,0 +1,48 @@
import { useEffect, useState } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "../cmp/tooltip";
import { useEmojiRegistry } from "./emoji-context";
import type { EmojiRegistry } from "./emoji-data";
export type EmojiProps = {
className?: string;
registry?: EmojiRegistry;
shortcode: string;
tooltip?: boolean;
};
export default function Emoji({
className = "size-6",
registry: registryOverride,
shortcode,
tooltip = true,
}: EmojiProps) {
const registry = useEmojiRegistry(registryOverride);
const emoji = registry.resolve(shortcode);
const [failedSource, setFailedSource] = useState<string>();
useEffect(() => setFailedSource(undefined), [emoji?.src]);
if (!emoji || failedSource === emoji.src) return <span>{shortcode}</span>;
const image = (
<img
alt={emoji.shortcode}
className={className}
decoding="async"
draggable={false}
loading="lazy"
src={emoji.src}
onError={() => setFailedSource(emoji.src)}
/>
);
if (!tooltip) return image;
return (
<Tooltip>
<TooltipTrigger render={image} />
<TooltipContent sideOffset={8}>{emoji.shortcode}</TooltipContent>
</Tooltip>
);
}