import { Avatar, AvatarFallback, AvatarImage, Card, CardContent, CardDescription, CardHeader, CardTitle, ListRow, } from "@godxjp/ui/data-display"; import { Button, Text } from "@godxjp/ui/general"; import { Flex, PageContainer } from "@godxjp/ui/layout"; import { Building2, KeyRound, ShieldCheck, Sparkles } from "lucide-react"; import portraitAmber from "../assets/portrait-amber.svg"; import portraitClay from "../assets/portrait-clay.svg"; import portraitIndigo from "../assets/portrait-indigo.svg"; import portraitIris from "../assets/portrait-iris.svg"; import portraitMoss from "../assets/portrait-moss.svg"; import portraitPlum from "../assets/portrait-plum.svg"; import portraitSlate from "../assets/portrait-slate.svg"; /* The portraits are committed SVG files under docs/assets, imported so the bundler rewrites each * URL against PREVIEW_BASE — an absolute "/assets/…" would 404 wherever the site is served from a * sub-path. * * A docs page must never fetch a THIRD-PARTY image: without the public internet it cannot render, * and on CI it does not merely look wrong, it hangs — the request never settles, `networkidle` * never fires, and `page.goto` times out. Committed files cost no request that can hang and no * service that can disappear. */ /** * Avatar — identity image with a readable fallback (users, teams, entities). * Always compose AvatarImage + AvatarFallback so broken/missing images degrade * gracefully. Size on the control ladder with `size` (xs/sm/md/lg, the same * --control-height tier Button reads); className only for sizes off that ladder. * Composed only from real @godxjp/ui components. */ export default function Demo() { return ( Image + fallback Compose AvatarImage with AvatarFallback: a loaded photo shows the image, an avatar with no image shows initials. NA TK VB 経理 Fallback on a broken image When the src fails to load, AvatarImage swaps in the AvatarFallback automatically, never a blank circle. delayMs holds the fallback back briefly so it does not flash before a slow image arrives. YM HS {/* shape="square" — the entity-header organization / service mark */} エンティティヘッダー · shape="square" 組織・サービスのマークは shape="square" (角丸スクエア + ブランド面)、人物は既定の shape="circle"。 半径・サイズ・配色はすべて --avatar-square-* トークン所有なので、サービス側は className を上書きせずテーマ 1 か所で調整できる。 株式会社山田商事 組織 · 取引先コード 100482 経理 DX {/* appearance="tinted" — the capability medallion */} ケイパビリティ メダリオン · appearance="tinted" 機能・ケイパビリティのアイコンは、淡いロール地の角丸スクエア(メダリオン)に載せる。 メダリオンは Avatar + Lucide グリフの合成パターン(docs/COMPOSITION-VS-COMPONENT.md) なので、ライブラリが持つべきは「淡色」そのもの · appearance="tinted"。 これが無いと消費側は hsl(var(--primary) / 0.1) をページ CSS に書き写すか、素のグリフを置くしかなかった。 shape と直交するので、円形メダリオンも 同じ 1 語で得られる。配色は --avatar-tinted-* トークン所有。 {/* The left-aligned capability card: medallion, title, one line of prose. */} シングルサインオン 1 つの ID で全サービスへ {/* Solid entity mark beside it — the two treatments are different jobs. */} {/* presence — the realtime reachability dot */} プレゼンス · presence 「今つながるか」はマークの上に出る。presence を渡すとドットとローカライズ済みの sr-only テキストが同時に付く(色だけで状態を伝えない · WCAG 1.4.1)。 4 つの値は色に加えて形でも区別する。online は塗り、away は下半分塗り、busy は横棒入り、offline は中空リング。 グレースケールでも、色覚特性があっても、Windows ハイコントラストでも 4 状態が判別できる。 直径・食い込み・リング幅・リング色は --avatar-presence-* トークン所有(#44 / #45)。 直径はマークに対する比率なので、size-8 でも size-12 でも組織マークでも同じ 1 つの値で追従する。 presence を渡さない=「プレゼンスという概念が無い」(組織マーク)で、DOM には何も出ない。presence="offline" は「不在だと分かっている」で、別の意味。 } title="田中 未来" description="プロダクト · #general" /> } title="佐藤 玲" description="デザイン · #general" /> } title="鈴木 大輔" description="エンジニアリング · #general" /> } title="山本 彩" description="サポート · #general" /> {/* No presence at all — an organization mark has no reachability to report. */} } title="株式会社山田商事" description="組織 · プレゼンスの概念なし" /> プレゼンス · 4 状態と寸法追従 上段は 4 状態を写真の上に重ねたもの。リングが写真から ドットを切り離すために幅を稼いでいることが分かる。 中段は同じ presence="online" を size-8 / 既定 / size-12 / 組織マークに載せたもので、 ドットが px 固定ではなくマーク比で追従することを示す。下段は密度の高い行(36px マーク)での見え方。 S D L } title="佐藤 玲" description="presenceLabel でプロダクト側の言い回しに差し替え(表示はされない)" /> {/* size — the control ladder (gh#716) */} サイズ · size xs 24px / sm 28px / md 32px(既定) / lg 36px。すべて Button や Input と同じ --control-height の段なので、同じ段の Button と並べたときに高さがそろう。イニシャルの級数もグリフの箱も同じ段で動くため、小さい マークは「小さい」であって「切れている」ではない。shape="square" も同じ段に乗る。 ラダーの外側のサイズ(プロフィール用の 96px マークなど)は従来どおり className。 XS SM MD LG {/* square rides the identical ladder */} {/* the glyph steps with the box, so a medallion is never clipped */} {/* The row that could not be built before #716 */} 行に入るマーク · size="sm" と icon-sm 行の高さが先に決まっている場所(28px の icon-sm トリガ、24/28px の密なテーブル行)では、マークの側が行に合わせる。#716 以前は箱が --control-height に固定されていたため、28px のトリガに 32px のマークが入って外へはみ出し、消費側に残された手は「行全体を 32px に上げる」だけだった。 下の 1 段目は同じ段の Button と並べたもの、2 段目は icon-sm トリガの中に入れたもの。 マークはトリガの内寸に収まる(28px の中に 28px、24px の中に 24px)。 ラダーの外 · className コントロール行の段に無いサイズ(プロフィールヘッダの大きなマークなど)は、従来どおり size-* ユーティリティで指定する。 M L ); }