Skip to content

Latest commit

 

History

History
356 lines (205 loc) · 14.4 KB

File metadata and controls

356 lines (205 loc) · 14.4 KB

Design system — descriptive component inventory

The descriptive half of the design docs (ADR 0194): which components/ui primitives exist, their slots, and each one's when-to-use — extracted from the JSDoc on the shipped components. It is DESCRIPTIVE ONLY. The normative design law — the four pillars, the prohibitions, and the role-token values — is founder-authored in design-system-manifest.md and is never written here. A when-to-use references that law; it never restates or mints it.

Alert

Source: apps/web/src/components/ui/Alert.tsx

When to use: A Manti-backed inline semantic message. Use danger for errors and another semantic variant for non-error outcomes; add kp-alert--inline when preserving a feature's existing text-only geometry.

Slots:

  • children — The message description.

Avatar

Source: apps/web/src/components/ui/Avatar.tsx

When to use: The Manti-backed user/actor image primitive. Always pass name: it names the image and supplies the initials fallback when src is absent or fails. Reach for it for any actor identity glyph.

Slots:

  • fallback — Rendered internally from the first two initials of name.

Badge

Source: apps/web/src/components/ui/Badge.tsx

When to use: A Manti-backed compact status or category chip. Keep state in text, not color alone, and use a feature class only to preserve an established Phoenix category palette.

Slots:

  • children — The badge label.

Button

Source: apps/web/src/components/ui/Button.tsx

When to use: The Manti-backed base action control. Use primary for the promoted action, secondary for standard actions, tertiary for low-emphasis actions and danger for destructive actions; prefer it over a hand-rolled button.

Slots:

  • children — The visible label and accessible name.
  • icon — Optional leading decorative glyph, mapped to Manti's icon slot.

Card

Source: apps/web/src/components/ui/Card.tsx

When to use: The opinionated default for a NEW surface — a bordered, subtly-raised, padded box. Reach for Surface with explicit props only to preserve an existing shell's exact look during a migration (the composite-primitive selection rule is the manifest's, referenced not restated — see design-system-manifest.md).

Slots:

  • children — The card's content.

Agent directives (@agent — protected, do not regenerate):

  • Prefer this composite over hand-rolling a bordered box; do not regenerate this selection guidance — it echoes the manifest's component-selection rule.

CaylakBadge

Source: apps/web/src/components/ui/CaylakBadge.tsx

When to use: Never directly — reach for SandboxMarker, which owns the ReviewBadge/CaylakBadge choice so the two cannot stack on one item. Rendered only when the server-derived sandboxedInPlace field is true, which is structurally false while PHOENIX_CAYLAK_VISIBILITY is off.

Slots:

  • none — Fixed copy; no children slot.

Code

Source: apps/web/src/components/ui/atoms.tsx

When to use: The inline-code glyph — renders a <code> for an identifier, path, or short literal inside running prose. Reach for it over a styled span so the code run is semantic; for a multi-line block use a <pre>, not this inline atom.

Slots:

  • children — The code text.

Collapsible

Source: apps/web/src/components/ui/Collapsible.tsx

When to use: The Manti-backed inline disclosure. Pass the trigger and panel content to reveal optional detail while retaining keyboard and ARIA behavior.

Slots:

  • trigger — The disclosure control supplied through the trigger prop.
  • children — The region shown while the disclosure is open.

CopyLinkButton

Source: apps/web/src/components/ui/CopyLinkButton.tsx

When to use: The shared paylaş (share/copy-link) control. Reach for it on any shareable item (pano post/comment, sözlük definition) — pass the canonical path and it resolves the absolute URL, copies it, and flashes inline kopyalandı/kopyalanamadı feedback (native share sheet only on coarse-pointer surfaces). Don't hand-roll per-page link logic.

Slots:

  • none — Renders its own label; no children slot.

CountToggle

Source: apps/web/src/components/ui/CountToggle.tsx

When to use: The pressable count-pill — a reaction/vote/toggle affordance that carries an aggregate count. Reach for it over a bare toggle button whenever a count rides alongside the on/off state (the reaction bar is the canonical use).

Slots:

  • children — The visible label; when omitted (icon-only), name the control via aria-label since the icon is decorative.
  • icon — Leading decorative glyph rendered before the label/count.

