Frontend: Tech-Stack
Technologien
| Technologie | Version | Zweck |
|---|---|---|
| SolidJS | ~1.x | UI Framework (reaktiv, kein Virtual DOM) |
| TypeScript | ~5.x | Typsicherheit |
| Vite | ~5.x | Build-Tool |
| pnpm | ~8.x | Package Manager |
| Styled System | (Panda CSS) | CSS-in-JS |
| Lingui | ~4.x | i18n (Übersetzungen) |
| solid-dnd-directive | – | Drag & Drop |
| solid-floating-ui | – | Tooltips, Popups |
SolidJS Grundlagen
SolidJS ist React-ähnlich, aber reaktiv ohne Virtual DOM.
import { createSignal, createMemo, createEffect, Show, For } from "solid-js";
// Signal = reaktiver State
const [count, setCount] = createSignal(0);
// Memo = abgeleiteter Wert (cached)
const doubled = createMemo(() => count() * 2);
// Effect = Seiteneffekt bei Änderungen
createEffect(() => {
console.log("Count changed:", count());
});
// Bedingte Darstellung
<Show when={count() > 0}>
<p>Count: {count()}</p>
</Show>
// Listen
<For each={items()}>
{(item) => <div>{item.name}</div>}
</For>
Komponenten-Struktur
// Typische Komponentendefinition
import { Component, createSignal } from "solid-js";
interface Props {
name: string;
onClose: () => void;
}
export function MyComponent(props: Props) {
const [open, setOpen] = createSignal(false);
return (
<div>
<h1>{props.name}</h1>
<button onClick={props.onClose}>Schließen</button>
</div>
);
}
CSS mit css() und styled()
import { css } from "styled-system/css";
import { styled } from "styled-system/jsx";
// Inline CSS (für dynamische Styles)
const dynamicStyle = css({
color: "var(--md-sys-color-primary)",
borderRadius: "8px",
});
// Styled Component
const MyDiv = styled("div", {
base: {
background: "var(--bg)",
padding: "1rem",
},
variants: {
size: {
small: { fontSize: "0.8rem" },
large: { fontSize: "1.2rem" },
}
}
});
Floating-System (Tooltips, Menus)
Das use:floating Direktiv wird für Tooltips, Context-Menus und User-Cards verwendet:
// Tooltip
<div use:floating={{
tooltip: {
content: "Hover-Text",
placement: "right",
}
}}>
Hover mich
</div>
// Context Menu (Rechtsklick)
<div use:floating={{
contextMenu: () => (
<ContextMenu>
<ContextMenuButton onClick={doSomething}>
Aktion
</ContextMenuButton>
</ContextMenu>
),
}}>
Rechtsklick mich
</div>
createResource für async Daten
import { createResource } from "solid-js";
// Automatisches Fetching mit Reaktivität
const [data, { mutate, refetch }] = createResource(userId, async (id) => {
const res = await fetch(/api/user/${id});
return res.json();
});
// Zugriff
if (data.loading) return <div>Lädt...</div>;
if (data.error) return <div>Fehler!</div>;
return <div>{data()?.name}</div>;
// Lokal aktualisieren (optimistic update)
mutate({ ...data(), name: "Neuer Name" });