{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "drag-sortieren-platzhalter",
 "name": "Drag-and-drop-Sortieren mit Platzhalter- und Drop-Animation",
 "name_en": "Drag-and-drop sorting with placeholder and drop animation",
 "kurz": "Gänge eines Menüs in die Wunschfolge ziehen: Das Original bleibt als Platzhalter, eine Linie oder ausweichende Nachbarn zeigen das Ziel, und ein kurzer Farb-Flash bestätigt das Ablegen.",
 "kategorie": "Mikroanimationen",
 "kategorie_slug": "mikroanimationen",
 "kategorie_nr": 9,
 "bau_chat": "C4",
 "prioritaet": "B",
 "trendstatus": "etabliert",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "präzise",
  "verspielt"
 ],
 "stimmung_roh": [
  "funktional",
  "taktil",
  "app-artig",
  "präzise"
 ],
 "technik": [
  "vanilla-js",
  "css",
  "draggable"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "1) Ziehbare Elemente zeigen das vorab: Griff-Icon, cursor: grab und ein leichter Hintergrundwechsel beim Hover. 2) Beim Ziehen bleibt das Original als gedimmter Platzhalter (opacity 0.4) stehen oder wird zur leeren Lücke. Eine Vorschau folgt dem Zeiger. 3) Das Ziel wird sichtbar, bevor man loslässt: entweder als Drop-Linie mit Punkt am Anfang oder durch Nachbarn, die mit kurzer Transform-Animation ausweichen. 4) Nach dem Ablegen gleitet das Element in seine Lücke, und die Fläche leuchtet einmal kurz in der Auswahlfarbe auf. 5) Tastatur und Knöpfe („Nach oben“, „Nach unten“) erreichen dasselbe Ergebnis ohne Ziehen.",
  "warum_es_wirkt": "Direkte Manipulation fühlt sich physisch und schnell an. Linie oder Ausweichen zeigen die Folgen der Aktion, bevor man loslässt. Der Flash bestätigt, wo das Element gelandet ist.",
  "wann_einsetzen": "Kanban-Boards, Playlists, Prioritäten- und Wunschlisten, Menü- und Navigations-Editoren, Bildreihenfolge in Galerien, Formular- und Seitenbaukästen, Konfiguratoren.",
  "wann_nicht": "Als einzige Möglichkeit zum Umsortieren (Barrierefreiheit). Bei sehr langen, virtuellen Listen ohne Auto-Scroll. Wenn die Reihenfolge fachlich egal ist.",
  "varianten": [
   "Gedimmtes Original (opacity 0.4) mit Drop-Linie, Nachbarn bleiben stehen (Atlassian Pragmatic drag and drop)",
   "Live-Umordnung: Nachbarn weichen während des Ziehens aus (dnd kit Sortable, SortableJS animation: 150)",
   "Leere Lücke mit gestricheltem Rahmen in Elementgröße",
   "Vorschau leicht gedreht und angehoben (Trello: 4°)",
   "Drop-Flash in der Auswahlfarbe nach dem Ablegen",
   "Native View Transitions für die Umordnung (siehe flip-zustandswechsel)"
  ],
  "umsetzung": "Bibliothek wählen: Pragmatic drag and drop (nativ, sehr klein, framework-unabhängig), dnd kit (React, Vue, Svelte; Sortable-Preset, Tastatursensor) oder SortableJS (Vanilla). Ohne Bibliothek reichen Pointer Events, wenn alle Elemente gleich hoch sind.\n\nZustände als Klassen: .is-dragging { opacity: .4 } am Original. Drop-Indikator als absolut positionierte 2-px-Linie mit 8-px-Kreis, der 4 px nach links übersteht. Vorschau höchstens 280 × 280 px, 16/8 px vom Zeiger versetzt. Nachbarn: transition: transform 150ms cubic-bezier(0.25, 1, 0.5, 1) (dnd kit Standard: 250 ms). Nach dem Drop: element.animate([{ backgroundColor: 'var(--selected)' }, { backgroundColor: 'transparent' }], { duration: 700, easing: 'cubic-bezier(0.25, 0.1, 0.25, 1)' }).\n\nAktivierung: Maus ab 10 px Bewegung, Touch nach 250 ms Halten mit 5 px Toleranz, damit Scrollen möglich bleibt. Zusätzlich Knöpfe oder Menü „Verschieben nach …“ und Tastatur (Leertaste aufnehmen, Pfeiltasten, Leertaste ablegen, Escape abbrechen) mit aria-live-Ansagen.\n\nFallstricke: Nach dem Gleiten die Transforms und die DOM-Reihenfolge im selben Frame zurücksetzen, sonst springt die Liste. Den Klick nach einem Zug abfangen. Beim Verschieben per Tastatur den Fokus auf dem Griff halten.",
  "mobil": "Long-Press (etwa 250 ms) zum Aufnehmen, am Griff sofort. Auto-Scroll am Rand bei langen Listen. Griffe mindestens 24 × 24 px, besser 44 px. Natives HTML5-Drag-and-drop ist auf Touch eingeschränkt, deshalb Pointer Events oder eine Bibliothek mit Touch-Sensor nutzen.",
  "reduzierte_bewegung": "Ausweich- und Gleitanimationen auf 0 ms. Drop-Linie und Flash bleiben, der Flash als reiner Farbwechsel ohne Bewegung.",
  "barrierefreiheit": "Dasselbe Ergebnis ohne Ziehen ermöglichen (WCAG 2.5.7 Dragging Movements): Tastatursteuerung und Knöpfe oder Menüaktionen. Positionswechsel per aria-live ansagen („Position 2 von 5“). Der Griff ist ein Button mit Label, etwa „Saibling und Kren verschieben“."
 },
 "messwerte": {
  "easing": "Motion-Layout-Animation (Standard-Spring)",
  "dauer_ms": "",
  "stagger_ms": "",
  "distanz": "",
  "sonstiges": "kein separater Platzhalter: Lücke entsteht durch Layout-Verschiebung",
  "herkunft": "beobachtet",
  "quelle": "https://posthog.com/"
 },
 "kurve": null,
 "gesehen_bei": [
  {
   "seite": "Atlassian Design – Pragmatic drag and drop: Design guidelines",
   "url": "https://atlassian.design/components/pragmatic-drag-and-drop/design-guidelines",
   "auszeichnung": "",
   "beobachtung": "Verbindliche Werte des Atlassian-Systems (Jira, Confluence, Trello): Original während des Ziehens opacity 0.4, Drop-Linie 2 px mit 8-px-Endpunkt, der 4 px nach links übersteht; Preview max. 280×280 px, 16/8 px vom Zeiger versetzt, nicht drehen (Ausnahme Trello 4°); nach dem Drop Hintergrund-Flash 700 ms cubic-bezier(0.25, 0.1, 0.25, 1.0); cursor: grab bei sekundärem Drag erst nach 800 ms.",
   "art": "artikel"
  },
  {
   "seite": "dnd kit – Sortable (Dokumentation)",
   "url": "https://docs.dndkit.com/presets/sortable",
   "auszeichnung": "",
   "beobachtung": "Standard-Transition 250 ms ease, Beispiel 150 ms cubic-bezier(0.25, 1, 0.5, 1); Sensoren: Maus nach 10 px Bewegung, Touch nach 250 ms Halten mit 5 px Toleranz; Tastatur-Sensor mit sortableKeyboardCoordinates; DragOverlay für scrollbare Listen.",
   "art": "artikel"
  },
  {
   "seite": "SortableJS – Beispiele",
   "url": "https://sortablejs.github.io/Sortable/",
   "auszeichnung": "",
   "beobachtung": "Framework-unabhängige Bibliothek; Beispiele mit animation: 150, ghostClass für den Platzhalter, Handles, geteilte Listen, Grid, Swap-Schwellen.",
   "art": "demo"
  },
  {
   "seite": "PostHog",
   "url": "https://posthog.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (app-c044e6caca919f86cd8c.js): Framer-Motion Reorder.Group (as 'ul', axis 'y', values=order, onReorder) für die Forum-Themenliste; Reorder.Item mit drag, dragSnapToOrigin:true und layout-Animation – die übrigen Einträge weichen per Layout-Animation aus (Ladezustand mit animate-pulse-Skeletons).",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Atlassian – Pragmatic drag and drop: Design guidelines",
   "url": "https://atlassian.design/components/pragmatic-drag-and-drop/design-guidelines"
  },
  {
   "titel": "dnd kit – Sortable",
   "url": "https://docs.dndkit.com/presets/sortable"
  },
  {
   "titel": "SortableJS – Beispiele",
   "url": "https://sortablejs.github.io/Sortable/"
  }
 ],
 "kombinierbar_mit": [
  "flip-zustandswechsel",
  "druck-feedback",
  "toast-stapel",
  "hold-to-confirm",
  "bento-grid-interaktiv"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/mikroanimationen/drag-sortieren-platzhalter/",
  "meta": "https://cecodesign.de/lab/fundus/mikroanimationen/drag-sortieren-platzhalter/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/mikroanimationen/drag-sortieren-platzhalter/demo"
 },
 "herkunft": {
  "quelldateien": [
   "patch-luecken-b.json",
   "r3-belege-b.json"
  ],
  "pruefnotizen": [
   "r3-belege-b.json (Runde 3, 31.10.2026): Produktionsbeleg vorhanden, aber ohne sichtbaren Platzhalter-Kasten oder Drop-Flash; Atlassian-Werte bleiben die Referenz."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Gänge eines Menüs in die Wunschfolge ziehen: Das Original bleibt als Platzhalter, eine Linie oder ausweichende Nachbarn zeigen das Ziel, und ein kurzer Farb-Flash bestätigt das Ablegen.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "platzhalter": "Variante Linie: Original opacity 0.4 an seiner Stelle; Variante Lücke: leere Fläche in Kartengröße mit 2 px gestricheltem Rahmen",
   "drop_linie": "2 px Linie mit 8-px-Ring (2 px Rand), Ring steht 4 px links über, sitzt mittig im 10-px-Spalt",
   "vorschau": "Linie: kompakte Karte max. 280 px breit, 16 px rechts und 8 px unter dem Zeiger, nicht gedreht; Lücke: Karte in voller Breite, 4° gedreht, Drehpunkt 30 % 50 %",
   "angehoben": "Variante Ausweichen: die Karte selbst folgt dem Zeiger, scale 1.02, Schatten 0 18px 38px -8px",
   "nachbarn_ms": 150,
   "nachbarn_easing": "cubic-bezier(0.25, 1, 0.5, 1)",
   "ablegen_ms": "250 (Gleiten in die Lücke, gleiche Kurve); Variante Linie ohne Gleiten",
   "flash": "700 ms cubic-bezier(0.25, 0.1, 0.25, 1), Hintergrund #f6d88f → #f4eee2",
   "aktivierung": "Maus ab 10 px Bewegung; Touch nach 250 ms Halten mit 5 px Toleranz, am Griff sofort",
   "knopf_und_tastatur": "Umordnen per FLIP 250 ms cubic-bezier(0.25, 1, 0.5, 1)",
   "raster": "Kartenhöhe 78 px, Abstand 10 px (Telefon 74/8 px, ≤ 360 px: 104 px)",
   "farben": "Grund #24392f, Karte #f4eee2, Akzent und Linie #e7bc63",
   "vorfuehrung": "gedachter Zeiger, power2.inOut; Anfahrt 650 ms, Zug 520 + 880 ms, Halten 420 ms; wechselt je Runde die Variante"
  },
  "ausloeser": "ziehen",
  "touch": "Karte nach 250 ms Halten aufnehmen (vorher bleibt Scrollen möglich), am Griff sofort. Während des Zugs wird nicht gescrollt. Pfeilknöpfe Nach oben/Nach unten sind immer sichtbar (34 × 30 px).",
  "reduziert": "Kein Ausweichen, kein Gleiten, keine FLIP-Bewegung: Nachbarn springen sofort. Drop-Linie, Lücke und Farb-Flash bleiben. Die Vorführung zeigt keinen Zeiger und versetzt die Gänge im Sprung.",
  "korrekturen": {
   "beschreibung": "1) Ziehbare Elemente zeigen das vorab: Griff-Icon, cursor: grab und ein leichter Hintergrundwechsel beim Hover. 2) Beim Ziehen bleibt das Original als gedimmter Platzhalter (opacity 0.4) stehen oder wird zur leeren Lücke. Eine Vorschau folgt dem Zeiger. 3) Das Ziel wird sichtbar, bevor man loslässt: entweder als Drop-Linie mit Punkt am Anfang oder durch Nachbarn, die mit kurzer Transform-Animation ausweichen. 4) Nach dem Ablegen gleitet das Element in seine Lücke, und die Fläche leuchtet einmal kurz in der Auswahlfarbe auf. 5) Tastatur und Knöpfe („Nach oben“, „Nach unten“) erreichen dasselbe Ergebnis ohne Ziehen.",
   "warum_es_wirkt": "Direkte Manipulation fühlt sich physisch und schnell an. Linie oder Ausweichen zeigen die Folgen der Aktion, bevor man loslässt. Der Flash bestätigt, wo das Element gelandet ist.",
   "wann_einsetzen": "Kanban-Boards, Playlists, Prioritäten- und Wunschlisten, Menü- und Navigations-Editoren, Bildreihenfolge in Galerien, Formular- und Seitenbaukästen, Konfiguratoren.",
   "wann_nicht": "Als einzige Möglichkeit zum Umsortieren (Barrierefreiheit). Bei sehr langen, virtuellen Listen ohne Auto-Scroll. Wenn die Reihenfolge fachlich egal ist.",
   "varianten": [
    "Gedimmtes Original (opacity 0.4) mit Drop-Linie, Nachbarn bleiben stehen (Atlassian Pragmatic drag and drop)",
    "Live-Umordnung: Nachbarn weichen während des Ziehens aus (dnd kit Sortable, SortableJS animation: 150)",
    "Leere Lücke mit gestricheltem Rahmen in Elementgröße",
    "Vorschau leicht gedreht und angehoben (Trello: 4°)",
    "Drop-Flash in der Auswahlfarbe nach dem Ablegen",
    "Native View Transitions für die Umordnung (siehe flip-zustandswechsel)"
   ],
   "umsetzung": "Bibliothek wählen: Pragmatic drag and drop (nativ, sehr klein, framework-unabhängig), dnd kit (React, Vue, Svelte; Sortable-Preset, Tastatursensor) oder SortableJS (Vanilla). Ohne Bibliothek reichen Pointer Events, wenn alle Elemente gleich hoch sind.\n\nZustände als Klassen: .is-dragging { opacity: .4 } am Original. Drop-Indikator als absolut positionierte 2-px-Linie mit 8-px-Kreis, der 4 px nach links übersteht. Vorschau höchstens 280 × 280 px, 16/8 px vom Zeiger versetzt. Nachbarn: transition: transform 150ms cubic-bezier(0.25, 1, 0.5, 1) (dnd kit Standard: 250 ms). Nach dem Drop: element.animate([{ backgroundColor: 'var(--selected)' }, { backgroundColor: 'transparent' }], { duration: 700, easing: 'cubic-bezier(0.25, 0.1, 0.25, 1)' }).\n\nAktivierung: Maus ab 10 px Bewegung, Touch nach 250 ms Halten mit 5 px Toleranz, damit Scrollen möglich bleibt. Zusätzlich Knöpfe oder Menü „Verschieben nach …“ und Tastatur (Leertaste aufnehmen, Pfeiltasten, Leertaste ablegen, Escape abbrechen) mit aria-live-Ansagen.\n\nFallstricke: Nach dem Gleiten die Transforms und die DOM-Reihenfolge im selben Frame zurücksetzen, sonst springt die Liste. Den Klick nach einem Zug abfangen. Beim Verschieben per Tastatur den Fokus auf dem Griff halten.",
   "mobil": "Long-Press (etwa 250 ms) zum Aufnehmen, am Griff sofort. Auto-Scroll am Rand bei langen Listen. Griffe mindestens 24 × 24 px, besser 44 px. Natives HTML5-Drag-and-drop ist auf Touch eingeschränkt, deshalb Pointer Events oder eine Bibliothek mit Touch-Sensor nutzen.",
   "reduzierte_bewegung": "Ausweich- und Gleitanimationen auf 0 ms. Drop-Linie und Flash bleiben, der Flash als reiner Farbwechsel ohne Bewegung.",
   "barrierefreiheit": "Dasselbe Ergebnis ohne Ziehen ermöglichen (WCAG 2.5.7 Dragging Movements): Tastatursteuerung und Knöpfe oder Menüaktionen. Positionswechsel per aria-live ansagen („Position 2 von 5“). Der Griff ist ein Button mit Label, etwa „Saibling und Kren verschieben“."
  },
  "geprueft": "01.11.2026",
  "notiz": "Welt: Rezept gastro-warm-appetitlich, erfundenes Restaurant „Lände“ in Linz-Urfahr. Gäste ordnen beim Menü „Freie Folge“ fünf Gänge. Die Zeitschiene (1. Gang 19:15 usw.) bleibt stehen, die Karten wandern; die Zielzeit leuchtet senfgelb und zeigt die Folge vor dem Loslassen. Drei Varianten per Umschalter: Linie (Atlassian), Ausweichen (dnd kit), Lücke mit 4° gekippter Vorschau (Trello). Vanilla JS mit Pointer Events, ohne Bibliothek. Teller-Illustrationen als eigene Inline-SVG, Schriften Fraunces und Commissioner. Die Vorführung wechselt je Runde die Variante. PostHog (Framer Motion Reorder) nutzt eine Federanimation ohne Platzhalter; die Demo folgt den Atlassian- und dnd-kit-Werten. AD-Review 01.11.2026: Note 4. Zugang 02.11.2026: --tinte-leise .62 → .70 (5,2:1), Notizen brechen am Desktop und bei ≤ 360 px um statt Auslassungspunkte (dort Kartenhöhe 104 px), Variantenleiste mit flex-wrap, Rahmen für Knöpfe im Kontrastmodus."
 }
}
