Add widget registry for universal UI decoupling
Introduces a widget system where domains register UI fragments into named slots (container_nav, container_card, account_page, account_link). Host apps iterate widgets generically without naming any domain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
contracts/widgets.py
Normal file
49
contracts/widgets.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Widget descriptors for cross-domain UI composition.
|
||||
|
||||
Each widget type describes a UI fragment that one domain contributes to
|
||||
another domain's page. Host apps iterate widgets generically — they never
|
||||
name the contributing domain.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class NavWidget:
|
||||
"""Renders nav items on a container page (entries, calendars, markets)."""
|
||||
domain: str
|
||||
order: int
|
||||
context_fn: Callable # async (session, *, container_type, container_id, **kw) -> dict
|
||||
template: str
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class CardWidget:
|
||||
"""Decorates content cards in listings with domain data."""
|
||||
domain: str
|
||||
order: int
|
||||
batch_fn: Callable # async (session, post_ids) -> dict[int, list]
|
||||
context_key: str # key injected into each post dict
|
||||
template: str
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class AccountPageWidget:
|
||||
"""Sub-page under /auth/<slug>/."""
|
||||
domain: str
|
||||
slug: str
|
||||
label: str
|
||||
order: int
|
||||
context_fn: Callable # async (session, *, user_id, **kw) -> dict
|
||||
template: str
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class AccountNavLink:
|
||||
"""Nav link on account page (internal or external)."""
|
||||
label: str
|
||||
order: int
|
||||
href_fn: Callable # () -> str
|
||||
external: bool = False
|
||||
Reference in New Issue
Block a user