Dialog

Source: apps/web/src/components/ui/Dialog.tsx

When to use: The Manti-backed modal surface for confirmations, forms and focused overlay tasks. Supply title for its accessible name and use the footer render prop when actions need the provided close callback.

Slots:

  • trigger — Optional element that opens the dialog.
  • children — The dialog body.
  • footer — Optional action row, accepting Manti's dialog render props.

DraftRestoreBanner

Source: apps/web/src/components/ui/DraftRestoreBanner.tsx

When to use: The saved-draft restore prompt. Reach for it after a flow that may have stashed a draft across the auth round-trip — it OFFERS restore/discard rather than silently re-injecting (#1214). Wire onRestore/onDismiss to the caller's draft store.

Slots:

  • none — Fixed copy + two actions; no children slot.

EditedIndicator

Source: apps/web/src/components/ui/EditedIndicator.tsx

When to use: The edited-marker glyph. Reach for it on any editable entity's meta row (post, comment, definition) to signal an edit — render it unconditionally and let it self-suppress when the item is unedited or still within the grace window.

Slots:

  • none — Fixed copy + tooltip; no children slot.

EmptyState

Source: apps/web/src/components/ui/EmptyState.tsx

When to use: The inline empty-state block. Reach for it to fill a sparse region within a page (an empty feed, a zero-count list, a contribution-less profile) so the void reads as intentional. For a full-page miss use NotFoundPage, its 404 sibling, instead.

Slots:

  • icon — Optional decorative glyph above the title (aria-hidden).
  • title — The required headline for the empty state.
  • description — Optional supporting line under the title.
  • action — Optional CTA (e.g. a Button) below the copy.

Form

Source: apps/web/src/components/ui/Form.tsx

When to use: The native form shell around Manti's field-owning Input and Textarea components. Use it for submit semantics without introducing another field state layer.

Slots:

  • children — The Manti fields and form actions.

Input

Source: apps/web/src/components/ui/Form.tsx

When to use: The Manti single-line field. Pass its label directly and use hint or error so Manti owns the field's accessible relationships.

Slots:

  • none — A leaf field control with its label and messages supplied as props.

Kbd

Source: apps/web/src/components/ui/atoms.tsx

When to use: The keyboard-key glyph — renders a <kbd> for a shortcut key or key combo mentioned in running text (e.g. a ⌘K hint). Reach for it over a styled span so the key reads as a key semantically, not just visually.

Slots:

  • children — The key label (a single key or a combo).

Mark

Source: apps/web/src/components/ui/atoms.tsx

When to use: The highlight glyph — renders a <mark> to emphasize a run of text (a search-match hit, a called-out term). Reach for it over a colored span so the highlight carries the native highlight semantics.

Slots:

  • children — The highlighted text.

Menu

Source: apps/web/src/components/ui/Menu.tsx

When to use: The Manti-backed dropdown command list for account and contextual actions. Describe commands through items; use groups and separators for structure instead of hand-built popup content.

Slots:

  • trigger — The element that opens the menu.
  • items — Commands, separators and command groups supplied through items.

MetaRow

Source: apps/web/src/components/ui/MetaRow.tsx

When to use: The muted metadata row shell — author · time · a count · an action, dot-separated. Reach for it (with MetaRow.Dot between items) for any feed row, post/definition header, or comment footer instead of hand-rolling the row.

Slots:

  • children — The metadata items; separate them with MetaRow.Dot.

NumberInput

Source: apps/web/src/components/ui/NumberInput.tsx

When to use: A Manti-backed numeric field with bounds and step controls. Prefer this over a generic Input with type="number" when numeric stepping is the interaction.

Slots:

  • label — Optional visible field label.

Popover

Source: apps/web/src/components/ui/Popover.tsx

When to use: The Manti-backed non-modal anchored surface for compact interactive content such as the notification preview. Use Dialog when the task must be modal.

Slots:

  • trigger — The element that anchors and opens the popover.
  • children — The popover content.

ReportButton

Source: apps/web/src/components/ui/ReportButton.tsx

When to use: The shared bildir (report) control. Reach for it on any reportable item (pano post/comment, sözlük definition) — pass onReport to perform the mutation and it owns the in-flight lock plus the bildirildi/zaten bildirildi feedback, locking once confirmed. Don't hand-roll per-page report logic.

Slots:

  • none — Renders its own label; no children slot.

ReviewBadge

Source: apps/web/src/components/ui/ReviewBadge.tsx

When to use: Every "incelemede" (pending review) badge, wherever it renders — the author's own sandboxed content (post-detail, definition, profile katkıların) and the divan review queue. Never hand-roll a second one; a feature class over a raw Badge variant is how the divan chip ended up grey-on-blue (#5228).

Slots:

  • none — Fixed copy; no children slot.

SandboxMarker

Source: apps/web/src/components/ui/SandboxMarker.tsx

When to use: Any surface showing content that can be sandboxed — the pano feed row, post detail, comment tree node, sözlük definition entry. Renders nothing when neither wire field applies, which is also what every viewer gets with PHOENIX_CAYLAK_VISIBILITY off.

Slots:

  • none — Chooses a fixed-copy badge; no children slot.

ScrollArea

Source: apps/web/src/components/ui/ScrollArea.tsx

When to use: A bounded Manti-backed scroll viewport that needs keyboard focus and draggable scrollbars while its surrounding header/footer stay fixed.

Slots:

  • children — Scrollable content.

Select

Source: apps/web/src/components/ui/Select.tsx

When to use: The Manti-backed selection field for a compact fixed option list whose choices need keyboard navigation and a styled listbox.

Slots:

  • items — The options supplied through items.

Skeleton

Source: apps/web/src/components/ui/atoms.tsx

When to use: The loading-placeholder block — a shimmering box that reserves space for content still in flight. Reach for it to hold layout during a fetch instead of a spinner or a collapsing void; size it to the content it stands in for.

Slots:

  • none — Presentational; renders no children.

Surface

Source: apps/web/src/components/ui/Card.tsx

When to use: The parameterized surface shell — background/border/radius/padding/ elevation driven entirely by role-token props. Reach for it (over Card) only to reproduce an existing shell's exact look during a migration; for a new surface prefer Card's opinionated default (the selection rule is the manifest's, referenced not restated — see design-system-manifest.md).

Slots:

  • children — The surface's content.

Switch

Source: apps/web/src/components/ui/Switch.tsx

When to use: The Manti-backed binary setting control for an immediately applied on/off value. Supply a textual child as its label; use CountToggle when a count travels with the state.

Slots:

  • children — The switch's trailing accessible label.

Tabs

Source: apps/web/src/components/ui/Tabs.tsx

When to use: The Manti-backed sibling-view switcher. Declare each trigger and panel through items; use line, pill or soft appearance without hand-wiring tab roles and selection state.

Slots:

  • items — Tab labels and their corresponding panel content.

Tag

Source: apps/web/src/components/ui/atoms.tsx

When to use: The category/kind chip — a small colored label for a post kind, topic, or status. Pass href to render it as a link chip, omit it for a static label. Reach for it over a hand-styled span for any categorical badge.

Slots:

  • children — The chip label.

Textarea

Source: apps/web/src/components/ui/Form.tsx

When to use: The Manti multi-line field for free-form content. Pass its label directly; use kp-textarea--mono only for code or preformatted input.

Slots:

  • none — A leaf field control with its label and messages supplied as props.

ToastProvider

Source: apps/web/src/components/ui/Toast.tsx

When to use: The Manti-backed transient-notification host. Mount it once near the application root and raise ephemeral status through useToast; stable ids replace.

Slots:

  • children — The subtree that can call useToast.

ToggleGroup

Source: apps/web/src/components/ui/ToggleGroup.tsx

When to use: The Manti-backed compact selection set for segmented controls, filters and small fixed option lists. Supply options through items and control selection with the string-array value contract.

Slots:

  • items — Toggle options supplied through items.

Tooltip

Source: apps/web/src/components/ui/Tooltip.tsx

When to use: The Manti-backed hover/focus hint for short supplementary text. Never place essential information solely in a tooltip.

Slots:

  • children — The trigger content wrapped by Manti's inline trigger.

TooltipProvider

Source: apps/web/src/components/ui/Tooltip.tsx

When to use: Compatibility-only no-op for the former application-level provider. Manti Tooltip needs no provider; new code should not add another provider.

Slots:

  • children — The application subtree, returned unchanged.