ttrpg-tools/src/components/md-deck/CardLayer.tsx

51 lines
1.8 KiB
TypeScript
Raw Normal View History

import {createMemo, For} from 'solid-js';
2026-02-27 21:12:23 +08:00
import { marked } from '../../markdown';
import { getLayerStyle } from './hooks/dimensions';
import type { CardData } from './types';
import {DeckStore} from "./hooks/deckStore";
import {processVariables} from "../utils/csv-loader";
2026-02-27 21:12:23 +08:00
export interface CardLayerProps {
cardData: CardData;
store: DeckStore;
2026-02-27 21:12:23 +08:00
}
export function CardLayer(props: CardLayerProps) {
const layers = createMemo(() => props.store.state.layerConfigs.filter((l) => l.visible));
const dimensions = () => props.store.state.dimensions!;
const showBounds = () => props.store.state.isEditing;
function renderLayerContent(content: string) {
return marked.parse(processVariables(content, props.cardData, props.store.state.cards)) as string;
}
2026-02-27 21:12:23 +08:00
return (
<For each={layers()}>
2026-02-27 22:56:06 +08:00
{(layer) => {
return (
<>
<article
class="absolute flex items-center justify-center text-center prose prose-sm"
2026-02-27 22:37:11 +08:00
style={{
...getLayerStyle(layer, dimensions()),
2026-02-28 12:18:52 +08:00
'font-size': `${layer.fontSize || 3}mm`
2026-02-27 22:37:11 +08:00
}}
innerHTML={renderLayerContent(props.cardData[layer.prop])}
2026-02-27 22:37:11 +08:00
/>
{showBounds() && (
2026-02-27 22:56:06 +08:00
<div
class="absolute border-2 border-blue-500/50 pointer-events-none select-none"
style={{
left: `${(layer.x1 - 1) * dimensions().cellWidth}mm`,
top: `${(layer.y1 - 1) * dimensions().cellHeight}mm`,
width: `${(layer.x2 - layer.x1 + 1) * dimensions().cellWidth}mm`,
height: `${(layer.y2 - layer.y1 + 1) * dimensions().cellHeight}mm`
2026-02-27 22:56:06 +08:00
}}
/>
)}
</>
);
}}
2026-02-27 21:12:23 +08:00
</For>
);
}