managarten/packages/shared-ui
Till JS abafdfbeb3
Some checks are pending
CD Mac Mini / Detect Changes (push) Waiting to run
CD Mac Mini / Deploy (push) Blocked by required conditions
CI / Detect Changes (push) Waiting to run
CI / Validate (push) Waiting to run
CI / Build mana-search (push) Blocked by required conditions
CI / Build mana-sync (push) Blocked by required conditions
CI / Build mana-api-gateway (push) Blocked by required conditions
CI / Build mana-crawler (push) Blocked by required conditions
Docker Validate / Validate Dockerfiles (push) Waiting to run
Docker Validate / Build calendar-web (push) Blocked by required conditions
Docker Validate / Build quotes-web (push) Blocked by required conditions
Docker Validate / Build todo-backend (push) Blocked by required conditions
Docker Validate / Build todo-web (push) Blocked by required conditions
Docker Validate / Build mana-auth (push) Blocked by required conditions
Docker Validate / Build mana-sync (push) Blocked by required conditions
Docker Validate / Build mana-media (push) Blocked by required conditions
Mirror to Forgejo / Push to Forgejo (push) Waiting to run
fix(shared-ui): TagChip nested button + Pill svelte:element ARIA role
Beide standen seit dem letzten shared-ui-Sync (ce923bbdc) als
svelte-check --fail-on-warnings Treffer im Pre-Push-Hook drin.
Aufgeräumt für die Cutover-PRs.

TagChip: outer war `<button>` mit innerem Remove-`<button>` —
verschachtelte interaktive Elemente sind invalid HTML und brechen
SSR-Hydration. Outer ist jetzt `<span role="button" tabindex="0">`
mit Enter/Space-Keyboard-Handler. CSS-Selektor `button.chip` →
`.chip-interactive` Klasse.

Pill: `<svelte:element this={tag}>` mit onclick/oncontextmenu
braucht explizite ARIA-Rolle (button bzw. link), weil der
statische Analyser den dynamischen Tag nicht aufdröselt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:24:56 +02:00
..
scripts shared-ui: Sync auf mana/shared-ui v1.0.0 + AppSlider tot weg 2026-05-21 14:56:54 +02:00
src fix(shared-ui): TagChip nested button + Pill svelte:element ARIA role 2026-05-21 17:24:56 +02:00
.gitignore shared-ui: Sync auf mana/shared-ui v1.0.0 + AppSlider tot weg 2026-05-21 14:56:54 +02:00
package.json shared-ui: Sync auf mana/shared-ui v1.0.0 + AppSlider tot weg 2026-05-21 14:56:54 +02:00
README.md shared-ui: Sync auf mana/shared-ui v1.0.0 + AppSlider tot weg 2026-05-21 14:56:54 +02:00
tsconfig.json shared-ui: Sync auf mana/shared-ui v1.0.0 + AppSlider tot weg 2026-05-21 14:56:54 +02:00

@mana/shared-ui

Vereins-UI-Komponenten — Svelte 5, strikte 12-Token-Disziplin nach mana/docs/THEMING.md. Konsumiert von allen mana-e.V.-Apps (managarten, zitare, nutriphi, wordeck, manawald, …).

Stand: v1.0.0 (2026-05-21). Konsolidiert aus shared-ui@0.1.x + shared-ui-2@0.1.x. Ehemalige Doppel-Bibliothek ist Geschichte — eine UI-Foundation, ein Disziplin-Set, ein Verzeichnis.

Disziplin

  1. Styles ausschließlich in <style>-Block. Keine Tailwind-Utility-Klassen für Farben (bg-card, text-foreground). Layout-Klassen (flex, gap-2) sind okay, wenn der Konsument Tailwind nutzt.
  2. Nur die 12 Tokens aus THEMING.md: background, foreground, surface, surface-hover, muted, muted-foreground, border, primary, primary-foreground, error, success, warning. Kein 13. Token. Sub-Tokens werden via color-mix(in srgb, var(--color-surface) 95%, var(--color-foreground)) oder Alpha-Modifier (hsl(var(--color-primary) / 0.12)) gelöst.
  3. hsl()-Wrap immer. color: hsl(var(--color-foreground)), nie bare var(--color-X).
  4. Keine Hex-Farben außer in der --brand-*-Schicht (für App-Brand-Identität, NICHT für Theme-Tokens).
  5. Phosphor-Icons sind raus. DynamicIcon (40+ Inline-SVGs, 16×16, currentColor, stroke 1.4-1.6) ersetzt die phosphor-svelte-Peer-Dep. Komponenten die in v0.x noch icon: Component hatten, akzeptieren in v1.0.0 nur noch iconSvg: string.
  6. A11y-Pflichten: ARIA-Labels für Icon-Buttons, semantisches HTML, :focus-visible mit sichtbarem Outline, keyboard-Navigation.
  7. Storybook + Lost-Pixel für die Komponenten, die diese Disziplin schon mit Stories+Baseline belegt haben (siehe PORTING_PLAN.md, Status vs 🚧).

Installation

pnpm add @mana/shared-ui

Voraussetzung: 12 Tokens aus @mana/themes (oder eigene Variant) im <html data-theme="...">-Kontext aktiv.

Nutzung

<script>
  import { Button, Card, Badge } from '@mana/shared-ui/atoms';
  import { PillTabGroup, PillDropdown } from '@mana/shared-ui/navigation';
  import { Modal, ContextMenu, NotificationBar } from '@mana/shared-ui/organisms';
  import { dragSource, dropTarget } from '@mana/shared-ui/dnd';
</script>

Tests

pnpm validate         # Disziplin-Validator (12-Token-Allowlist, hsl-wrap-Pflicht)
pnpm storybook        # Storybook auf :6006
pnpm test:visual      # Lost-Pixel-Run gegen Baseline
pnpm test:visual:update  # Baseline aktualisieren (nach bewusster Änderung)

Vorgeschichte

v0.1.1 (alt, organisch über 3 Jahre gewachsen) und v0.1.0 als shared-ui-2 (Greenfield-Refactor seit 2026-05-09) liefen 12 Tage parallel. Konsolidierung am 2026-05-21: alle 12 zusätzlich benötigten Komponenten portiert, AppSlider als tot identifiziert, alte v1 vollständig durch v2-Code ersetzt, Paket-Name zurück auf @mana/shared-ui. Details: Phasen-Log in PORTING_PLAN.md.