liquiddesign

Wzorzec 01

Cztery stany widoku

Widok projektowany tylko dla szczęśliwej ścieżki rozpada się przy pierwszym pustym wyniku albo błędzie sieci. W liquid design wszystkie cztery stany powstają razem, mieszkają w kontenerze o wspólnych wymiarach i wymieniają się bez śladu w otaczającym layoucie.

List projektów w czterech stanach

Przełączaj stany i obserwuj krawędź panelu. Container trzyma wymiary, więc reszta strony nawet nie wie, że coś się zmieniło.

Atlas Rebranding

Postęp: 68%

W toku

Sklep Novak Studio

Postęp: 91%

Review

Panel Heliotrop

Postęp: 100%

Gotowe

Reguły

  • Kontener widoku ma stałą minimalną wysokość, wspólną dla wszystkich stanów.
  • Stan pusty mówi, co zrobić dalej, i prowadzi do konkretnej akcji, zamiast zostawiać białą plamę.
  • Stan błędu zawiera przycisk ponowienia w tym samym miejscu, w którym stała treść.
  • Przełączenie stanu nigdy nie zmienia pozycji elementów poza kontenerem.

Wzorzec w kodzie

Unia dyskryminowana wymusza obsługę wszystkich stanów
type ViewState<T> =
  | { stan: "loading" }
  | { stan: "content"; data: T }
  | { stan: "empty" }
  | { stan: "error"; message: string };

function ProjectList({ view }: { view: ViewState<Projekt[]> }) {
  return (
    <div className="grid min-h-64 grid-rows-1">
      {view.state === "loading" && <ListSkeleton />}
      {view.state === "content" && <List projects={view.data} />}
      {view.state === "empty" && <EmptyState />}
      {view.state === "error" && <ErrorState komunikat={view.message} />}
    </div>
  );
}
Stan pusty prowadzi do akcji, nie zostawia białej plamy
function EmptyState() {
  return (
    <div className="flex flex-col items-center justify-center gap-3">
      <p className="font-semibold">Nie masz jeszcze projektów</p>
      <p className="text-sm">Załóż pierwszy albo poproś o zaproszenie.</p>
      <Button variant="secondary">Nowy projekt</Button>
    </div>
  );
}